diff --git a/nix.shell b/nix.shell new file mode 100644 index 0000000..69dd8c8 --- /dev/null +++ b/nix.shell @@ -0,0 +1,5 @@ +{ pkgs ? import { } }: pkgs.mkShell { + packages = with pkgs; [ + nodejs + ]; +} \ No newline at end of file diff --git a/package.json b/package.json index f40e459..35f8610 100644 --- a/package.json +++ b/package.json @@ -1,50 +1,50 @@ { "devDependencies": { - "@babel/core": "^7.14.3", - "@babel/eslint-parser": "^7.14.4", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-decorators": "^7.14.2", - "@babel/plugin-proposal-object-rest-spread": "^7.14.4", - "@babel/plugin-transform-runtime": "^7.14.3", - "@babel/preset-env": "^7.14.4", - "@types/file-saver": "^2.0.2", - "@types/prismjs": "^1.16.5", - "@types/uikit": "^3.3.1", - "@typescript-eslint/eslint-plugin": "^4.25.0", - "@typescript-eslint/parser": "^4.25.0", - "babel-loader": "^8.2.2", + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-object-rest-spread": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@types/file-saver": "^2.0.4", + "@types/prismjs": "^1.16.6", + "@types/uikit": "^3.3.2", + "@typescript-eslint/eslint-plugin": "^5.4.0", + "@typescript-eslint/parser": "^5.4.0", + "babel-loader": "^8.2.3", "clipboard": "^2.0.8", - "codejar": "^3.4.0", - "core-js": "^3.13.1", - "css-loader": "^5.2.6", - "date-fns": "^2.22.1", - "eslint": "^7.27.0", + "codejar": "^3.5.0", + "core-js": "^3.19.1", + "css-loader": "^6.5.1", + "date-fns": "^2.26.0", + "eslint": "^8.3.0", "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.23.4", - "eslint-plugin-prettier": "^3.4.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-sort-imports-es6-autofix": "^0.6.0", "file-saver": "^2.0.5", "git-revision-webpack-plugin": "^5.0.0", - "html-webpack-plugin": "^5.3.1", - "i18next": "^20.3.1", - "mini-css-extract-plugin": "^2.0.0", - "node-sass": "^6.0.0", + "html-webpack-plugin": "^5.5.0", + "i18next": "^21.5.2", + "mini-css-extract-plugin": "^2.4.5", + "node-sass": "^6.0.1", "normalize.css": "^8.0.1", - "preact": "^10.5.13", - "prettier": "^2.3.0", - "prismjs": "^1.23.0", - "qr-scanner": "^1.2.0", + "preact": "^10.5.15", + "prettier": "^2.4.1", + "prismjs": "^1.25.0", + "qr-scanner": "^1.3.0", "raw-loader": "^4.0.2", - "sass-loader": "^12.1.0", - "ts-loader": "^9.2.2", - "typescript": "^4.3.2", - "uikit": "^3.6.22", - "webpack": "^5.38.1", - "webpack-cli": "^4.7.0", - "webpack-dev-server": "^3.11.2", - "z-pagerouter": "^1.0.6" + "sass-loader": "^12.3.0", + "ts-loader": "^9.2.6", + "typescript": "^4.5.2", + "uikit": "^3.9.3", + "webpack": "^5.64.2", + "webpack-cli": "^4.9.1", + "webpack-dev-server": "^4.5.0" }, "dependencies": { - "css-minimizer-webpack-plugin": "^3.0.0" + "css-minimizer-webpack-plugin": "^3.1.4", + "npm-update": "^2.1.0" } } diff --git a/src/allPages.ts b/src/allPages.ts index 1c83a47..d639c82 100644 --- a/src/allPages.ts +++ b/src/allPages.ts @@ -1,7 +1,4 @@ -// So that we dont get `PageType not found in 'z-pagerouter' import/named` -/* eslint-disable */ -import { PageType } from "z-pagerouter"; -/* eslint-enable */ +import { PageType } from "./pagerouter/PageType"; import { AccessHomePage } from "./pages/Access/AccessHome"; import { AuthHomePage } from "./pages/Access/Auth/AuthHome"; diff --git a/src/elements/NavBar.tsx b/src/elements/NavBar.tsx index 8fcb043..ac47dc9 100644 --- a/src/elements/NavBar.tsx +++ b/src/elements/NavBar.tsx @@ -1,5 +1,5 @@ import { JSX, render } from "preact"; -import { PageRouter } from "z-pagerouter"; +import { PageRouter } from "../pagerouter/PageRouter"; import i18next from "i18next"; export type NavBarProps = { diff --git a/src/main.tsx b/src/main.tsx index 1866f2c..cd7a7fd 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -22,7 +22,7 @@ Prism.highlightAll(); import translations from "./translations/index.mjs"; // Actual Imports -import { PageRouter } from "z-pagerouter"; +import { PageRouter } from "./pagerouter/PageRouter"; import { formatDistance } from "./formatDistance"; import { getSealStatus } from "./api/sys/getSealStatus"; import { pageList } from "./allPages"; diff --git a/src/pageUtils.ts b/src/pageUtils.ts index b4af84f..403c4f3 100644 --- a/src/pageUtils.ts +++ b/src/pageUtils.ts @@ -1,4 +1,4 @@ -import { PageRouter } from "z-pagerouter"; +import { PageRouter } from "./pagerouter/PageRouter"; import { PageState } from "./state/PageState"; import { getSealStatus } from "./api/sys/getSealStatus"; import { lookupSelf } from "./api/sys/lookupSelf"; diff --git a/src/pagerouter/PageListType.ts b/src/pagerouter/PageListType.ts new file mode 100644 index 0000000..7057156 --- /dev/null +++ b/src/pagerouter/PageListType.ts @@ -0,0 +1,6 @@ +import { PageType } from "./PageType"; + +export type PageListType = { + getPageIDs(): Promise; + getPage(pageID: string): Promise; +} \ No newline at end of file diff --git a/src/pagerouter/PageRouter.ts b/src/pagerouter/PageRouter.ts new file mode 100644 index 0000000..9ea488b --- /dev/null +++ b/src/pagerouter/PageRouter.ts @@ -0,0 +1,105 @@ +import { PageType } from "./PageType"; +import { PageListType } from "./PageListType"; + +const PageDoesNotExistError = new Error("Page does not exist."); +const PageHasNotBeenSetError = new Error("Page has not been set."); + +export type Options = { + pageList: PageListType; + state: unknown; + pageContentElement: HTMLElement; + pageTitleElement: HTMLElement; + resetElementContent?: Boolean; + onPageChange: () => void; +} + +export class PageRouter { + constructor( + options: Options + ) { + this.pageList = options.pageList; + this.state = options.state; + this.pageContentElement = options.pageContentElement; + this.pageTitleElement = options.pageTitleElement; + this.resetElementContent = (options.resetElementContent || true) == true; + this.onPageChange = (options.onPageChange); + } + + public onPageChange: () => void; + + private pageList: PageListType; + private currentPageID: string; + private currentPage: PageType; + + private resetElementContent: Boolean; + + public state: unknown; + public pageContentElement: HTMLElement; + public pageTitleElement: HTMLElement; + + public async getPageIDs(): Promise { + return await this.pageList.getPageIDs(); + } + + public async getCurrentPage(): Promise { + return this.currentPage; + } + + public async getCurrentPageID(): Promise { + return this.currentPageID; + } + + public async setPageContent(content: string | HTMLElement): Promise { + if (typeof content === "string") { + this.pageContentElement.innerHTML = content; + } else { + this.pageContentElement.innerHTML = ""; + this.pageContentElement.appendChild(content); + } + } + + public async changePage(pageID: string): Promise { + 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 = await this.pageList.getPage(pageID); + + await this.currentPage.setRouterAndState(this, this.state); + + // Dispatch an event saying the page has been changed. + this.onPageChange(); + + // Render the page. + await this.renderPage(); + } + + public async renderPage(): Promise { + if (!this.currentPage) throw PageHasNotBeenSetError; + + if (this.resetElementContent) { + // Reset back to blank. + this.pageContentElement.innerHTML = ""; + this.pageTitleElement.innerHTML = ""; + } + await Promise.all([ + this.currentPage.renderPageTitle(), + this.currentPage.render(), + ]) +; + } + + public async refresh(): Promise { + await this.renderPage(); + } + + public async goBack(): Promise { + if (!this.currentPage) throw PageHasNotBeenSetError; + await this.currentPage.goBack(); + } +} diff --git a/src/pagerouter/PageType.ts b/src/pagerouter/PageType.ts new file mode 100644 index 0000000..feb0d7c --- /dev/null +++ b/src/pagerouter/PageType.ts @@ -0,0 +1,9 @@ +import { PageRouter } from "./PageRouter"; + +export type PageType = { + render(): Promise; + renderPageTitle(): Promise; + goBack(): Promise; + cleanup(): Promise; + setRouterAndState(router: PageRouter, state: unknown): Promise; +} \ No newline at end of file diff --git a/src/playground.tsx b/src/playground.tsx index d084d02..38ca770 100644 --- a/src/playground.tsx +++ b/src/playground.tsx @@ -1,4 +1,4 @@ -import { PageRouter } from "z-pagerouter"; +import { PageRouter } from "./pagerouter/PageRouter"; import { PageState } from "./state/PageState"; import i18next from "i18next"; diff --git a/src/types/Page.ts b/src/types/Page.ts index 082dc4d..f77beae 100644 --- a/src/types/Page.ts +++ b/src/types/Page.ts @@ -1,4 +1,4 @@ -import { PageRouter } from "z-pagerouter"; +import { PageRouter } from "../pagerouter/PageRouter"; import { PageState } from "../state/PageState"; export class Page { diff --git a/webpack-dev.config.js b/webpack-dev.config.js index f46bcd2..ce8cb6e 100644 --- a/webpack-dev.config.js +++ b/webpack-dev.config.js @@ -30,7 +30,7 @@ module.exports = { }) ], devServer: { - open: process.env.BROWSER || "microsoft-edge-dev", + open: process.env.BROWSER, }, resolve: { modules: ['node_modules'],