170 lines
4.3 KiB
JavaScript
170 lines
4.3 KiB
JavaScript
"use strict";
|
|
|
|
import Session from "/models/session.js";
|
|
import SessionRepo from "/data/session_repo.js";
|
|
import SessionList from "/ui/session_list.js";
|
|
import SessionView from "/ui/session.js";
|
|
|
|
export default class BaseView {
|
|
#model = new BaseViewModel();
|
|
|
|
oninit() {
|
|
this.#model.loadAllSessions();
|
|
}
|
|
|
|
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 });
|
|
|
|
if (this.#model.sessions !== null)
|
|
return m(SessionList, {
|
|
models: this.#model.sessions,
|
|
onSelect: (session) => this.#model.current = session,
|
|
onDelete: (id, index) => this.#model.deleteSession(id, index),
|
|
});
|
|
|
|
return m("p", "Wart kurz, i lad grad die Spiele…");
|
|
}
|
|
}
|
|
|
|
class BaseViewModel {
|
|
#current = null;
|
|
#currentLoading = null;
|
|
|
|
get 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) {
|
|
if (value instanceof Session) {
|
|
this.#setCurrent(value);
|
|
this.#currentLoading = null;
|
|
|
|
} else if (typeof value === "number") {
|
|
if (value === this.#current?.id || value === this.#currentLoading)
|
|
return;
|
|
this.#currentLoading = value;
|
|
SessionRepo
|
|
.get(value)
|
|
.then((s) => {
|
|
if (this.#currentLoading === s?.id)
|
|
this.#setCurrent(s);
|
|
})
|
|
.catch((e) => {
|
|
console.error("failed to load session: ", e);
|
|
})
|
|
.finally(() => {
|
|
m.redraw();
|
|
if (this.#currentLoading === value)
|
|
this.#currentLoading = null;
|
|
});
|
|
|
|
} else if (value === null) {
|
|
if (this.#current === null)
|
|
return;
|
|
this.#setCurrent(null);
|
|
this.#currentLoading = null;
|
|
|
|
} 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.#setCurrent(session);
|
|
this.#sessions.splice(0, 0, session);
|
|
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;
|
|
});
|
|
}
|
|
|
|
#sessions = null;
|
|
#sessionsLoading = false;
|
|
|
|
get sessions() {
|
|
return this.#sessions;
|
|
}
|
|
|
|
loadAllSessions() {
|
|
if (this.#sessionsLoading)
|
|
return;
|
|
|
|
this.#sessionsLoading = true;
|
|
SessionRepo
|
|
.getAllFromNewest()
|
|
.then(s => this.#sessions = s)
|
|
.finally(() => {
|
|
this.#sessionsLoading = false;
|
|
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();
|
|
};
|
|
|
|
deleteSession(id, index) {
|
|
SessionRepo.delete(id);
|
|
if (this.#sessions[index] === undefined || this.#sessions[index].id !== id)
|
|
return;
|
|
this.#sessions.splice(index, 1);
|
|
}
|
|
}
|