1
0
Fork 0

Decouple the page routing system from pageState.

This commit is contained in:
Kitteh 2021-05-14 13:38:29 +01:00
parent 67d8d982c6
commit 8f448b80fc
6 changed files with 117 additions and 33 deletions

74
src/PageRouter.ts Normal file
View file

@ -0,0 +1,74 @@
import { Page } from "./types/Page";
import { getObjectKeys } from "./utils";
type pageList = {
[key: string]: Page;
};
const PageDoesNotExistError = new Error("Page does not exist.");
const PageHasNotBeenSetError = new Error("Page has not been set.");
export class PageRouter extends EventTarget {
constructor(pages: pageList, pageContentElement: HTMLElement, pageTitleElement: HTMLElement) {
super();
this.pages = pages;
this.pageContentElement = pageContentElement;
this.pageTitleElement = pageTitleElement;
}
private pages: pageList;
private currentPageID: string;
private currentPage: Page;
public pageContentElement: HTMLElement;
public pageTitleElement: HTMLElement;
public async getPageIDs(): Promise<string[]> {
return getObjectKeys(this.pages);
}
public async getCurrentPageID(): Promise<string> {
return this.currentPageID;
}
public async changePage(pageID: string): Promise<void> {
if (!(await this.getPageIDs()).includes(pageID)) throw PageDoesNotExistError;
// Do cleanup on current page.
if (this.currentPage) {
await this.currentPage.cleanup();
}
// Set the current page to the new page
this.currentPageID = pageID;
this.currentPage = this.pages[pageID];
// Dispatch an event saying the page has been changed.
this.dispatchEvent(new CustomEvent("pageChanged"));
// Render the page.
await this.renderPage();
}
public async renderPage(): Promise<void> {
if (!this.currentPage) throw PageHasNotBeenSetError;
// Reset back to blank.
this.pageContentElement.innerHTML = "";
this.pageTitleElement.innerHTML = "";
// TODO: Make Page have a getTitle method.
this.pageTitleElement.innerText = this.currentPage.name;
await this.currentPage.render();
}
public async refresh(): Promise<void> {
await this.renderPage();
}
public async goBack(): Promise<void> {
if (!this.currentPage) throw PageHasNotBeenSetError;
await this.currentPage.goBack();
}
}

View file

@ -1,8 +1,6 @@
import { ListItem } from "./ListItem"; import { ListItem } from "./ListItem";
import { Page } from "../types/Page";
import { changePage } from "../pageUtils";
import { makeElement } from "../htmlUtils"; import { makeElement } from "../htmlUtils";
import { pageState } from "../globalPageState"; import { pageRouter } from "../globalPageRouter";
import i18next from "i18next"; import i18next from "i18next";
export function NavBar(): HTMLElement { export function NavBar(): HTMLElement {
@ -23,7 +21,7 @@ export function NavBar(): HTMLElement {
tag: "a", tag: "a",
text: i18next.t("home_btn"), text: i18next.t("home_btn"),
onclick: async () => { onclick: async () => {
await changePage("HOME"); await pageRouter.changePage("HOME");
}, },
}), }),
), ),
@ -32,7 +30,7 @@ export function NavBar(): HTMLElement {
tag: "a", tag: "a",
text: i18next.t("back_btn"), text: i18next.t("back_btn"),
onclick: async () => { onclick: async () => {
await (pageState.currentPage as Page).goBack(); await pageRouter.goBack();
}, },
}), }),
), ),
@ -41,7 +39,7 @@ export function NavBar(): HTMLElement {
tag: "a", tag: "a",
text: i18next.t("refresh_btn"), text: i18next.t("refresh_btn"),
onclick: async () => { onclick: async () => {
await changePage(pageState.currentPageString); await pageRouter.refresh();
}, },
}), }),
), ),
@ -60,7 +58,7 @@ export function NavBar(): HTMLElement {
tag: "a", tag: "a",
text: i18next.t("me_btn"), text: i18next.t("me_btn"),
onclick: async () => { onclick: async () => {
await changePage("ME"); await pageRouter.changePage("ME");
}, },
}), }),
), ),

6
src/globalPageRouter.ts Normal file
View file

@ -0,0 +1,6 @@
import { PageRouter } from "./PageRouter";
export let pageRouter: PageRouter;
export function setPageRouter(router: PageRouter): void {
pageRouter = router;
}

View file

