|
@@ -0,0 +1,208 @@
|
|
|
+import { fetchUNMastersType, fetchUNMastersTypes } from '@api/ranking';
|
|
|
+import { StoreType, storage } from 'src/storage';
|
|
|
+
|
|
|
+const NAMESPACE = 'UNMasters';
|
|
|
+
|
|
|
+function saveData<T>(key: string, data: T) {
|
|
|
+ const namespacedKey = `${NAMESPACE}:${key}`;
|
|
|
+ const jsonData = JSON.stringify(data);
|
|
|
+ storage.set(namespacedKey, jsonData);
|
|
|
+}
|
|
|
+
|
|
|
+function loadData<T>(key: string): T | null {
|
|
|
+ const namespacedKey = `${NAMESPACE}:${key}`;
|
|
|
+ const jsonData = storage.get(namespacedKey, StoreType.STRING) as string;
|
|
|
+
|
|
|
+ return jsonData ? JSON.parse(jsonData) : null;
|
|
|
+}
|
|
|
+
|
|
|
+function saveTypes(
|
|
|
+ typesData: { type: number; name: string }[],
|
|
|
+ startIndexes: Record<string, number>
|
|
|
+): void {
|
|
|
+ const types: TypeData[] = typesData.map((item) => ({
|
|
|
+ ...item,
|
|
|
+ start: startIndexes[item.type]
|
|
|
+ }));
|
|
|
+ saveData<TypeData[]>('types', types);
|
|
|
+}
|
|
|
+
|
|
|
+function saveTypeMasters(type: number, masters: Master[]): void {
|
|
|
+ let allMasters: Record<number, Master[]> = loadData<Record<number, Master[]>>('masters') || {};
|
|
|
+ allMasters[type] = masters;
|
|
|
+ saveData('masters', allMasters);
|
|
|
+}
|
|
|
+
|
|
|
+function saveSort(filtersData: any, filterType: 'yearOfCompletion' | 'countryOfOrigin'): void {
|
|
|
+ const filters = filtersData.reduce((obj: any, item: any) => {
|
|
|
+ const key = filterType === 'yearOfCompletion' ? item.year : item.country;
|
|
|
+ obj[key] = item.masters.map((master: Master) => master.id);
|
|
|
+
|
|
|
+ return obj;
|
|
|
+ }, {});
|
|
|
+ saveData<SortData>(filterType, filters);
|
|
|
+}
|
|
|
+
|
|
|
+async function handleGetTypeResponse(type: number): Promise<number | null> {
|
|
|
+ const responseData = await fetchUNMastersType(type);
|
|
|
+ if (responseData && responseData.result === 'OK') {
|
|
|
+ saveTypeMasters(type, (responseData.data as { data: Master[] }).data);
|
|
|
+
|
|
|
+ return (responseData.data as { start: number }).start;
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+export async function fetchAndSaveAllTypesAndMasters() {
|
|
|
+ const typesResponse = await fetchUNMastersTypes();
|
|
|
+ const startIndexes: Record<string, number> = {};
|
|
|
+
|
|
|
+ if (typesResponse && typesResponse.result === 'OK') {
|
|
|
+ const types = typesResponse.data.map((type) => type.type);
|
|
|
+ for (let type of types) {
|
|
|
+ const startIndex = await handleGetTypeResponse(type);
|
|
|
+ if (startIndex !== null) {
|
|
|
+ startIndexes[type] = startIndex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ saveTypes(typesResponse.data, startIndexes);
|
|
|
+ }
|
|
|
+
|
|
|
+ const countryResponse = await fetchUNMastersType(-1);
|
|
|
+ const yearResponse = await fetchUNMastersType(-2);
|
|
|
+
|
|
|
+ if (yearResponse && yearResponse.result === 'OK') {
|
|
|
+ saveSort(yearResponse.data, 'yearOfCompletion');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (countryResponse && countryResponse.result === 'OK') {
|
|
|
+ saveSort(countryResponse.data, 'countryOfOrigin');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export function getMastersByCountryOfOrigin() {
|
|
|
+ const countrySortData = loadData('countryOfOrigin');
|
|
|
+ if (!countrySortData) return null;
|
|
|
+
|
|
|
+ const countryBlocks: { country: string; count: number; masters: Master[] }[] = [];
|
|
|
+
|
|
|
+ for (const [country, masterIds] of Object.entries(countrySortData)) {
|
|
|
+ const mastersList: Master[] = [];
|
|
|
+ masterIds.forEach((id: number) => {
|
|
|
+ const master = getMasterById(id);
|
|
|
+ if (master) {
|
|
|
+ mastersList.push(master);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ countryBlocks.push({
|
|
|
+ country,
|
|
|
+ count: mastersList.length,
|
|
|
+ masters: mastersList
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return countryBlocks;
|
|
|
+}
|
|
|
+
|
|
|
+export function getMastersByYearOfCompletion() {
|
|
|
+ const yearSortData = loadData('yearOfCompletion');
|
|
|
+ if (!yearSortData) return null;
|
|
|
+
|
|
|
+ const yearBlocks: { year: string; count: number; masters: Master[] }[] = [];
|
|
|
+
|
|
|
+ for (const [year, masterIds] of Object.entries(yearSortData)) {
|
|
|
+ const mastersList: Master[] = [];
|
|
|
+ masterIds.forEach((id: number) => {
|
|
|
+ const master = getMasterById(id);
|
|
|
+ if (master) {
|
|
|
+ mastersList.push(master);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ yearBlocks.push({
|
|
|
+ year,
|
|
|
+ count: mastersList.length,
|
|
|
+ masters: mastersList
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return yearBlocks;
|
|
|
+}
|
|
|
+
|
|
|
+export function getMastersByType(type: number) {
|
|
|
+ const allMasters: MastersData | null = loadData('masters');
|
|
|
+ if (!allMasters) return null;
|
|
|
+
|
|
|
+ return allMasters[type] || [];
|
|
|
+}
|
|
|
+
|
|
|
+function getMasterById(id: number) {
|
|
|
+ const allMasters = loadData('masters');
|
|
|
+ if (!allMasters) return null;
|
|
|
+
|
|
|
+ for (const typeMasters of Object.values(allMasters)) {
|
|
|
+ const master = typeMasters.find((m: Master) => m.id === id);
|
|
|
+ if (master) return master;
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+export function getUNMastersTypes() {
|
|
|
+ const types = loadData('types');
|
|
|
+ if (!types) return null;
|
|
|
+
|
|
|
+ return types;
|
|
|
+}
|
|
|
+
|
|
|
+interface Master {
|
|
|
+ id: number;
|
|
|
+ type: number;
|
|
|
+ origin: string;
|
|
|
+ origin1: string;
|
|
|
+ origin2: string;
|
|
|
+ full_name: string;
|
|
|
+ tbt_username: string;
|
|
|
+ born: string;
|
|
|
+ final: string | null;
|
|
|
+ final_year: string;
|
|
|
+ final_country: string;
|
|
|
+ age: string;
|
|
|
+ personal: string;
|
|
|
+ media: string;
|
|
|
+ media2: string;
|
|
|
+ media3: string;
|
|
|
+ wikipedia: string;
|
|
|
+ book: string;
|
|
|
+ book_url: string;
|
|
|
+ book2: string;
|
|
|
+ book_url2: string;
|
|
|
+ social: string;
|
|
|
+ twitter: string;
|
|
|
+ instagram: string;
|
|
|
+ youtube: string;
|
|
|
+ status: number;
|
|
|
+ sort: number;
|
|
|
+ last_country: string;
|
|
|
+ user_id: number | null;
|
|
|
+ origin1_flag: string;
|
|
|
+ origin2_flag: string | null;
|
|
|
+ final_flag: string;
|
|
|
+ interviews: string[];
|
|
|
+}
|
|
|
+
|
|
|
+interface TypeData {
|
|
|
+ name: string;
|
|
|
+ start: number;
|
|
|
+ type: number;
|
|
|
+}
|
|
|
+
|
|
|
+interface SortData {
|
|
|
+ [key: string]: number[];
|
|
|
+}
|
|
|
+
|
|
|
+interface MastersData {
|
|
|
+ [key: string]: Master[];
|
|
|
+}
|