From 4e9d35178a9eadbbcd96af6830b6508b97e3d468 Mon Sep 17 00:00:00 2001 From: Adrian Wannenmacher Date: Fri, 27 Feb 2026 00:08:18 +0100 Subject: [PATCH] make opening sessions by query param possible Specific sessions can now be opened by setting a query param to their id. This is needed to allow users to reload the page without being kicked out to the session selection. --- ui/base_view.js | 131 +++++++++++++++++++++++++++++++++++++-------- ui/session_list.js | 2 +- 2 files changed, 109 insertions(+), 24 deletions(-) diff --git a/ui/base_view.js b/ui/base_view.js index 9554462..df5d8f5 100644 --- a/ui/base_view.js +++ b/ui/base_view.js @@ -6,39 +6,124 @@ import SessionList from "/ui/session_list.js"; import SessionView from "/ui/session.js"; export default class BaseView { - /** @type(?Session[]) */ - #sessions = null; - /** @type(?Session) */ - #currentSession = null; + #model = new BaseViewModel(); - constructor() { - SessionRepo.getAll().then(ls => { - this.#sessions = ls; - m.redraw(); - }); + oninit() { + let id = m.route.param("session"); + id = parseInt(id); + if (Number.isNaN(id)) + id = null; + + this.#model.current = id; + this.#model.loadAllSessions(); } view() { - if (this.#currentSession !== null) + if (this.#model.current !== null) return m(SessionView, { - model: this.#currentSession, - onDeselect: () => this.#currentSession = null, + model: this.#model.current, + onDeselect: () => this.#model.current = null, }); - if (this.#sessions !== null) + if (this.#model.sessions !== null) return m(SessionList, { - models: this.#sessions, - onSelect: async (key) => { - this.#currentSession = await SessionRepo.get(key) ?? null; - }, - onNew: async () => { - let session = new Session(); - await SessionRepo.put(session); - this.#currentSession = session; - this.#sessions.splice(0, 0, session); - } + models: this.#model.sessions, + onSelect: (session) => this.#model.current = session, + onNew: () => this.#model.newSession(), }); return m("p", "Wart kurz, i lad grad die Spiele…"); } } + +class BaseViewModel { + #current = null; + #currentLoading = null; + + get current() { + return this.#current; + } + + set current(value) { + if (value instanceof Session) { + this.#current = value; + this.#currentLoading = null; + m.route.set("/", { session: value.id }); + + } else if (typeof value === "number") { + if (value === this.#current?.id || value === this.#currentLoading) + return; + this.#currentLoading = value; + m.route.set("/", { session: value }); + SessionRepo + .get(value) + .then((s) => { + if (this.#currentLoading === s?.id) + this.#current = s; + }) + .finally(() => { + if (this.#currentLoading === value) + this.#currentLoading = null; + m.redraw(); + }); + + } else if (value === null) { + this.#current = null; + this.#currentLoading = null; + this.loadAllSessions(); + m.route.set("/"); + + } else { + throw new TypeError("current session must be session or id or null"); + } + } + + get currentLoading() { + return this.#currentLoading !== null; + } + + static #newSessionMarker = Symbol("new session loading"); + + newSession() { + if (this.#currentLoading === BaseViewModel.#newSessionMarker) + return; + + this.#currentLoading = BaseViewModel.#newSessionMarker; + + let session = new Session(); + SessionRepo + .put(session) + .then(() => { + if (this.#currentLoading === BaseViewModel.#newSessionMarker) { + this.#current = session; + m.route.set("/", { session: session.id }); + } + }) + .finally(() => { + if (this.#currentLoading === BaseViewModel.#newSessionMarker) + this.#currentLoading = null; + m.redraw(); + }); + } + + #sessions = null; + #sessionsLoading = false; + + get sessions() { + return this.#sessions; + } + + loadAllSessions() { + if (this.#sessionsLoading) + return; + + this.#sessionsLoading = true; + SessionRepo + .getAll() + .then(s => this.#sessions = s) + .finally(() => { + this.#sessionsLoading = false; + m.redraw(); + }); + } +} diff --git a/ui/session_list.js b/ui/session_list.js index e3f4ba3..d3f35a3 100644 --- a/ui/session_list.js +++ b/ui/session_list.js @@ -9,7 +9,7 @@ export default class SessionList { m("button", { onclick: () => onNew() }, "Neie Session"), m("ol", [ models.map((s) => m("li", [ - m("button", { onclick: () => onSelect(s.id) }, [ + m("button", { onclick: () => onSelect(s) }, [ m("p", s.ourTeam !== "" ? s.ourTeam : "Unbnannts Team"), m("p", s.theirTeam !== "" ? s.theirTeam : "Unbnannts Team"), m("p", "•".repeat(s.result.ourPoints)),