@ -17,15 +17,17 @@ import "prismjs/components/prism-json";
Prism.highlightAll(); Prism.highlightAll();
/* eslint-enable */ /* eslint-enable */
// Actual Imports
import { NavBar } from "./elements/NavBar"; import { NavBar } from "./elements/NavBar";
import { changePage, renderPage } from "./pageUtils"; import { PageRouter } from "./PageRouter";
import { allPages } from "./allPages";
import { formatDistance } from "./formatDistance";
import { getSealStatus } from "./api/sys/getSealStatus"; import { getSealStatus } from "./api/sys/getSealStatus";
import { makeElement } from "./htmlUtils"; import { makeElement } from "./htmlUtils";
import { pageState } from "./globalPageState"; import { pageState } from "./globalPageState";
import { playground } from "./playground"; import { playground } from "./playground";
import { setPageRouter } from "./globalPageRouter";
// Translations
import { formatDistance } from "./formatDistance";
import i18next from "i18next"; import i18next from "i18next";
// @ts-ignore // @ts-ignore
@ -65,23 +67,34 @@ async function onLoad(): Promise<void> {
window.pageContent = document.querySelector("#pageContent"); window.pageContent = document.querySelector("#pageContent");
const pageRouter = new PageRouter(
allPages,
document.getElementById("pageContent"),
document.getElementById("pageTitle"),
);
setPageRouter(pageRouter);
pageRouter.addEventListener("pageChanged", async function (_) {
pageState.currentPage = await pageRouter.getCurrentPageID();
document.documentElement.dir = pageState.pageDirection;
});
if (process.env.NODE_ENV == "development") { if (process.env.NODE_ENV == "development") {
await playground(); await playground();
} }
await renderPage(); await pageRouter.changePage(pageState.currentPageString);
setInterval(() => { setInterval(async () => {
if (pageState.currentPageString != "UNSEAL") { if ((await pageRouter.getCurrentPageID()) != "UNSEAL") {
if (pageState.apiURL.length != 0) { if (pageState.apiURL.length != 0) {
return; return;
} }
void getSealStatus().then((sealStatus) => { const sealStatus = await getSealStatus();
if (sealStatus.sealed) { if (sealStatus.sealed) {
void changePage("UNSEAL"); await pageRouter.changePage("UNSEAL");
return; return;
} }
});
} }
}, 5000); }, 5000);
} }

View file

@ -3,6 +3,7 @@ import { PageState } from "./PageState";
import { getSealStatus } from "./api/sys/getSealStatus"; import { getSealStatus } from "./api/sys/getSealStatus";
import { lookupSelf } from "./api/sys/lookupSelf"; import { lookupSelf } from "./api/sys/lookupSelf";
import { makeElement } from "./htmlUtils"; import { makeElement } from "./htmlUtils";
import { pageRouter } from "./globalPageRouter";
import { pageState } from "./globalPageState"; import { pageState } from "./globalPageState";
import ClipboardJS from "clipboard"; import ClipboardJS from "clipboard";
import UIkit from "uikit"; import UIkit from "uikit";
@ -79,19 +80,7 @@ export function setErrorText(text: string): void {
} }
export async function changePage(page: string): Promise<void> { export async function changePage(page: string): Promise<void> {
if (pageState.currentPage) { await pageRouter.changePage(page);
await (pageState.currentPage as Page).cleanup();
}
pageState.currentPage = page;
await renderPage();
}
export async function renderPage(): Promise<void> {
document.documentElement.dir = pageState.pageDirection;
console.log("Rendering Page: ", (pageState.currentPage as Page).name);
document.querySelector("#pageContent").innerHTML = "";
setPageTitle((pageState.currentPage as Page).name);
await (pageState.currentPage as Page).render();
} }
export function setPageTitle(title: string | HTMLElement): void { export function setPageTitle(title: string | HTMLElement): void {

View file

@ -1,4 +1,6 @@
import { PageRouter } from "./PageRouter";
import { PageState } from "./PageState"; import { PageState } from "./PageState";
import { pageRouter } from "./globalPageRouter";
import { pageState } from "./globalPageState"; import { pageState } from "./globalPageState";
import i18next from "i18next"; import i18next from "i18next";
@ -11,6 +13,7 @@ declare global {
interface Window { interface Window {
pageState: PageState; pageState: PageState;
i18next: unknown; i18next: unknown;
router: PageRouter;
} }
} }
@ -19,4 +22,5 @@ export async function playground(): Promise<void> {
console.log("Welcome to Playground!"); console.log("Welcome to Playground!");
window.pageState = pageState; window.pageState = pageState;
window.i18next = i18next; window.i18next = i18next;
window.router = pageRouter;
} }