mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-26 00:37:37 +08:00
refactor: page loadingOptions rework (@miodec, @fehmer) (#6949)
Co-authored-by: Miodec <jack@monkeytype.com>
This commit is contained in:
parent
31a7a2de08
commit
d1e118a01d
4 changed files with 51 additions and 29 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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<void> {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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.<br>If this error persists, please contact support."
|
||||
|
|
|
|||
|
|
@ -24,13 +24,19 @@ type Options<T> = {
|
|||
|
||||
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<void>;
|
||||
loadingPromise: () => Promise<void>;
|
||||
} & (
|
||||
| {
|
||||
style: "spinner";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue