diff --git a/frontend/src/ts/auth.ts b/frontend/src/ts/auth.ts index 68c159a53..04d0ec3cb 100644 --- a/frontend/src/ts/auth.ts +++ b/frontend/src/ts/auth.ts @@ -170,10 +170,14 @@ export async function onAuthStateChanged( await navigate(undefined, { force: true, loadingOptions: { - shouldLoad: () => { - return user !== null; + loadingMode: () => { + if (user !== null) { + return "sync"; + } else { + return "none"; + } }, - waitFor: async () => { + loadingPromise: async () => { await userPromise; }, style: "bar", diff --git a/frontend/src/ts/controllers/page-controller.ts b/frontend/src/ts/controllers/page-controller.ts index 8fcf84fed..90ff97724 100644 --- a/frontend/src/ts/controllers/page-controller.ts +++ b/frontend/src/ts/controllers/page-controller.ts @@ -50,7 +50,7 @@ function updateTitle(nextPage: { id: string; display?: string }): void { } } -async function showLoading({ +async function showSyncLoading({ loadingOptions, totalDuration, easingMethod, @@ -97,7 +97,7 @@ async function showLoading({ void PageLoading.updateBar(100, 125); PageLoading.updateText("Done"); } else { - await options.waitFor(); + await options.loadingPromise(); } } @@ -123,7 +123,7 @@ async function getLoadingPromiseWithBarKeyframes( fillOffset: number ): Promise { let aborted = false; - let loadingPromise = loadingOptions.waitFor(); + let loadingPromise = loadingOptions.loadingPromise(); // Animate bar keyframes, but allow aborting if loading.promise finishes first const keyframePromise = (async () => { @@ -214,28 +214,25 @@ export async function change( previousPage.element.addClass("hidden"); await previousPage?.afterHide(); + // we need to evaluate and store next page loading mode in case options.loadingOptions.loadingMode is sync + const nextPageLoadingMode = nextPage.loadingOptions?.loadingMode(); + //show loading page if needed try { - let loadingOptions: LoadingOptions[] = []; - if (options.loadingOptions) { - loadingOptions.push(options.loadingOptions); + let syncLoadingOptions: LoadingOptions[] = []; + if (options.loadingOptions?.loadingMode() === "sync") { + syncLoadingOptions.push(options.loadingOptions); } - if (nextPage.loadingOptions) { - loadingOptions.push(nextPage.loadingOptions); + if (nextPage.loadingOptions?.loadingMode() === "sync") { + syncLoadingOptions.push(nextPage.loadingOptions); } - if (loadingOptions.length > 0) { - const shouldShowLoading = - options.loadingOptions?.shouldLoad() || - nextPage.loadingOptions?.shouldLoad(); - - if (shouldShowLoading === true) { - await showLoading({ - loadingOptions, - totalDuration, - easingMethod, - }); - } + if (syncLoadingOptions.length > 0) { + await showSyncLoading({ + loadingOptions: syncLoadingOptions, + totalDuration, + easingMethod, + }); } } catch (error) { pages.loading.element.addClass("active"); @@ -263,6 +260,17 @@ export async function change( // @ts-expect-error for the future (i think) data: options.data, }); + + if ( + typeof nextPageLoadingMode === "object" && + nextPageLoadingMode.mode === "async" + ) { + nextPageLoadingMode.beforeLoading(); + void nextPage?.loadingOptions?.loadingPromise().then(() => { + nextPageLoadingMode.afterLoading(); + }); + } + nextPage.element.removeClass("hidden").css("opacity", 0); await Misc.promiseAnimation( nextPage.element, diff --git a/frontend/src/ts/pages/account.ts b/frontend/src/ts/pages/account.ts index 734985567..338c4e11c 100644 --- a/frontend/src/ts/pages/account.ts +++ b/frontend/src/ts/pages/account.ts @@ -1323,10 +1323,14 @@ export const page = new Page({ element: $(".page.pageAccount"), path: "/account", loadingOptions: { - shouldLoad: () => { - return DB.getSnapshot()?.results === undefined; + loadingMode: () => { + if (DB.getSnapshot()?.results === undefined) { + return "sync"; + } else { + return "none"; + } }, - waitFor: async () => { + loadingPromise: async () => { if (DB.getSnapshot() === null) { throw new Error( "Looks like your account data didn't download correctly. Please refresh the page.
If this error persists, please contact support." diff --git a/frontend/src/ts/pages/page.ts b/frontend/src/ts/pages/page.ts index c889dc99f..caf112b90 100644 --- a/frontend/src/ts/pages/page.ts +++ b/frontend/src/ts/pages/page.ts @@ -24,13 +24,19 @@ type Options = { export type LoadingOptions = { /** - * Should the loading screen be shown? + * Get the loading mode for this page. + * "none" - No loading screen will be shown. + * "sync" - A loading spinner or bar (depending on style) will be shown until the page is ready. + * { mode: "async", beforeLoading, afterLoading } - The loadingPromise will be executed in the background and afterLoading called after it resolves. */ - shouldLoad: () => boolean; + loadingMode: () => + | "none" + | "sync" + | { mode: "async"; beforeLoading: () => void; afterLoading: () => void }; /** * When this promise resolves, the loading screen will be hidden. */ - waitFor: () => Promise; + loadingPromise: () => Promise; } & ( | { style: "spinner";