From 97b2e17d5523f87c0c1549a34a4d4ffbb78762a6 Mon Sep 17 00:00:00 2001 From: Nigel Breslaw Date: Sat, 20 Jul 2024 17:48:42 +0200 Subject: [PATCH] refactor: All defintions must load to init the app (#2087) --- native/app/Root.tsx | 53 ++++++++++++++++++++-------- native/app/store/DefinitionsSlice.ts | 33 ++++++++++------- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/native/app/Root.tsx b/native/app/Root.tsx index a8dea12d4..ac9f64a68 100644 --- a/native/app/Root.tsx +++ b/native/app/Root.tsx @@ -17,7 +17,6 @@ import { useGGStore } from "@/app/store/GGStore.ts"; import { bungieManifestSchema } from "@/app/core/ApiResponse.ts"; import type { DestinyItemIdentifier } from "@/app/inventory/logic/Helpers.ts"; import App from "@/app/App"; // Do not use the file extension or the web version will fail to be used. -import { updateBucketSizes, updateDestinyText } from "@/app/utilities/Constants.ts"; import "@/global.css"; SplashScreen.preventAutoHideAsync(); @@ -32,24 +31,47 @@ useGGStore.getState().initDefinitions(); enableFreeze(true); -async function init() { +let customDownloadAttempts = 0; +async function getCustomItemDefinition() { try { const customManifest = getJsonBlob(CUSTOM_MANIFEST_URL); - const bungieManifest = getJsonBlob(BUNGIE_MANIFEST_URL); - - const manifest = await Promise.all([customManifest, bungieManifest]); - const parsedManifest = parse(object({ version: string() }), manifest[0]); - const parsedBungieManifest = parse(bungieManifestSchema, manifest[1]); + const manifest = await customManifest; + const parsedManifest = parse(object({ version: string() }), manifest); await useGGStore.getState().loadCustomDefinitions(parsedManifest.version); - await useGGStore.getState().loadBungieDefinitions(parsedBungieManifest); - updateBucketSizes(); - updateDestinyText(); } catch (e) { - // If the network call fails try to use the already downloaded version. console.error("Failed to load custom manifest", e); - useGGStore.getState().loadCustomDefinitions(null); + if (customDownloadAttempts < 5) { + customDownloadAttempts++; + getCustomItemDefinition(); + } else { + console.error("Failed to download custom manifest"); + } + } +} + +let bungieDownloadAttempts = 0; +async function getBungieDefinitions() { + try { + const bungieManifest = getJsonBlob(BUNGIE_MANIFEST_URL); + const manifest = await bungieManifest; + const parsedManifest = parse(bungieManifestSchema, manifest); + await useGGStore.getState().loadBungieDefinitions(parsedManifest); + } catch (e) { + console.error("Failed to load bungie manifest", e); + if (bungieDownloadAttempts < 5) { + console.log("Failed to load bungie manifest. Trying again"); + bungieDownloadAttempts++; + getBungieDefinitions(); + } else { + console.error("Failed to download bungie manifest"); + } } } + +async function init() { + getCustomItemDefinition(); + getBungieDefinitions(); +} init(); export type RootStackParamList = { @@ -99,7 +121,8 @@ function Root() { allowFontScaling: false, }; - const definitionsReady = useGGStore((state) => state.definitionsReady); + const itemsDefinitionReady = useGGStore((state) => state.itemsDefinitionReady); + const bungieDefinitionsReady = useGGStore((state) => state.bungieDefinitionsReady); const authenticated = useGGStore((state) => state.authenticated); const navigationRef = useRef>(null); const { width } = useWindowDimensions(); @@ -118,14 +141,14 @@ function Root() { } else { console.error("No navigationRef"); } - } else if (authenticated === "AUTHENTICATED" && definitionsReady) { + } else if (authenticated === "AUTHENTICATED" && itemsDefinitionReady && bungieDefinitionsReady) { getFullProfile(); useGGStore.getState().setLastRefreshTime(); const intervalId = setInterval(refreshIfNeeded, 2000); return () => clearInterval(intervalId); } - }, [authenticated, definitionsReady]); + }, [authenticated, itemsDefinitionReady, bungieDefinitionsReady]); function refreshIfNeeded() { const lastRefresh = useGGStore.getState().lastRefreshTime; diff --git a/native/app/store/DefinitionsSlice.ts b/native/app/store/DefinitionsSlice.ts index c4ae1252a..81234a6f8 100644 --- a/native/app/store/DefinitionsSlice.ts +++ b/native/app/store/DefinitionsSlice.ts @@ -59,12 +59,14 @@ import { } from "@/app/core/BungieDefinitions.ts"; import { bungieUrl, type BungieManifest } from "@/app/core/ApiResponse.ts"; import type { ItemHash } from "@/app/core/GetProfile.ts"; +import { updateBucketSizes, updateDestinyText } from "@/app/utilities/Constants.ts"; export type DefinitionsSliceSetter = Parameters>[0]; export type DefinitionsSliceGetter = Parameters>[1]; export interface DefinitionsSlice { - definitionsReady: boolean; + itemsDefinitionReady: boolean; + bungieDefinitionsReady: boolean; snackBarVisible: boolean; snackBarMessage: string; inventorySectionWidth: number; @@ -79,7 +81,8 @@ export interface DefinitionsSlice { } export const createDefinitionsSlice: StateCreator = (set, get) => ({ - definitionsReady: false, + itemsDefinitionReady: false, + bungieDefinitionsReady: false, snackBarVisible: false, snackBarMessage: "", inventorySectionWidth: 0, @@ -133,18 +136,20 @@ export const createDefinitionsSlice: StateCreator { saveItemDefinitionVersion(""); saveBungieDefinitionsVersion(""); - set({ definitionsReady: false }); + set({ itemsDefinitionReady: false }); }, }); @@ -179,7 +184,6 @@ async function downloadAndStoreItemDefinition(set: DefinitionsSliceSetter): Prom const downloadedDefinition = await getCustomItemDefinition(); const itemDefinition = parse(ItemResponseSchema, downloadedDefinition); const versionKey = itemDefinition.id; - console.log("versionKey", versionKey); await saveItemDefinitionVersion(versionKey); await setData(itemDefinition as unknown as JSON, "ITEM_DEFINITION", "setupItemDefinition()"); return set(parseAndSet(itemDefinition)); @@ -203,7 +207,10 @@ const NonInterpolationTable = [ let failCount = 0; -async function downloadAndStoreBungieDefinitions(bungieManifest: BungieManifest | null): Promise { +async function downloadAndStoreBungieDefinitions( + set: DefinitionsSliceSetter, + bungieManifest: BungieManifest | null, +): Promise { const versionKey = bungieManifest?.Response.version; if (!versionKey) { console.error("No version key found in bungieManifest"); @@ -283,12 +290,13 @@ async function downloadAndStoreBungieDefinitions(bungieManifest: BungieManifest } await saveBungieDefinitionsVersion(versionKey); + set({ bungieDefinitionsReady: true }); } catch (e) { console.error("Failed to download and save bungieDefinition", e); if (failCount < 3) { failCount++; console.error("Failed to download and save bungieDefinition", e); - await downloadAndStoreBungieDefinitions(bungieManifest); + await downloadAndStoreBungieDefinitions(set, bungieManifest); } else { // show error toast console.error("Failed to download and save bungieDefinition", e); @@ -297,7 +305,7 @@ async function downloadAndStoreBungieDefinitions(bungieManifest: BungieManifest } } -async function loadLocalBungieDefinitions(): Promise { +async function loadLocalBungieDefinitions(set: DefinitionsSliceSetter): Promise { try { const loadSocketTypeDefinition = await getAsyncStorage("DestinySocketCategoryDefinition"); const socketDefJson = JSON.parse(loadSocketTypeDefinition); @@ -314,6 +322,7 @@ async function loadLocalBungieDefinitions(): Promise { const loadInventoryBucketDefinition = await getAsyncStorage("DestinyInventoryBucketDefinition"); const inventoryBucketDefJson = JSON.parse(loadInventoryBucketDefinition); setDestinyInventoryBucketDefinition(inventoryBucketDefJson as InventoryBucketDefinition); + set({ bungieDefinitionsReady: true }); } catch (e) { console.error("Failed to load bungieDefinition version", e); saveBungieDefinitionsVersion(""); @@ -352,7 +361,7 @@ function parseAndSet(itemDefinition: ItemResponse) { setUiPlugLabel(itemDefinition.helpers.UiPlugLabel); setIcons(itemDefinition.helpers.Icons); - return { definitionsReady: true }; + return { itemsDefinitionReady: true }; } function getData(storageKey: StorageKey, errorMessage: string): Promise {