import LoginView from "./views/accounts/LoginView.js"; import Dashboard from "./views/Dashboard.js"; import Posts from "./views/Posts.js"; import PostView from "./views/PostView.js"; import Settings from "./views/Settings.js"; import Chat from "./views/Chat.js"; import HomeView from "./views/HomeView.js"; import RegisterView from "./views/accounts/RegisterView.js"; import LogoutView from "./views/accounts/LogoutView.js"; import GameView from "./views/Game.js" import { Client } from "./api/client.js"; import AbstractRedirectView from "./views/AbstractRedirectView.js"; import MeView from "./views/MeView.js"; let client = new Client(location.protocol + "//" + location.host) let lastView = undefined const pathToRegex = path => new RegExp("^" + path.replace(/\//g, "\\/").replace(/:\w+/g, "(.+)") + "$"); const getParams = match => { const values = match.result.slice(1); const keys = Array.from(match.route.path.matchAll(/:(\w+)/g)).map(result => result[1]); return Object.fromEntries(keys.map((key, i) => { return [key, values[i]]; })); }; const navigateTo = async (uri) => { if (await router(uri) === 0) history.pushState(null, null, uri); }; const router = async (uri = "") => { const routes = [ { path: "/", view: Dashboard }, { path: "/posts", view: Posts }, { path: "/posts/:id", view: PostView }, { path: "/settings", view: Settings }, { path: "/login", view: LoginView }, { path: "/logout", view: LogoutView }, { path: "/register", view: RegisterView }, { path: "/chat", view: Chat }, { path: "/home", view: HomeView }, { path: "/me", view: MeView }, { path: "/game", view: GameView }, ]; // Test each route for potential match const potentialMatches = routes.map(route => { return { route: route, result: uri.match(pathToRegex(route.path)) }; }); let match = potentialMatches.find(potentialMatch => potentialMatch.result !== null); if (!match) { match = { route: routes[0], result: [uri] }; } if (lastView !== undefined) await lastView.leavePage(); const view = new match.route.view(getParams(match)); if (view instanceof AbstractRedirectView && await view.redirect()) return 1; lastView = view; let content = await view.getHtml(); if (content == null) return 1; view.setTitle(); document.querySelector("#app").innerHTML = content await view.postInit(); return 0; }; window.addEventListener("popstate", router); document.addEventListener("DOMContentLoaded", () => { document.body.addEventListener("click", e => { if (e.target.matches("[data-link]")) { e.preventDefault(); navigateTo(e.target.href.slice(location.origin.length)); } }); router(location.pathname); }); export { client, navigateTo }