import { acceptHMRUpdate, defineStore } from "pinia"; import { API } from "./api"; import { Loading } from "./helpers"; import { Credentials, DoorSaved, ImageData, SiteConfigModel } from "./model"; import { Door } from "./rects/door"; declare global { interface Navigator { readonly msMaxTouchPoints: number; } } type State = { on_initialized: (() => void)[] | null; is_touch_device: boolean; is_admin: boolean; site_config: SiteConfigModel; background_image: Loading; user_doors: Door[]; next_door_target: number | null; }; export const advent22Store = defineStore({ id: "advent22", state: (): State => ({ on_initialized: [], is_touch_device: window.matchMedia("(any-hover: none)").matches || "ontouchstart" in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0, is_admin: false, site_config: { title: document.title, subtitle: "", content: "", footer: "", }, background_image: "loading", user_doors: [], next_door_target: null, }), actions: { async init(): Promise { await this.update(); if (this.on_initialized !== null) { for (const callback of this.on_initialized) callback(); } this.on_initialized = null; }, async update(): Promise { try { const favicon = await API.request("user/favicon"); const link: HTMLLinkElement = document.querySelector("link[rel*='icon']") || document.createElement("link"); link.rel = "shortcut icon"; link.type = "image/x-icon"; link.href = favicon.data_url; if (link.parentElement === null) document.getElementsByTagName("head")[0].appendChild(link); } catch {} const [is_admin, site_config, background_image, user_doors, next_door] = await Promise.all([ this.update_is_admin(), API.request("user/site_config"), API.request("user/background_image"), API.request("user/doors"), API.request("user/next_door"), ]); is_admin; // discard value document.title = site_config.title; if (site_config.subtitle !== "") document.title += " – " + site_config.subtitle; this.site_config = site_config; this.background_image = background_image; this.user_doors.length = 0; for (const door_saved of user_doors) { this.user_doors.push(Door.load(door_saved)); } if (next_door !== null) this.next_door_target = Date.now() + next_door; }, when_initialized(callback: () => void): void { if (this.on_initialized === null) { callback(); } else { this.on_initialized.push(callback); } }, async update_is_admin(): Promise { this.is_admin = await API.request("admin/is_admin"); return this.is_admin; }, login(creds: Credentials): Promise { API.creds = { username: creds[0], password: creds[1] }; return this.update_is_admin(); }, logout(): Promise { return this.login(["", ""]); }, toggle_touch_device(): void { this.is_touch_device = !this.is_touch_device; }, }, }); if (import.meta.webpackHot) { import.meta.webpackHot.accept( acceptHMRUpdate(advent22Store, import.meta.webpackHot), ); }