import { Client } from "./api/client.js"; import LoginView from "./views/accounts/LoginView.js"; import Dashboard from "./views/Dashboard.js"; import Search from "./views/Search.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 PageNotFoundView from './views/PageNotFoundView.js' import AbstractRedirectView from "./views/abstracts/AbstractRedirectView.js"; import MeView from "./views/MeView.js"; import ProfilePageView from "./views/ProfilePageView.js"; import MatchMakingView from "./views/MatchMakingView.js"; import TournamentPageView from "./views/TournamentPageView.js"; import TournamentsView from "./views/TournamentsListView.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); }; async function renderView(view) { let content = await view.getHtml(); if (content == null) return 1; view.setTitle(); document.querySelector("#app").innerHTML = content if (await view.postInit()) renderView(new PageNotFoundView()); } const router = async (uri) => { const routes = [ { path: "/", view: Dashboard }, { path: "/profiles/:id", view: ProfilePageView }, { path: "/tournaments/:id", view: TournamentPageView }, { path: "/tournaments/", view: TournamentsView}, { path: "/login", view: LoginView }, { path: "/logout", view: LogoutView }, { path: "/register", view: RegisterView }, { path: "/search", view: Search }, { path: "/home", view: HomeView }, { path: "/me", view: MeView }, { path: "/matchmaking", view: MatchMakingView }, { path: "/game/offline", 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: { path: uri, view: PageNotFoundView }, 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; await client.isAuthentificate(); renderView(view); return 0; }; window.addEventListener("popstate", function() {router(location.pathname)}); 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 }