1
0

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.
This commit is contained in:
Adrian Wannenmacher 2026-03-01 03:14:00 +01:00
parent de0fc8c917
commit 8a1140688e
Signed by: tfld
GPG Key ID: 19D986ECB1E492D5

View File

@ -39,9 +39,18 @@ class BaseViewModel {
return this.#current; 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) { set current(value) {
if (value instanceof Session) { if (value instanceof Session) {
this.#current = value; this.#setCurrent(value);
this.#currentLoading = null; this.#currentLoading = null;
} else if (typeof value === "number") { } else if (typeof value === "number") {
@ -52,7 +61,7 @@ class BaseViewModel {
.get(value) .get(value)
.then((s) => { .then((s) => {
if (this.#currentLoading === s?.id) if (this.#currentLoading === s?.id)
this.#current = s; this.#setCurrent(s);
}) })
.catch((e) => { .catch((e) => {
console.error("failed to load session: ", e); console.error("failed to load session: ", e);
@ -66,9 +75,8 @@ class BaseViewModel {
} else if (value === null) { } else if (value === null) {
if (this.#current === null) if (this.#current === null)
return; return;
this.#current = null; this.#setCurrent(null);
this.#currentLoading = null; this.#currentLoading = null;
this.loadAllSessions();
} else { } else {
throw new TypeError("current session must be session or id or null"); throw new TypeError("current session must be session or id or null");
@ -92,7 +100,8 @@ class BaseViewModel {
.put(session) .put(session)
.then(() => { .then(() => {
if (this.#currentLoading === BaseViewModel.#newSessionMarker) { 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 }); m.route.set("/", { session: session.id }, { replace: true });
} }
}) })
@ -132,4 +141,22 @@ class BaseViewModel {
m.redraw(); 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();
};
} }