From 7d3fbd78421d8f30d03a702fc4f3a7721c3e5e37 Mon Sep 17 00:00:00 2001 From: d1rshan Date: Sun, 26 Apr 2026 17:32:29 +0530 Subject: [PATCH 1/3] fix(funbox): avoid reinitializing funboxes on test page exit (@d1rshan) --- frontend/src/ts/pages/test.ts | 1 + frontend/src/ts/test/test-logic.ts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/frontend/src/ts/pages/test.ts b/frontend/src/ts/pages/test.ts index 3abbf34aab78..d77a962ff14f 100644 --- a/frontend/src/ts/pages/test.ts +++ b/frontend/src/ts/pages/test.ts @@ -18,6 +18,7 @@ export const page = new Page({ afterHide: async (): Promise => { TestLogic.restart({ noAnim: true, + skipInit: true, }); void Funbox.clear(); void ModesNotice.update(); diff --git a/frontend/src/ts/test/test-logic.ts b/frontend/src/ts/test/test-logic.ts index 3ce10c09a91a..b894db0169d7 100644 --- a/frontend/src/ts/test/test-logic.ts +++ b/frontend/src/ts/test/test-logic.ts @@ -175,6 +175,7 @@ type RestartOptions = { practiseMissed?: boolean; noAnim?: boolean; isQuickRestart?: boolean; + skipInit?: boolean; }; export function restart(options = {} as RestartOptions): void { @@ -184,6 +185,7 @@ export function restart(options = {} as RestartOptions): void { noAnim: false, nosave: false, isQuickRestart: false, + skipInit: false, }; options = { ...defaultOptions, ...options }; @@ -353,6 +355,12 @@ export function restart(options = {} as RestartOptions): void { TestState.setPaceRepeat(repeatWithPace); TestInitFailed.hide(); TestState.setTestInitSuccess(true); + + if (options.skipInit) { + TestState.setTestRestarting(false); + return; + } + const initResult = await init(); if (!initResult) { From bedb09b9b8e16336f22199d634fd65b3a9b42366 Mon Sep 17 00:00:00 2001 From: d1rshan Date: Sun, 3 May 2026 00:17:09 +0530 Subject: [PATCH 2/3] better fix --- frontend/src/ts/controllers/page-controller.ts | 7 +++++++ frontend/src/ts/pages/test.ts | 1 - frontend/src/ts/states/core.ts | 4 ++++ frontend/src/ts/test/test-logic.ts | 15 ++++++--------- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/frontend/src/ts/controllers/page-controller.ts b/frontend/src/ts/controllers/page-controller.ts index b777f0eec1f3..9afa57310fed 100644 --- a/frontend/src/ts/controllers/page-controller.ts +++ b/frontend/src/ts/controllers/page-controller.ts @@ -4,6 +4,7 @@ import { getActivePage, setActivePage, setSelectedProfileName, + setTestPageVisible, } from "../states/core"; import * as Settings from "../pages/settings"; import * as Account from "../pages/account"; @@ -241,6 +242,9 @@ export async function change( }); previousPage.element.hide(); await previousPage?.afterHide(); + if (previousPage?.id === "test") { + setTestPageVisible(false); + } // we need to evaluate and store next page loading mode in case options.loadingOptions.loadingMode is sync const nextPageLoadingMode = nextPage.loadingOptions?.loadingMode(); @@ -291,6 +295,9 @@ export async function change( setActivePage(nextPage.id); updateOpenGraphUrl(); Focus.set(false); + if (nextPage.id === "test") { + setTestPageVisible(true); + } //next page await nextPage?.beforeShow({ diff --git a/frontend/src/ts/pages/test.ts b/frontend/src/ts/pages/test.ts index d77a962ff14f..3abbf34aab78 100644 --- a/frontend/src/ts/pages/test.ts +++ b/frontend/src/ts/pages/test.ts @@ -18,7 +18,6 @@ export const page = new Page({ afterHide: async (): Promise => { TestLogic.restart({ noAnim: true, - skipInit: true, }); void Funbox.clear(); void ModesNotice.update(); diff --git a/frontend/src/ts/states/core.ts b/frontend/src/ts/states/core.ts index b8023581092b..4d1a36935a90 100644 --- a/frontend/src/ts/states/core.ts +++ b/frontend/src/ts/states/core.ts @@ -35,3 +35,7 @@ export const isAuthenticated = (): boolean => getUserId() !== null; export const [getSelectedProfileName, setSelectedProfileName] = createSignal< string | undefined >(undefined); + +export const [isTestPageVisible, setTestPageVisible] = createSignal( + getActivePage() === "test", +); diff --git a/frontend/src/ts/test/test-logic.ts b/frontend/src/ts/test/test-logic.ts index cee3d08a164a..d78fb182a0a7 100644 --- a/frontend/src/ts/test/test-logic.ts +++ b/frontend/src/ts/test/test-logic.ts @@ -26,7 +26,11 @@ import * as TodayTracker from "./today-tracker"; import * as ChallengeContoller from "../controllers/challenge-controller"; import { clearQuoteStats } from "../states/quote-rate"; import * as Result from "./result"; -import { getActivePage, isAuthenticated } from "../states/core"; +import { + getActivePage, + isAuthenticated, + isTestPageVisible, +} from "../states/core"; import { setResultVisible, setWordsHaveNewline, @@ -175,7 +179,6 @@ type RestartOptions = { practiseMissed?: boolean; noAnim?: boolean; isQuickRestart?: boolean; - skipInit?: boolean; }; export function restart(options = {} as RestartOptions): void { @@ -185,7 +188,6 @@ export function restart(options = {} as RestartOptions): void { noAnim: false, nosave: false, isQuickRestart: false, - skipInit: false, }; options = { ...defaultOptions, ...options }; @@ -356,11 +358,6 @@ export function restart(options = {} as RestartOptions): void { TestInitFailed.hide(); TestState.setTestInitSuccess(true); - if (options.skipInit) { - TestState.setTestRestarting(false); - return; - } - const initResult = await init(); if (!initResult) { @@ -431,7 +428,7 @@ async function init(): Promise { return await init(); } - if (getActivePage() === "test") { + if (isTestPageVisible()) { await Funbox.activate(); } From ee325a786f5341b8b8384aeb664736936708f305 Mon Sep 17 00:00:00 2001 From: d1rshan Date: Sun, 3 May 2026 00:52:15 +0530 Subject: [PATCH 3/3] tidy --- frontend/src/ts/test/test-logic.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/ts/test/test-logic.ts b/frontend/src/ts/test/test-logic.ts index d78fb182a0a7..fbc258d2056f 100644 --- a/frontend/src/ts/test/test-logic.ts +++ b/frontend/src/ts/test/test-logic.ts @@ -357,7 +357,6 @@ export function restart(options = {} as RestartOptions): void { TestState.setPaceRepeat(repeatWithPace); TestInitFailed.hide(); TestState.setTestInitSuccess(true); - const initResult = await init(); if (!initResult) {