Skip to content

Commit

Permalink
refactor: All defintions must load to init the app (#2087)
Browse files Browse the repository at this point in the history
  • Loading branch information
NigelBreslaw authored Jul 20, 2024
1 parent 3c648cd commit 97b2e17
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 27 deletions.
53 changes: 38 additions & 15 deletions native/app/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 = {
Expand Down Expand Up @@ -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<NavigationContainerRef<ReactNavigation.RootParamList>>(null);
const { width } = useWindowDimensions();
Expand All @@ -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;
Expand Down
33 changes: 21 additions & 12 deletions native/app/store/DefinitionsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<StateCreator<IStore, [], [], DefinitionsSlice>>[0];
export type DefinitionsSliceGetter = Parameters<StateCreator<IStore, [], [], DefinitionsSlice>>[1];

export interface DefinitionsSlice {
definitionsReady: boolean;
itemsDefinitionReady: boolean;
bungieDefinitionsReady: boolean;
snackBarVisible: boolean;
snackBarMessage: string;
inventorySectionWidth: number;
Expand All @@ -79,7 +81,8 @@ export interface DefinitionsSlice {
}

export const createDefinitionsSlice: StateCreator<IStore, [], [], DefinitionsSlice> = (set, get) => ({
definitionsReady: false,
itemsDefinitionReady: false,
bungieDefinitionsReady: false,
snackBarVisible: false,
snackBarMessage: "",
inventorySectionWidth: 0,
Expand Down Expand Up @@ -133,18 +136,20 @@ export const createDefinitionsSlice: StateCreator<IStore, [], [], DefinitionsSli
try {
if (storedVersion === "") {
// download a version
await downloadAndStoreBungieDefinitions(bungieManifest);
await downloadAndStoreBungieDefinitions(set, bungieManifest);
} else if (versionKey === null) {
// try to use the already downloaded version
await loadLocalBungieDefinitions();
await loadLocalBungieDefinitions(set);
} else if (versionKey === storedVersion) {
// use the already downloaded version
await loadLocalBungieDefinitions();
await loadLocalBungieDefinitions(set);
} else {
// download a new version
console.log("download a new bungie definitions as KEY is different");
await downloadAndStoreBungieDefinitions(bungieManifest);
await downloadAndStoreBungieDefinitions(set, bungieManifest);
}
updateBucketSizes();
updateDestinyText();
} catch (e) {
console.error("Failed to load bungieDefinition version. Downloading new version...", e);
}
Expand All @@ -159,7 +164,7 @@ export const createDefinitionsSlice: StateCreator<IStore, [], [], DefinitionsSli
clearCache: () => {
saveItemDefinitionVersion("");
saveBungieDefinitionsVersion("");
set({ definitionsReady: false });
set({ itemsDefinitionReady: false });
},
});

Expand All @@ -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));
Expand All @@ -203,7 +207,10 @@ const NonInterpolationTable = [

let failCount = 0;

async function downloadAndStoreBungieDefinitions(bungieManifest: BungieManifest | null): Promise<void> {
async function downloadAndStoreBungieDefinitions(
set: DefinitionsSliceSetter,
bungieManifest: BungieManifest | null,
): Promise<void> {
const versionKey = bungieManifest?.Response.version;
if (!versionKey) {
console.error("No version key found in bungieManifest");
Expand Down Expand Up @@ -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);
Expand All @@ -297,7 +305,7 @@ async function downloadAndStoreBungieDefinitions(bungieManifest: BungieManifest
}
}

async function loadLocalBungieDefinitions(): Promise<void> {
async function loadLocalBungieDefinitions(set: DefinitionsSliceSetter): Promise<void> {
try {
const loadSocketTypeDefinition = await getAsyncStorage("DestinySocketCategoryDefinition");
const socketDefJson = JSON.parse(loadSocketTypeDefinition);
Expand All @@ -314,6 +322,7 @@ async function loadLocalBungieDefinitions(): Promise<void> {
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("");
Expand Down Expand Up @@ -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<JSON> {
Expand Down

0 comments on commit 97b2e17

Please sign in to comment.