Decouple the page routing system from pageState.
This commit is contained in:
parent
67d8d982c6
commit
8f448b80fc
74
src/PageRouter.ts
Normal file
74
src/PageRouter.ts
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
6
src/globalPageRouter.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { PageRouter } from "./PageRouter";
|
||||||
|
|
||||||
|
export let pageRouter: PageRouter;
|
||||||
|
export function setPageRouter(router: PageRouter): void {
|
||||||
|
pageRouter = router;
|
||||||
|
}
|
39
src/main.ts
39
src/main.ts
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue