From d5aa5001d0a06807822f4e46a9a87875132383e7 Mon Sep 17 00:00:00 2001 From: Miodec Date: Fri, 11 Feb 2022 15:59:20 +0100 Subject: [PATCH] completely reworked how page controller works page change is now generic and pages store their own callback functions active page now stores page name instead of element name adds 1 circular dependency. rip part of #2462 --- .../src/js/controllers/account-controller.js | 13 +- .../src/js/controllers/input-controller.js | 8 +- .../src/js/controllers/page-controller.js | 148 +++++------------- .../src/js/controllers/route-controller.js | 4 +- frontend/src/js/db.js | 8 +- frontend/src/js/elements/scroll-to-top.js | 4 +- frontend/src/js/pages/about.js | 19 +++ frontend/src/js/pages/account.js | 32 +++- frontend/src/js/pages/loading.js | 19 +++ frontend/src/js/pages/login.js | 19 +++ frontend/src/js/pages/page.js | 19 +++ frontend/src/js/pages/settings.js | 21 +++ frontend/src/js/pages/test.js | 33 ++++ frontend/src/js/states/active-page.js | 2 +- frontend/src/js/test/focus.js | 4 +- frontend/src/js/test/test-logic.js | 15 +- 16 files changed, 227 insertions(+), 141 deletions(-) create mode 100644 frontend/src/js/pages/login.js create mode 100644 frontend/src/js/pages/page.js create mode 100644 frontend/src/js/pages/test.js diff --git a/frontend/src/js/controllers/account-controller.js b/frontend/src/js/controllers/account-controller.js index d7dc595c6..515ae2bf2 100644 --- a/frontend/src/js/controllers/account-controller.js +++ b/frontend/src/js/controllers/account-controller.js @@ -75,9 +75,6 @@ const authListener = firebase.auth().onAuthStateChanged(async function (user) { // await UpdateConfig.loadPromise; console.log(`auth state changed, user ${user ? true : false}`); if (user) { - if (window.location.pathname == "/login") { - window.history.replaceState("", null, "/account"); - } await loadUser(user); } else { if (window.location.pathname == "/account") { @@ -85,12 +82,18 @@ const authListener = firebase.auth().onAuthStateChanged(async function (user) { } PageController.setTransition(false); } - if (window.location.pathname != "/account") { + if (window.location.pathname == "/login" && user) { + PageController.change("account"); + } else if (window.location.pathname != "/account") { + PageController.change(); setTimeout(() => { Focus.set(false); }, 125 / 2); + } else { + Account.update(); + // SignOutButton.show(); } - PageController.change(); + let theme = Misc.findGetParameter("customTheme"); if (theme !== null) { try { diff --git a/frontend/src/js/controllers/input-controller.js b/frontend/src/js/controllers/input-controller.js index 77d43a3f8..0d9df23a2 100644 --- a/frontend/src/js/controllers/input-controller.js +++ b/frontend/src/js/controllers/input-controller.js @@ -603,9 +603,9 @@ function handleTab(event) { $("#commandLineWrapper").hasClass("hidden") && $("#simplePopupWrapper").hasClass("hidden") && $("#quoteSubmitPopupWrapper").hasClass("hidden") && - ActivePage.get() != "pageLogin" + ActivePage.get() != "login" ) { - if (ActivePage.get() == "pageTest") { + if (ActivePage.get() == "test") { if (Config.quickTab) { if (!$("#leaderboardsWrapper").hasClass("hidden")) { Leaderboards.hide(); @@ -659,11 +659,11 @@ function handleTab(event) { } $(document).keydown((event) => { - if (ActivePage.get() == "pageLoading") return event.preventDefault(); + if (ActivePage.get() == "loading") return event.preventDefault(); //autofocus const wordsFocused = $("#wordsInput").is(":focus"); - const pageTestActive = ActivePage.get() === "pageTest"; + const pageTestActive = ActivePage.get() === "test"; const commandLineVisible = !$("#commandLineWrapper").hasClass("hidden"); const leaderboardsVisible = !$("#leaderboardsWrapper").hasClass("hidden"); diff --git a/frontend/src/js/controllers/page-controller.js b/frontend/src/js/controllers/page-controller.js index e747fe54b..8de09b463 100644 --- a/frontend/src/js/controllers/page-controller.js +++ b/frontend/src/js/controllers/page-controller.js @@ -1,16 +1,12 @@ -import * as Funbox from "./../test/funbox"; -import * as About from "./../pages/about"; import * as Misc from "./../misc"; import * as ActivePage from "./../states/active-page"; -import * as TestLogic from "./../test/test-logic"; import * as Settings from "./../pages/settings"; import * as Account from "./../pages/account"; -import * as TestUI from "./../test/test-ui"; -import * as TestConfig from "./../test/test-config"; -import * as SignOutButton from "./../account/sign-out-button"; -import * as TestStats from "./../test/test-stats"; import * as ManualRestart from "./../test/manual-restart-tracker"; -import Config from "./../config"; +import * as PageTest from "./../pages/test"; +import * as PageAbout from "./../pages/about"; +import * as PageLogin from "./../pages/login"; +import * as PageLoading from "./../pages/loading"; export let transition = true; @@ -18,12 +14,14 @@ export function setTransition(val) { transition = val; } -export function change(page, norestart = false) { +export function change(page) { if (transition) { console.log(`change page ${page} stopped`); return; } + console.log(`change page ${page}`); + if (page === "") page = "test"; if (page == undefined) { //use window loacation let pages = { @@ -40,111 +38,43 @@ export function change(page, norestart = false) { page = path; } - console.log(`change page ${page}`); - let activePageElement = $(".page.active"); - let check = ActivePage.get() + ""; - setTimeout(() => { - if (check === "pageAccount" && page !== "account") { - Account.reset(); - } else if (check === "pageSettings" && page !== "settings") { - Settings.reset(); - } else if (check === "pageAbout" && page !== "about") { - About.reset(); - } - }, 250); + if (ActivePage.get() === page) { + console.log(`page ${page} already active`); + return; + } + + const pages = { + loading: PageLoading.page, + test: PageTest.page, + settings: Settings.page, + about: PageAbout.page, + account: Account.page, + login: PageLogin.page, + }; + + const previousPage = pages[ActivePage.get()]; + const nextPage = pages[page]; ActivePage.set(undefined); $(".page").removeClass("active"); - $("#wordsInput").focusout(); - if (page == "test" || page == "") { - setTransition(true); - Misc.swapElements( - activePageElement, - $(".page.pageTest"), - 250, - () => { - setTransition(false); - TestUI.focusWords(); - $(".page.pageTest").addClass("active"); - ActivePage.set("pageTest"); - history.pushState("/", null, "/"); - }, - () => { - TestConfig.show(); - } - ); - SignOutButton.hide(); - // restartCount = 0; - // incompleteTestSeconds = 0; - TestStats.resetIncomplete(); - ManualRestart.set(); - if (!norestart) TestLogic.restart(); - Funbox.activate(Config.funbox); - } else if (page == "about") { - setTransition(true); - TestLogic.restart(); - Misc.swapElements(activePageElement, $(".page.pageAbout"), 250, () => { + previousPage?.beforeHide(); + setTransition(true); + Misc.swapElements( + previousPage.element, + nextPage.element, + 250, + () => { setTransition(false); - history.pushState("about", null, "about"); - $(".page.pageAbout").addClass("active"); - ActivePage.set("pageAbout"); - }); - About.fill(); - Funbox.activate("none"); - TestConfig.hide(); - SignOutButton.hide(); - } else if (page == "settings") { - setTransition(true); - TestLogic.restart(); - Misc.swapElements(activePageElement, $(".page.pageSettings"), 250, () => { - setTransition(false); - history.pushState("settings", null, "settings"); - $(".page.pageSettings").addClass("active"); - ActivePage.set("pageSettings"); - }); - Funbox.activate("none"); - Settings.fillSettingsPage().then(() => { - Settings.update(); - }); - // Settings.update(); - TestConfig.hide(); - SignOutButton.hide(); - } else if (page == "account") { - if (!firebase.auth().currentUser) { - console.log( - `current user is ${firebase.auth().currentUser}, going back to login` - ); - change("login"); - } else { - setTransition(true); - TestLogic.restart(); - Misc.swapElements(activePageElement, $(".page.pageAccount"), 250, () => { - setTransition(false); - history.pushState("account", null, "account"); - $(".page.pageAccount").addClass("active"); - ActivePage.set("pageAccount"); - }); - Funbox.activate("none"); - Account.update(); - TestConfig.hide(); + ActivePage.set(nextPage.name); + previousPage?.afterHide(); + nextPage.element.addClass("active"); + history.pushState(nextPage.pathname, null, nextPage.pathname); + nextPage?.afterShow(); + }, + () => { + nextPage?.beforeShow(); } - } else if (page == "login") { - if (firebase.auth().currentUser != null) { - change("account"); - } else { - setTransition(true); - TestLogic.restart(); - Misc.swapElements(activePageElement, $(".page.pageLogin"), 250, () => { - setTransition(false); - history.pushState("login", null, "login"); - $(".page.pageLogin").addClass("active"); - ActivePage.set("pageLogin"); - }); - Funbox.activate("none"); - TestConfig.hide(); - SignOutButton.hide(); - } - } + ); } $(document).on("click", "#top .logo", (e) => { diff --git a/frontend/src/js/controllers/route-controller.js b/frontend/src/js/controllers/route-controller.js index 47e93c551..c125d3219 100644 --- a/frontend/src/js/controllers/route-controller.js +++ b/frontend/src/js/controllers/route-controller.js @@ -19,7 +19,9 @@ export function handleInitialPageClasses(pathname) { let el = $(".page." + mappedRoutes[pathname]); $(el).removeClass("hidden"); $(el).addClass("active"); - ActivePage.set(mappedRoutes[pathname]); + let pageName = "loading"; + if (pathname === "/account") pageName = "account"; + ActivePage.set(pageName); } (function (history) { diff --git a/frontend/src/js/db.js b/frontend/src/js/db.js index 9e51c185a..0c0e92e69 100644 --- a/frontend/src/js/db.js +++ b/frontend/src/js/db.js @@ -50,7 +50,7 @@ export async function initSnapshot() { let snap = defaultSnap; try { if (firebase.auth().currentUser == null) return false; - // if (ActivePage.get() == "pageLoading") { + // if (ActivePage.get() == "loading") { // LoadingPage.updateBar(22.5); // } else { // LoadingPage.updateBar(16); @@ -88,7 +88,7 @@ export async function initSnapshot() { } else if (userData.lbMemory) { snap.lbMemory = userData.lbMemory; } - // if (ActivePage.get() == "pageLoading") { + // if (ActivePage.get() == "loading") { // LoadingPage.updateBar(45); // } else { // LoadingPage.updateBar(32); @@ -97,7 +97,7 @@ export async function initSnapshot() { if (configData) { snap.config = configData.config; } - // if (ActivePage.get() == "pageLoading") { + // if (ActivePage.get() == "loading") { // LoadingPage.updateBar(67.5); // } else { // LoadingPage.updateBar(48); @@ -113,7 +113,7 @@ export async function initSnapshot() { return 0; } }); - // if (ActivePage.get() == "pageLoading") { + // if (ActivePage.get() == "loading") { // LoadingPage.updateBar(90); // } else { // LoadingPage.updateBar(64); diff --git a/frontend/src/js/elements/scroll-to-top.js b/frontend/src/js/elements/scroll-to-top.js index f07eba2f3..3bbd2edda 100644 --- a/frontend/src/js/elements/scroll-to-top.js +++ b/frontend/src/js/elements/scroll-to-top.js @@ -8,8 +8,8 @@ $(".scrollToTopButton").click((event) => { $(window).scroll((e) => { let page = ActivePage.get(); - if (page == "pageTest") return; - if (page == "pageAbout" || page == "pageSettings" || page == "pageAccount") { + if (page == "test") return; + if (page == "about" || page == "settings" || page == "account") { let scroll = window.scrollY; if (!visible && scroll > 100) { $(".scrollToTopButton").removeClass("invisible"); diff --git a/frontend/src/js/pages/about.js b/frontend/src/js/pages/about.js index 29f2be195..b3df168c4 100644 --- a/frontend/src/js/pages/about.js +++ b/frontend/src/js/pages/about.js @@ -1,4 +1,5 @@ import * as Misc from "../misc"; +import Page from "./page"; export function reset() { $(".pageAbout .contributors").empty(); @@ -19,3 +20,21 @@ export async function fill() { `); }); } + +export const page = new Page( + "about", + $(".page.pageAbout"), + "/about", + () => { + // + }, + async () => { + reset(); + }, + () => { + fill(); + }, + () => { + // + } +); diff --git a/frontend/src/js/pages/account.js b/frontend/src/js/pages/account.js index 40ec8145d..a0dd2f79f 100644 --- a/frontend/src/js/pages/account.js +++ b/frontend/src/js/pages/account.js @@ -24,6 +24,7 @@ import axiosInstance from "../axios-instance"; import * as TodayTracker from "./../test/today-tracker"; import * as ActivePage from "../states/active-page"; import * as TestActive from "./../states/test-active"; +import Page from "./page"; let filterDebug = false; //toggle filterdebug @@ -37,7 +38,7 @@ export function toggleFilterDebug() { export async function getDataAndInit() { try { console.log("getting account data"); - if (ActivePage.get() == "pageLoading") { + if (ActivePage.get() == "loading") { LoadingPage.updateBar(90); } else { LoadingPage.updateBar(45); @@ -64,11 +65,11 @@ export async function getDataAndInit() { // $("#top #menu .account .icon").html(''); $("#top #menu .account").css("opacity", 1); - if (ActivePage.get() == "pageLoading") PageController.change(""); + if (ActivePage.get() == "loading") PageController.change(""); AccountController.signOut(); return; } - if (ActivePage.get() == "pageLoading") { + if (ActivePage.get() == "loading") { LoadingPage.updateBar(100); } else { LoadingPage.updateBar(45); @@ -213,7 +214,7 @@ export async function getDataAndInit() { UpdateConfig.apply(DB.getSnapshot().config); Settings.update(); UpdateConfig.saveToLocalStorage(true); - if (ActivePage.get() == "pageTest") { + if (ActivePage.get() == "test") { TestLogic.restart(false, true); } DB.saveConfig(Config); @@ -230,7 +231,7 @@ export async function getDataAndInit() { } } // if ( - // ActivePage.get() == "pageLogin" || + // ActivePage.get() == "login" || // window.location.pathname === "/account" // ) { // PageController.change("account"); @@ -244,7 +245,7 @@ export async function getDataAndInit() { Settings.showAccountSection(); PageController.setTransition(false); console.log("account loading finished"); - // if (ActivePage.get() == "pageLoading") { + // if (ActivePage.get() == "loading") { // LoadingPage.updateBar(100, true); // Focus.set(false); // PageController.change(""); @@ -1235,3 +1236,22 @@ $(document).on("click", ".buttonsAndTitle .buttons .button", (event) => { // We want to 'force' descending sort: sortAndRefreshHistory("timestamp", ".history-date-header", true); }); + +export const page = new Page( + "account", + $(".page.pageAccount"), + "/account", + () => { + SignOutButton.hide(); + }, + async () => { + reset(); + }, + () => { + update(); + // SignOutButton.show(); + }, + () => { + // + } +); diff --git a/frontend/src/js/pages/loading.js b/frontend/src/js/pages/loading.js index 49abc2bbd..1477e26ad 100644 --- a/frontend/src/js/pages/loading.js +++ b/frontend/src/js/pages/loading.js @@ -1,4 +1,5 @@ import * as Misc from "./../misc"; +import Page from "./page"; export function updateBar(percentage, fast) { const speed = fast ? 100 : 1000; @@ -36,3 +37,21 @@ export function showBar() { ); }); } + +export const page = new Page( + "loading", + $(".page.pageLoading"), + "/", + async () => { + // + }, + async () => { + // + }, + () => { + // + }, + () => { + // + } +); diff --git a/frontend/src/js/pages/login.js b/frontend/src/js/pages/login.js new file mode 100644 index 000000000..a2de89839 --- /dev/null +++ b/frontend/src/js/pages/login.js @@ -0,0 +1,19 @@ +import Page from "./page"; + +export const page = new Page( + "login", + $(".page.pageLogin"), + "/login", + () => { + // + }, + () => { + // + }, + () => { + // + }, + () => { + // + } +); diff --git a/frontend/src/js/pages/page.js b/frontend/src/js/pages/page.js new file mode 100644 index 000000000..451b6cad0 --- /dev/null +++ b/frontend/src/js/pages/page.js @@ -0,0 +1,19 @@ +export default class Page { + constructor( + name, + element, + pathname, + beforeHide, + afterHide, + beforeShow, + afterShow + ) { + this.name = name; + this.element = element; + this.pathname = pathname; + this.beforeHide = beforeHide; + this.afterHide = afterHide; + this.beforeShow = beforeShow; + this.afterShow = afterShow; + } +} diff --git a/frontend/src/js/pages/settings.js b/frontend/src/js/pages/settings.js index fb2535211..25b74caac 100644 --- a/frontend/src/js/pages/settings.js +++ b/frontend/src/js/pages/settings.js @@ -13,6 +13,7 @@ import * as ThemePicker from "../settings/theme-picker"; import * as ImportExportSettingsPopup from "../popups/import-export-settings-popup"; import * as CustomThemePopup from "../popups/custom-theme-popup"; import * as AccountController from "../controllers/account-controller"; +import Page from "./page"; export let groups = {}; async function initGroups() { @@ -919,3 +920,23 @@ $(".quickNav .links a").on("click", (e) => { ); isOpen && toggleSettingsGroup(settingsGroup); }); + +export const page = new Page( + "settings", + $(".page.pageSettings"), + "/settings", + () => { + // + }, + async () => { + reset(); + }, + () => { + fillSettingsPage().then(() => { + update(); + }); + }, + () => { + // + } +); diff --git a/frontend/src/js/pages/test.js b/frontend/src/js/pages/test.js new file mode 100644 index 000000000..b893f2ee3 --- /dev/null +++ b/frontend/src/js/pages/test.js @@ -0,0 +1,33 @@ +import Config from "./../config"; +import * as TestStats from "./../test/test-stats"; +import * as TestUI from "./../test/test-ui"; +import * as ManualRestart from "./../test/manual-restart-tracker"; +import * as TestConfig from "./../test/test-config"; +import * as TestLogic from "./../test/test-logic"; +import * as Funbox from "./../test/funbox"; +import Page from "./page"; + +export const page = new Page( + "test", + $(".page.pageTest"), + "/", + async () => { + TestLogic.restart(); + Funbox.activate("none"); + TestConfig.hide(); + $("#wordsInput").focusout(); + }, + async () => { + // + }, + () => { + TestConfig.show(); + TestStats.resetIncomplete(); + ManualRestart.set(); + TestLogic.restart(undefined, undefined, undefined, undefined, true); + Funbox.activate(Config.funbox); + }, + () => { + TestUI.focusWords(); + } +); diff --git a/frontend/src/js/states/active-page.js b/frontend/src/js/states/active-page.js index e55bba15c..a9390e903 100644 --- a/frontend/src/js/states/active-page.js +++ b/frontend/src/js/states/active-page.js @@ -1,4 +1,4 @@ -let activePage = "pageLoading"; +let activePage = "loading"; export function get() { return activePage; diff --git a/frontend/src/js/test/focus.js b/frontend/src/js/test/focus.js index 9042a4307..7cc93974a 100644 --- a/frontend/src/js/test/focus.js +++ b/frontend/src/js/test/focus.js @@ -23,8 +23,8 @@ export function set(foc, withCursor = false) { $(document).mousemove(function (event) { if (!state) return; - if (ActivePage.get() == "pageLoading") return; - if (ActivePage.get() == "pageAccount" && state == true) return; + if (ActivePage.get() == "loading") return; + if (ActivePage.get() == "account" && state == true) return; if ( $("#top").hasClass("focus") && (event.originalEvent.movementX > 0 || event.originalEvent.movementY > 0) diff --git a/frontend/src/js/test/test-logic.js b/frontend/src/js/test/test-logic.js index 32560f219..8c514378d 100644 --- a/frontend/src/js/test/test-logic.js +++ b/frontend/src/js/test/test-logic.js @@ -282,7 +282,8 @@ export function restart( withSameWordset = false, nosave = false, event, - practiseMissed = false + practiseMissed = false, + noAnim = false ) { if (TestUI.testRestarting || TestUI.resultCalculating) { try { @@ -290,7 +291,7 @@ export function restart( } catch {} return; } - if (ActivePage.get() == "pageTest" && !TestUI.resultVisible) { + if (ActivePage.get() == "test" && !TestUI.resultVisible) { if (!ManualRestart.get()) { if (TestWords.hasTab) { try { @@ -383,7 +384,7 @@ export function restart( $("#restartTestButton").blur(); Funbox.resetMemoryTimer(); QuoteRatePopup.clearQuoteStats(); - if (ActivePage.get() == "pageTest" && window.scrollY > 0) + if (ActivePage.get() == "test" && window.scrollY > 0) window.scrollTo({ top: 0, behavior: "smooth" }); $("#wordsInput").val(" "); @@ -414,9 +415,9 @@ export function restart( { opacity: 0, }, - 125, + noAnim ? 0 : 125, async () => { - if (ActivePage.get() == "pageTest") Focus.set(false); + if (ActivePage.get() == "test") Focus.set(false); TestUI.focusWords(); $("#monkey .fast").stop(true, true).css("opacity", 0); $("#monkey").stop(true, true).css({ animationDuration: "0s" }); @@ -554,7 +555,7 @@ export function restart( { opacity: 1, }, - 125, + noAnim ? 0 : 125, () => { TestUI.setTestRestarting(false); // resetPaceCaret(); @@ -958,7 +959,7 @@ export async function init() { // $("#words").css("height", "auto"); // $("#wordsWrapper").css("height", "auto"); // } else { - if (ActivePage.get() == "pageTest") { + if (ActivePage.get() == "test") { await Funbox.activate(); } TestUI.showWords();