42_ft_transcendence/frontend/static/js/index.js

171 lines
5.3 KiB
JavaScript

import { Client } from "./api/Client.js";
import Dashboard from "./views/Dashboard.js";
import Search from "./views/Search.js";
import HomeView from "./views/HomeView.js";
import LogoutView from "./views/accounts/LogoutView.js";
import GameOfflineView from "./views/GameOfflineView.js";
import GameView2D from "./views/GameView.js";
import GameView3D from "./views/GameView3D.js";
import PageNotFoundView from './views/PageNotFoundView.js' ;
import AbstractRedirectView from "./views/abstracts/AbstractRedirectView.js";
import SettingsView from "./views/SettingsView.js";
import ProfilePageView from "./views/ProfilePageView.js";
import MatchMakingView from "./views/MatchMakingView.js";
import TournamentPageView from "./views/tournament/TournamentPageView.js";
import TournamentsListView from "./views/tournament/TournamentsListView.js";
import TournamentCreateView from "./views/tournament/TournamentCreateView.js";
import AuthenticationView from "./views/accounts/AuthenticationView.js";
import TicTacToeView from "./views/TicTacToeView.js";
import GameHistoryView from "./views/GameHistoryView.js";
let client = new Client(location.origin);
let lang = client.lang;
let lastView;
let lastPageUrlBeforeLogin;
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) => {
history.pushState(null, null, uri);
if (await router(uri) !== 0)
return;
let link = document.querySelector('a[href=\'' + location.pathname + '\']');
if (link) {
document.querySelector('[data-link].active')?.classList.remove('active');
link.classList.add('active');
}
};
const reloadView = async _ => {
await lastView?.leavePage();
await renderView(lastView);
};
async function renderView(view)
{
let content = await view?.getHtml();
if (content == null)
return 1;
view.setTitle();
document.querySelector("#app").innerHTML = content;
let error_code = await view.postInit();
if (error_code === 404)
renderView(new PageNotFoundView());
else if (error_code === 403)
this._client._update_logged(false);
}
const router = async(uri) => {
const routes = [
{ path: "/", view: Dashboard },
{ path: "/profiles/:id/history", view: GameHistoryView },
{ path: "/profiles/:username", view: ProfilePageView },
{ path: "/tournaments/create", view: TournamentCreateView },
{ path: "/tournaments/:id", view: TournamentPageView },
{ path: "/tournaments/", view: TournamentsListView },
{ path: "/login", view: AuthenticationView },
{ path: "/register", view: AuthenticationView },
{ path: "/logout", view: LogoutView },
{ path: "/search", view: Search },
{ path: "/home", view: HomeView },
{ path: "/settings", view: SettingsView },
{ path: "/matchmaking", view: MatchMakingView },
{ path: "/games/offline", view: GameOfflineView },
{ path: "/tictactoe", view: TicTacToeView },
{ path: "/games/:id/0", view: GameView2D },
{ path: "/games/:id/1", view: GameView3D },
];
// 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), lastPageUrlBeforeLogin);
if (!(view instanceof AuthenticationView) && ! (view instanceof LogoutView))
lastPageUrlBeforeLogin = uri;
if (view instanceof AbstractRedirectView && await view.redirect())
return 1;
lastView = view;
if (await renderView(view))
return 1;
return 0;
};
window.addEventListener("popstate", function() {router(location.pathname);});
document.addEventListener("DOMContentLoaded", async () => {
document.body.addEventListener("click", e => {
if (e.target.matches("[data-link]")) {
e.preventDefault();
if (e.target.classList.contains('nav-link')) {
document.querySelector('[data-link].active')?.classList.remove('active');
e.target.classList.add('active');
}
navigateTo(e.target.href.slice(location.origin.length));
}
});
//Languages
await lang.waitLoading();
Array.from(document.getElementById('languageSelector').children).forEach(el => {
el.onclick = async _ => {
if (await lang.changeLanguage(el.value))
return;
document.querySelector('#languageSelector > .active')?.classList.remove('active');
el.classList.add('active');
};
});
document.querySelector(`#languageSelector > [value=${lang.chosenLang}]`)
?.classList.add('active');
await client.isAuthenticated();
router(location.pathname);
document.querySelector('a[href=\'' + location.pathname + '\']')?.classList.add('active');
});
export { client, lang, navigateTo, reloadView };