From 30128107fb551754d0be7bfa96a3a553ee5a6414 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sat, 13 Dec 2025 22:14:49 -0800 Subject: [PATCH] cache user settings in cookie for faster modal loading store granblueId and showCrewGamertag in cookie at login, use as initial values so modal opens instantly --- src/lib/auth/map.ts | 4 +- src/lib/auth/oauth.ts | 2 + src/lib/components/UserSettingsModal.svelte | 73 +++++---------------- 3 files changed, 20 insertions(+), 59 deletions(-) diff --git a/src/lib/auth/map.ts b/src/lib/auth/map.ts index af1fd604..42b1cac3 100644 --- a/src/lib/auth/map.ts +++ b/src/lib/auth/map.ts @@ -18,7 +18,9 @@ export function buildCookies(oauth: OAuthLoginResponse, info: UserInfoResponse) element: info.avatar.element ?? '', language: info.language ?? 'en', gender: info.gender ?? 0, - theme: info.theme ?? 'system' + theme: info.theme ?? 'system', + granblueId: info.granblueId, + showCrewGamertag: info.showCrewGamertag } return { account, user, accessTokenExpiresAt, refresh: oauth.refresh_token } diff --git a/src/lib/auth/oauth.ts b/src/lib/auth/oauth.ts index d13d05da..f61acee8 100644 --- a/src/lib/auth/oauth.ts +++ b/src/lib/auth/oauth.ts @@ -27,6 +27,8 @@ export interface UserInfoResponse { language: string | null gender: number | null theme: string | null + granblueId?: string + showCrewGamertag?: boolean } export async function passwordGrantLogin( diff --git a/src/lib/components/UserSettingsModal.svelte b/src/lib/components/UserSettingsModal.svelte index c6433087..e673a2cc 100644 --- a/src/lib/components/UserSettingsModal.svelte +++ b/src/lib/components/UserSettingsModal.svelte @@ -38,20 +38,19 @@ let theme = $state(user.theme) let bahamut = $state(user.bahamut ?? false) - // Form state - fields from API (must wait for query to load) - // Initialize as empty - will be set by $effect when API data loads - let granblueId = $state('') - let showCrewGamertag = $state(false) - let apiDataLoaded = $state(false) + // Form state - fields that are also in cookie (use cookie as initial value) + let granblueId = $state(user.granblueId ?? '') + let showCrewGamertag = $state(user.showCrewGamertag ?? false) let saving = $state(false) let error = $state(null) - // Fetch current user data from API (to get actual show_gamertag value from database) + // Fetch current user data from API (to sync with latest database values) const currentUserQuery = createQuery(() => ({ queryKey: ['currentUser', 'settings'], queryFn: () => userAdapter.getCurrentUser(), - enabled: open // Only fetch when modal is open + enabled: open, // Only fetch when modal is open + staleTime: 5 * 60 * 1000 // Cache for 5 minutes })) // Fetch current user's crew (for showing gamertag toggle) @@ -62,21 +61,12 @@ const isInCrew = $derived(!!myCrewQuery.data) const crewGamertag = $derived(myCrewQuery.data?.gamertag) - const isLoadingApiData = $derived(currentUserQuery.isLoading || currentUserQuery.isPending) - // Update form state when API data loads (to get actual values from database) + // Sync form state when API returns fresher data than cookie $effect(() => { if (currentUserQuery.data) { granblueId = currentUserQuery.data.granblueId ?? '' showCrewGamertag = currentUserQuery.data.showCrewGamertag ?? false - apiDataLoaded = true - } - }) - - // Reset apiDataLoaded when modal closes so fresh data is fetched next time - $effect(() => { - if (!open) { - apiDataLoaded = false } }) @@ -252,31 +242,20 @@ /> - {#if isLoadingApiData} -
- Granblue ID - Loading... -
- {:else} - - {/if} + {#if isInCrew && crewGamertag}

Display "{crewGamertag}" next to your name

@@ -391,28 +370,6 @@ } } - .loading-field { - display: flex; - flex-direction: column; - gap: spacing.$unit-half; - - .loading-label { - font-size: typography.$font-small; - font-weight: typography.$medium; - color: var(--text-primary); - } - - .loading-text { - font-size: typography.$font-regular; - color: var(--text-secondary); - } - } - - .loading-text { - font-size: typography.$font-regular; - color: var(--text-secondary); - } - .picture-section { display: flex; gap: spacing.$unit-3x;