Skip to content

Commit ac4a151

Browse files
authored
refactor: loading page rework (@Miodec) (monkeytypegame#6885)
- Moved all loading page logic to the page controller. No other module handles text or bar updating. The page controller displays either the spinner or loading bar (depending on the configuration) inbetween the source and target page. Once a promise resolves the page change continues. - Pages can now say they require a loading page before opening the page - Navigate function call can override that / add a loading page to any page load - Simplified account controller flow a lot - only one `navigate` call remains - Removed the preloader from the account page which simplifies things aswell - Moved loading page styles
1 parent 7c27898 commit ac4a151

File tree

20 files changed

+350
-256
lines changed

20 files changed

+350
-256
lines changed

frontend/src/html/pages/account.html

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
<div class="page pageAccount hidden full-width" id="pageAccount">
2-
<div class="preloader hidden">
2+
<div class="error hidden content-grid">
33
<div class="icon">
4-
<i class="fas fa-fw fa-spin fa-circle-notch"></i>
5-
</div>
6-
<div class="barWrapper hidden">
7-
<div class="bar">
8-
<div class="fill"></div>
9-
</div>
10-
<div class="text"></div>
4+
<i class="fas fa-fw fa-times"></i>
115
</div>
6+
<div class="text">Error</div>
127
</div>
138
<div class="content full-width content-grid">
149
<div class="profile">

frontend/src/styles/account.scss

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
.pageAccount {
22
height: 100%;
33

4+
.error {
5+
display: grid;
6+
place-items: center;
7+
align-content: center;
8+
height: 100%;
9+
.icon {
10+
font-size: 2rem;
11+
color: var(--error-color);
12+
}
13+
.text {
14+
font-size: 1rem;
15+
text-align: center;
16+
}
17+
}
18+
419
.accountVerificatinNotice {
520
background: var(--bg-color);
621
border-radius: var(--roundness);
@@ -23,13 +38,6 @@
2338
}
2439
}
2540

26-
.preloader {
27-
align-self: center;
28-
text-align: center;
29-
align-items: center;
30-
height: 100%;
31-
}
32-
3341
.content {
3442
gap: 2rem;
3543
}

frontend/src/styles/core.scss

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -208,42 +208,6 @@ key {
208208
align-items: center;
209209
}
210210

211-
.pageLoading,
212-
.pageAccount {
213-
.preloader {
214-
text-align: center;
215-
justify-self: center;
216-
display: grid;
217-
.barWrapper {
218-
justify-content: center;
219-
display: grid;
220-
gap: 1rem;
221-
grid-row: 1;
222-
grid-column: 1;
223-
.bar {
224-
width: 20rem;
225-
height: 0.5rem;
226-
background: var(--sub-alt-color);
227-
border-radius: var(--roundness);
228-
.fill {
229-
height: 100%;
230-
width: 0%;
231-
background: var(--main-color);
232-
border-radius: var(--roundness);
233-
// transition: 1s;
234-
}
235-
}
236-
}
237-
.icon {
238-
grid-row: 1;
239-
grid-column: 1;
240-
font-size: 2rem;
241-
color: var(--main-color);
242-
margin-bottom: 1rem;
243-
}
244-
}
245-
}
246-
247211
.devIndicator {
248212
position: fixed;
249213
font-size: 3rem;

frontend/src/styles/index.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@import "buttons", "fonts", "404", "ads", "about", "account", "animations",
22
"banners", "caret", "commandline", "core", "footer", "inputs", "keymap",
33
"login", "monkey", "nav", "notifications", "popups", "profile", "scroll",
4-
"settings", "account-settings", "leaderboards", "test", "media-queries";
4+
"settings", "account-settings", "leaderboards", "test", "loading",
5+
"media-queries";

frontend/src/styles/loading.scss

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.pageLoading {
2+
.preloader {
3+
text-align: center;
4+
justify-self: center;
5+
display: grid;
6+
.barWrapper {
7+
justify-content: center;
8+
display: grid;
9+
gap: 1rem;
10+
grid-row: 1;
11+
grid-column: 1;
12+
.text {
13+
height: 1.25em;
14+
}
15+
.bar {
16+
width: 20rem;
17+
height: 0.5rem;
18+
background: var(--sub-alt-color);
19+
border-radius: var(--roundness);
20+
justify-self: center;
21+
.fill {
22+
height: 100%;
23+
width: 0%;
24+
background: var(--main-color);
25+
border-radius: var(--roundness);
26+
// transition: 1s;
27+
}
28+
}
29+
}
30+
.icon {
31+
grid-row: 1;
32+
grid-column: 1;
33+
font-size: 2rem;
34+
color: var(--main-color);
35+
margin-bottom: 1rem;
36+
}
37+
}
38+
}

frontend/src/ts/commandline/lists/load-challenge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function update(challenges: Challenge[]): void {
2525
id: "loadChallenge" + capitalizeFirstLetterOfEachWord(challenge.name),
2626
display: challenge.display,
2727
exec: async (): Promise<void> => {
28-
navigate("/");
28+
await navigate("/");
2929
await ChallengeController.setup(challenge.name);
3030
TestLogic.restart({
3131
nosave: true,

frontend/src/ts/commandline/lists/navigation.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const commands: Command[] = [
1010
alias: "navigate go to start begin type test",
1111
icon: "fa-keyboard",
1212
exec: (): void => {
13-
navigate("/");
13+
void navigate("/");
1414
},
1515
},
1616
{
@@ -19,7 +19,7 @@ const commands: Command[] = [
1919
alias: "navigate go to",
2020
icon: "fa-crown",
2121
exec: (): void => {
22-
navigate("/leaderboards");
22+
void navigate("/leaderboards");
2323
},
2424
},
2525
{
@@ -28,7 +28,7 @@ const commands: Command[] = [
2828
alias: "navigate go to",
2929
icon: "fa-info",
3030
exec: (): void => {
31-
navigate("/about");
31+
void navigate("/about");
3232
},
3333
},
3434
{
@@ -37,7 +37,7 @@ const commands: Command[] = [
3737
alias: "navigate go to",
3838
icon: "fa-cog",
3939
exec: (): void => {
40-
navigate("/settings");
40+
void navigate("/settings");
4141
},
4242
},
4343

@@ -47,7 +47,7 @@ const commands: Command[] = [
4747
alias: "navigate go to stats",
4848
icon: "fa-user",
4949
exec: (): void => {
50-
isAuthenticated() ? navigate("/account") : navigate("/login");
50+
isAuthenticated() ? void navigate("/account") : void navigate("/login");
5151
},
5252
},
5353
{

frontend/src/ts/controllers/account-controller.ts

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ import Config, * as UpdateConfig from "../config";
44
import * as Misc from "../utils/misc";
55
import * as DB from "../db";
66
import * as Loader from "../elements/loader";
7-
import * as PageTransition from "../states/page-transition";
8-
import * as ActivePage from "../states/active-page";
9-
import * as LoadingPage from "../pages/loading";
107
import * as LoginPage from "../pages/login";
118
import * as RegisterCaptchaModal from "../modals/register-captcha";
129
import * as Account from "../pages/account";
@@ -65,13 +62,6 @@ async function sendVerificationEmail(): Promise<void> {
6562
async function getDataAndInit(): Promise<boolean> {
6663
try {
6764
console.log("getting account data");
68-
if (window.location.pathname !== "/account") {
69-
LoadingPage.updateBar(90);
70-
} else {
71-
LoadingPage.updateBar(45);
72-
}
73-
LoadingPage.updateText("Downloading user data...");
74-
await LoadingPage.showBar();
7565
const snapshot = await DB.initSnapshot();
7666

7767
if (snapshot === false) {
@@ -91,12 +81,6 @@ async function getDataAndInit(): Promise<boolean> {
9181
true
9282
);
9383
}
94-
if (ActivePage.get() === "loading") {
95-
LoadingPage.updateBar(100);
96-
} else {
97-
LoadingPage.updateBar(45);
98-
}
99-
LoadingPage.updateText("Applying settings...");
10084

10185
const areConfigsEqual =
10286
JSON.stringify(Config) === JSON.stringify(snapshot.config);
@@ -114,14 +98,8 @@ async function getDataAndInit(): Promise<boolean> {
11498
}
11599
}
116100
if (window.location.pathname === "/account") {
117-
LoadingPage.updateBar(90);
118101
await Account.downloadResults();
119102
}
120-
if (window.location.pathname === "/login") {
121-
navigate("/account");
122-
} else {
123-
navigate();
124-
}
125103
return true;
126104
} catch (error) {
127105
console.error(error);
@@ -155,56 +133,76 @@ async function getDataAndInit(): Promise<boolean> {
155133
}
156134

157135
export async function loadUser(_user: UserType): Promise<void> {
158-
// User is signed in.
159-
PageTransition.set(false);
160136
if (!(await getDataAndInit())) {
161137
signOut();
138+
return;
162139
}
163-
164140
AuthEvent.dispatch({ type: "snapshotUpdated", data: { isInitial: true } });
165-
166-
// var displayName = user.displayName;
167-
// var email = user.email;
168-
// var emailVerified = user.emailVerified;
169-
// var photoURL = user.photoURL;
170-
// var isAnonymous = user.isAnonymous;
171-
// var uid = user.uid;
172-
// var providerData = user.providerData;
173-
LoginPage.hidePreloader();
174-
175-
// showFavouriteThemesAtTheTop();
176141
}
177142

178143
export async function onAuthStateChanged(
179144
authInitialisedAndConnected: boolean,
180145
user: UserType | null
181146
): Promise<void> {
182147
console.debug(`account controller ready`);
148+
149+
let userPromise: Promise<void> = Promise.resolve();
150+
183151
if (authInitialisedAndConnected) {
184152
console.debug(`auth state changed, user ${user ? "true" : "false"}`);
185153
console.debug(user);
186154
if (user) {
187-
await loadUser(user);
155+
userPromise = loadUser(user);
188156
} else {
189-
if (window.location.pathname === "/account") {
190-
window.history.replaceState("", "", "/login");
191-
}
192-
193157
DB.setSnapshot(undefined);
194-
Sentry.clearUser();
195-
PageTransition.set(false);
196-
navigate();
197-
}
198-
} else {
199-
console.debug(`auth not initialised or not connected`);
200-
if (window.location.pathname === "/account") {
201-
window.history.replaceState("", "", "/login");
202158
}
159+
}
160+
161+
if (!authInitialisedAndConnected || !user) {
203162
Sentry.clearUser();
204-
PageTransition.set(false);
205-
navigate();
206163
}
207164

165+
let keyframes = [
166+
{
167+
percentage: 90,
168+
durationMs: 1000,
169+
text: "Downloading user data...",
170+
},
171+
];
172+
173+
if (
174+
window.location.pathname === "/account" ||
175+
window.location.pathname === "/login"
176+
) {
177+
keyframes = [
178+
{
179+
percentage: 40,
180+
durationMs: 1000,
181+
text: "Downloading user data...",
182+
},
183+
{
184+
percentage: 90,
185+
durationMs: 1000,
186+
text: "Downloading results...",
187+
},
188+
];
189+
}
190+
191+
//undefined means navigate to whatever the current window.location.pathname is
192+
await navigate(undefined, {
193+
force: true,
194+
overrideLoadingOptions: {
195+
shouldLoad: () => {
196+
return user !== null;
197+
},
198+
waitFor: async () => {
199+
await userPromise;
200+
},
201+
style: "bar",
202+
keyframes: keyframes,
203+
},
204+
});
205+
208206
AuthEvent.dispatch({
209207
type: "authStateChanged",
210208
data: { isUserSignedIn: user !== null },

0 commit comments

Comments
 (0)