diff --git a/native/app/Root.tsx b/native/app/Root.tsx index 50f963a3b..38782fb68 100644 --- a/native/app/Root.tsx +++ b/native/app/Root.tsx @@ -153,6 +153,7 @@ function Root() { console.error("No navigationRef"); } } else if (authenticated === "AUTHENTICATED" && itemsDefinitionReady && bungieDefinitionsReady) { + useGGStore.getState().loadCachedProfile(); getFullProfile(); useGGStore.getState().setLastRefreshTime(); const intervalId = setInterval(refreshIfNeeded, 2000); diff --git a/native/app/store/Account/AccountSlice.ts b/native/app/store/Account/AccountSlice.ts index a992c1385..e39df074d 100644 --- a/native/app/store/Account/AccountSlice.ts +++ b/native/app/store/Account/AccountSlice.ts @@ -52,18 +52,21 @@ import { updateAllPages, } from "@/app/store/InventoryLogic.ts"; import { bitmaskContains } from "@/app/utilities/Helpers.ts"; -import type { - BucketHash, - CharacterId, - DestinyItemBase, - GuardianData, - ItemHash, - ProfileData, +import { + getSimpleProfileSchema, + type BucketHash, + type CharacterId, + type DestinyItemBase, + type GuardianData, + type ItemHash, + type ProfileData, } from "@/app/core/GetProfile.ts"; import { InventoryPageEnums, lightLevelBuckets, type UISections } from "@/app/inventory/logic/Helpers.ts"; import { iconUrl, screenshotUrl } from "@/app/core/ApiResponse.ts"; import { DamageType, DestinyClass, ItemSubType, ItemType, SectionBuckets, TierType } from "@/app/bungie/Enums.ts"; import { ArmorSort, WeaponsSort } from "@/app/store/Types.ts"; +import { getAsyncStorage, setAsyncStorage } from "@/app/store/DefinitionsSlice.ts"; +import { safeParse } from "valibot"; export type AccountSliceSetter = Parameters>[0]; export type AccountSliceGetter = Parameters>[1]; @@ -126,6 +129,7 @@ export interface AccountSlice { setSecondarySpecial: (characterId: CharacterId, itemHash: ItemHash) => void; setLastRefreshTime: () => void; setDemoMode: () => Promise; + loadCachedProfile: () => Promise; getCharacterIndex: (characterId: CharacterId) => number; updateLightLevel: () => void; showInventoryMenu: (show: boolean) => void; @@ -229,8 +233,16 @@ export const createAccountSlice: StateCreator = (s }, updateProfile: (profile) => { + const p1 = performance.now(); updateProfile(get, set, profile); + const p2 = performance.now(); + console.log("update entire Profile", `${(p2 - p1).toFixed(4)} ms`); get().updateLightLevel(); + try { + setAsyncStorage("CACHED_PROFILE", JSON.stringify(profile)); + } catch (e) { + console.error("Failed to save cached profile", e); + } }, setQuantityToTransfer: (quantityToTransfer) => { @@ -290,6 +302,24 @@ export const createAccountSlice: StateCreator = (s updateProfile(get, set, await demoData.json()); get().updateLightLevel(); }, + loadCachedProfile: async () => { + try { + const p1 = performance.now(); + const cachedProfile = await getAsyncStorage("CACHED_PROFILE"); + if (cachedProfile) { + const profileData = JSON.parse(cachedProfile); + const p2 = performance.now(); + console.log("load cached profile", `${(p2 - p1).toFixed(4)} ms`); + const validatedProfile = safeParse(getSimpleProfileSchema, profileData); + if (validatedProfile.success) { + updateProfile(get, set, validatedProfile.output as ProfileData); + get().updateLightLevel(); + } + } + } catch (e) { + console.error("Failed to load cached profile", e); + } + }, getCharacterIndex: (characterId: CharacterId) => { const characterIndex = get().ggCharacters.findIndex((character) => character.characterId === characterId); return characterIndex; diff --git a/native/app/store/Authentication/AuthenticationSlice.ts b/native/app/store/Authentication/AuthenticationSlice.ts index 8687ddc55..f417a1abc 100644 --- a/native/app/store/Authentication/AuthenticationSlice.ts +++ b/native/app/store/Authentication/AuthenticationSlice.ts @@ -17,6 +17,7 @@ import { BungieProfileSchema, type BungieMembershipProfiles, type LinkedProfiles import { getBungieUser } from "@/app/bungie/Account.ts"; import { safeParse } from "valibot"; import { InventoryPageEnums } from "@/app/inventory/logic/Helpers.ts"; +import { setAsyncStorage } from "@/app/store/DefinitionsSlice.ts"; const initialBungieUser = { supplementalDisplayName: "", @@ -115,6 +116,7 @@ export const createAuthenticationSlice: StateCreator set({ inventorySectionWidth }), clearCache: () => { + setAsyncStorage("CACHED_PROFILE", ""); set({ itemDefinitionVersion: "", bungieDefinitionVersions: "", itemsDefinitionReady: false }); }, }); diff --git a/native/app/store/Types.ts b/native/app/store/Types.ts index 02acda312..1b4dca132 100644 --- a/native/app/store/Types.ts +++ b/native/app/store/Types.ts @@ -1,7 +1,7 @@ import type { DefinitionKey } from "@/app/core/BungieDefinitions.ts"; export type StorageKey = "ITEM_DEFINITION" | "ACCOUNTS"; -export type AsyncStorageKey = DefinitionKey; +export type AsyncStorageKey = DefinitionKey | "CACHED_PROFILE"; export enum WeaponsSort { Power = "POWER",