117 lines
3.2 KiB
TypeScript
117 lines
3.2 KiB
TypeScript
import { Credentials, DoorsSaved, SiteConfigModel } from "@/lib/api";
|
||
import { Advent22 } from "@/plugins/advent22";
|
||
import { AxiosBasicCredentials } from "axios";
|
||
import { acceptHMRUpdate, defineStore } from "pinia";
|
||
|
||
declare global {
|
||
interface Navigator {
|
||
readonly msMaxTouchPoints: number;
|
||
}
|
||
}
|
||
|
||
export const advent22Store = defineStore({
|
||
id: "advent22",
|
||
|
||
state: () => ({
|
||
advent22: {} as Advent22,
|
||
api_creds: ["", ""] as Credentials,
|
||
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: "",
|
||
} as SiteConfigModel,
|
||
calendar_aspect_ratio: 1,
|
||
user_doors: [] as DoorsSaved,
|
||
next_door_target: null as number | null,
|
||
}),
|
||
|
||
getters: {
|
||
axios_creds: (state): AxiosBasicCredentials => {
|
||
const [username, password] = state.api_creds;
|
||
return { username: username, password: password };
|
||
},
|
||
},
|
||
|
||
actions: {
|
||
init(advent22: Advent22): void {
|
||
this.advent22 = advent22;
|
||
|
||
advent22
|
||
.api_get_blob("user/favicon")
|
||
.then((favicon_src) => {
|
||
const link: HTMLLinkElement =
|
||
document.querySelector("link[rel*='icon']") ||
|
||
document.createElement("link");
|
||
link.rel = "shortcut icon";
|
||
link.type = "image/x-icon";
|
||
link.href = favicon_src;
|
||
|
||
if (link.parentElement === null)
|
||
document.getElementsByTagName("head")[0].appendChild(link);
|
||
})
|
||
.catch(() => {});
|
||
|
||
Promise.all([
|
||
advent22.api_get<SiteConfigModel>("user/site_config"),
|
||
advent22.api_get<DoorsSaved>("user/doors"),
|
||
advent22.api_get<number | null>("user/next_door"),
|
||
])
|
||
.then(([site_config, user_doors, next_door]) => {
|
||
document.title = site_config.title;
|
||
|
||
if (site_config.subtitle !== "")
|
||
document.title += " – " + site_config.subtitle;
|
||
|
||
this.site_config = site_config;
|
||
this.user_doors = user_doors;
|
||
|
||
if (next_door !== null)
|
||
this.next_door_target = Date.now() + next_door;
|
||
})
|
||
.catch(advent22.alert_user_error);
|
||
},
|
||
|
||
login(creds: Credentials): Promise<boolean> {
|
||
this.api_creds = creds;
|
||
|
||
return new Promise<boolean>((resolve, reject) => {
|
||
this.advent22
|
||
.api_get<boolean>("admin/is_admin")
|
||
.then((is_admin) => {
|
||
this.is_admin = is_admin;
|
||
resolve(is_admin);
|
||
})
|
||
.catch(reject);
|
||
});
|
||
},
|
||
|
||
logout(): Promise<boolean> {
|
||
return this.login(["", ""]);
|
||
},
|
||
|
||
toggle_touch_device(): void {
|
||
this.is_touch_device = !this.is_touch_device;
|
||
},
|
||
|
||
set_calendar_aspect_ratio(rect: DOMRectReadOnly): void {
|
||
const result = rect.width / rect.height;
|
||
|
||
// filter suspicious results
|
||
if (result !== 0 && isFinite(result) && !isNaN(result))
|
||
this.calendar_aspect_ratio = result;
|
||
},
|
||
},
|
||
});
|
||
|
||
if (import.meta.webpackHot) {
|
||
import.meta.webpackHot.accept(
|
||
acceptHMRUpdate(advent22Store, import.meta.webpackHot),
|
||
);
|
||
}
|