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),
 | ||
|   );
 | ||
| }
 |