dockered
This commit is contained in:
162
django/frontend/static/js/index.js
Normal file
162
django/frontend/static/js/index.js
Normal file
@ -0,0 +1,162 @@
|
||||
import { Client } from "./api/Client.js";
|
||||
|
||||
import Search from "./views/Search.js";
|
||||
import HomeView from "./views/HomeView.js";
|
||||
import LogoutView from "./views/accounts/LogoutView.js";
|
||||
|
||||
import PongOnlineView from "./views/PongOnlineView.js"
|
||||
import { PongOfflineView } from "./views/PongOfflineView.js"
|
||||
|
||||
import { TicTacToeOnlineView } from "./views/TicTacToeOnlineView.js"
|
||||
import { TicTacToeOfflineView } from "./views/TicTacToeOfflineView.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 AuthenticationView from "./views/accounts/AuthenticationView.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: HomeView},
|
||||
{ path: "/profiles/:username", view: ProfilePageView },
|
||||
{ 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/pong/offline", view: PongOfflineView },
|
||||
{ path: "/games/pong/:id", view: PongOnlineView },
|
||||
{ path: "/games/tictactoe/offline", view: TicTacToeOfflineView },
|
||||
{ path: "/games/tictactoe/:id", view: TicTacToeOnlineView },
|
||||
];
|
||||
|
||||
// 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();
|
||||
document.querySelector('[data-link].nav-link.active')?.classList.remove('active');
|
||||
if (e.target.classList.contains('nav-link'))
|
||||
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, lastView, navigateTo, reloadView };
|
Reference in New Issue
Block a user