From 8a1140688efc66266e545fd062c2d1ee898e7b5c Mon Sep 17 00:00:00 2001 From: Adrian Wannenmacher Date: Sun, 1 Mar 2026 03:14:00 +0100 Subject: [PATCH] improve in-memory change handling The base view now does a better job at keeping the sessions list up to date with the current session, without having to reload it all the time. The purpose of this is to be able to show the list and the current session at the same time, and keep them in sync without polling the database. --- ui/base_view.js | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/ui/base_view.js b/ui/base_view.js index 95ee6c5..989a599 100644 --- a/ui/base_view.js +++ b/ui/base_view.js @@ -39,9 +39,18 @@ class BaseViewModel { return this.#current; } + #setCurrent(value) { + if (this.#current !== null) + this.#current.removeEventListener( + Session.EVENT_CHANGE, this.#handleCurrentUpdate); + if (value !== null) + value.addEventListener(Session.EVENT_CHANGE, this.#handleCurrentUpdate); + this.#current = value; + } + set current(value) { if (value instanceof Session) { - this.#current = value; + this.#setCurrent(value); this.#currentLoading = null; } else if (typeof value === "number") { @@ -52,7 +61,7 @@ class BaseViewModel { .get(value) .then((s) => { if (this.#currentLoading === s?.id) - this.#current = s; + this.#setCurrent(s); }) .catch((e) => { console.error("failed to load session: ", e); @@ -66,9 +75,8 @@ class BaseViewModel { } else if (value === null) { if (this.#current === null) return; - this.#current = null; + this.#setCurrent(null); this.#currentLoading = null; - this.loadAllSessions(); } else { throw new TypeError("current session must be session or id or null"); @@ -92,7 +100,8 @@ class BaseViewModel { .put(session) .then(() => { if (this.#currentLoading === BaseViewModel.#newSessionMarker) { - this.#current = session; + this.#setCurrent(session); + this.#sessions.splice(0, 0, session); m.route.set("/", { session: session.id }, { replace: true }); } }) @@ -132,4 +141,22 @@ class BaseViewModel { m.redraw(); }); } + + #handleCurrentUpdate = (e) => { + if (this.#current !== e.target || this.#current === this.#sessions[0]) { + e.target.removeEventListener( + Session.EVENT_CHANGE, this.#handleCurrentUpdate); + return; + } + + if (this.#current?.id === this.#sessions[0]?.id) { + e.target.removeEventListener( + Session.EVENT_CHANGE, this.#handleCurrentUpdate); + this.#sessions[0] = this.#current; + return; + } + + this.loadAllSessions(); + }; + }