diff --git a/index.js b/index.js index 7e6cead..52a3411 100644 --- a/index.js +++ b/index.js @@ -6,8 +6,12 @@ import BaseView from "/ui/base_view.js"; m.route.prefix = ""; m.route(document.body, "/", { "/": { - render: function() { - return m(Layout, m(BaseView)); + render: function(vnode) { + let newSession = vnode.attrs.newSession ?? false; + let session = newSession ? null : parseInt(vnode.attrs.session); + session = isNaN(session) ? null : session; + + return m(Layout, m(BaseView, { newSession, session })); }, }, }); diff --git a/ui/base_view.js b/ui/base_view.js index 066013e..95ee6c5 100644 --- a/ui/base_view.js +++ b/ui/base_view.js @@ -9,27 +9,22 @@ export default class BaseView { #model = new BaseViewModel(); oninit() { - let id = m.route.param("session"); - id = parseInt(id); - if (Number.isNaN(id)) - id = null; - - this.#model.current = id; this.#model.loadAllSessions(); } - view() { + view(vnode) { + if (vnode.attrs.newSession) + this.#model.newSession(); + else + this.#model.current = vnode.attrs.session; + if (this.#model.current !== null) - return m(SessionView, { - model: this.#model.current, - onDeselect: () => this.#model.current = null, - }); + return m(SessionView, { model: this.#model.current }); if (this.#model.sessions !== null) return m(SessionList, { models: this.#model.sessions, onSelect: (session) => this.#model.current = session, - onNew: () => this.#model.newSession(), }); return m("p", "Wart kurz, i lad grad die Spiele…"); @@ -48,30 +43,32 @@ class BaseViewModel { 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; }) + .catch((e) => { + console.error("failed to load session: ", e); + }) .finally(() => { + m.redraw(); if (this.#currentLoading === value) this.#currentLoading = null; - m.redraw(); }); } else if (value === null) { + if (this.#current === null) + return; this.#current = null; this.#currentLoading = null; this.loadAllSessions(); - m.route.set("/"); } else { throw new TypeError("current session must be session or id or null"); @@ -96,13 +93,22 @@ class BaseViewModel { .then(() => { if (this.#currentLoading === BaseViewModel.#newSessionMarker) { this.#current = session; - m.route.set("/", { session: session.id }); + m.route.set("/", { session: session.id }, { replace: true }); } }) + .catch((e) => { + console.error("failed to create new session: ", e); + if (this.#currentLoading === BaseViewModel.#newSessionMarker) + m.route.set( + "/", + { session: this.#current?.id ?? undefined }, + { replace: true }); + else + m.redraw(); + }) .finally(() => { if (this.#currentLoading === BaseViewModel.#newSessionMarker) this.#currentLoading = null; - m.redraw(); }); } diff --git a/ui/session.js b/ui/session.js index ddeb9df..d7c1076 100644 --- a/ui/session.js +++ b/ui/session.js @@ -6,12 +6,12 @@ import RoundView from "/ui/round.js"; export default class SessionView { /** @param {{ attrs: { model: Session } }} param The session model to use. */ - view({ attrs: { model, onDeselect } }) { + view({ attrs: { model } }) { let res = model.result; return m("article.session-view", [ - m("button", { onclick: () => onDeselect() }, "Zruck"), + m(m.route.Link, { href: "/", selector: "button" }, "Zruck"), m("table", [ m("thead", [ m("tr", [ diff --git a/ui/session_list.js b/ui/session_list.js index d3f35a3..6736107 100644 --- a/ui/session_list.js +++ b/ui/session_list.js @@ -4,17 +4,32 @@ import Session from "/models/session.js"; export default class SessionList { /** @param {{ attrs: { models: Session[] } }} param The sessions to show. */ - view({attrs: { models, onSelect, onNew } }) { + view({attrs: { models, onSelect } }) { return m("section", [ - m("button", { onclick: () => onNew() }, "Neie Session"), + m(m.route.Link, { + href: "/", + selector: "button", + options: { + state: { newSession: true }, + }, + }, "Neie Session"), m("ol", [ models.map((s) => m("li", [ - 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)), - m("p", "•".repeat(s.result.theirPoints)), - ]) + m( + m.route.Link, + { + href: "/", + selector: "button", + params: { session: s.id }, + 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)), + m("p", "•".repeat(s.result.theirPoints)), + ], + ), ])) ]) ]);