WIP: major refactoring
This commit is contained in:
parent
55081b24d8
commit
15b957791f
7 changed files with 79 additions and 99 deletions
|
@ -2,33 +2,34 @@ module.exports = {
|
|||
root: true,
|
||||
|
||||
env: {
|
||||
node: true
|
||||
node: true,
|
||||
},
|
||||
|
||||
'extends': [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/typescript/recommended'
|
||||
extends: [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended",
|
||||
"@vue/typescript/recommended",
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||
"no-empty": "off",
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
},
|
||||
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'**/__tests__/*.{j,t}s?(x)',
|
||||
'**/tests/unit/**/*.spec.{j,t}s?(x)'
|
||||
"**/__tests__/*.{j,t}s?(x)",
|
||||
"**/tests/unit/**/*.spec.{j,t}s?(x)",
|
||||
],
|
||||
env: {
|
||||
mocha: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
mocha: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<figure>
|
||||
<div class="image is-unselectable">
|
||||
<img :src="store.calendar_background_image" />
|
||||
<img :src="store.background_image" />
|
||||
<ThouCanvas>
|
||||
<CalendarDoor
|
||||
v-for="(door, index) in doors"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
<figure class="image is-unselectable">
|
||||
<img :src="store.calendar_background_image" />
|
||||
<img :src="store.background_image" />
|
||||
<ThouCanvas>
|
||||
<PreviewDoor
|
||||
v-for="(door, index) in doors"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
<figure class="image is-unselectable">
|
||||
<img :src="store.calendar_background_image" />
|
||||
<img :src="store.background_image" />
|
||||
<DoorCanvas :doors="doors" />
|
||||
</figure>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { APIError } from "./api_error";
|
||||
|
||||
export function objForEach<T>(
|
||||
obj: T,
|
||||
f: (k: keyof T, v: T[keyof T]) => void,
|
||||
|
@ -8,3 +10,20 @@ export function objForEach<T>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type Loading<T> = T | "loading" | "error";
|
||||
|
||||
export function loading_success<T>(o: Loading<T>): o is T {
|
||||
if (o === "loading") return false;
|
||||
if (o === "error") return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function handle_error(error: unknown) {
|
||||
if (error instanceof APIError) {
|
||||
error.alert();
|
||||
} else {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@ export interface DoorSaved {
|
|||
export interface ImageData {
|
||||
height: number;
|
||||
width: number;
|
||||
aspect_ratio: number;
|
||||
data_url: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { acceptHMRUpdate, defineStore } from "pinia";
|
||||
import { API } from "./api";
|
||||
import { Credentials, DoorSaved, SiteConfigModel } from "./model";
|
||||
import { Loading, loading_success } from "./helpers";
|
||||
import { Credentials, DoorSaved, ImageData, SiteConfigModel } from "./model";
|
||||
import { Door } from "./rects/door";
|
||||
|
||||
declare global {
|
||||
|
@ -13,9 +14,8 @@ type State = {
|
|||
on_initialized: (() => void)[];
|
||||
is_touch_device: boolean;
|
||||
is_admin: boolean;
|
||||
site_config: SiteConfigModel;
|
||||
calendar_background_image: string | undefined;
|
||||
calendar_aspect_ratio: number;
|
||||
site_config: Loading<SiteConfigModel>;
|
||||
background_image: Loading<ImageData>;
|
||||
user_doors: Door[];
|
||||
next_door_target: number | null;
|
||||
};
|
||||
|
@ -31,14 +31,8 @@ export const advent22Store = defineStore({
|
|||
navigator.maxTouchPoints > 0 ||
|
||||
navigator.msMaxTouchPoints > 0,
|
||||
is_admin: false,
|
||||
site_config: {
|
||||
title: document.title,
|
||||
subtitle: "",
|
||||
content: "",
|
||||
footer: "",
|
||||
},
|
||||
calendar_background_image: undefined,
|
||||
calendar_aspect_ratio: 1,
|
||||
site_config: "loading",
|
||||
background_image: "loading",
|
||||
user_doors: [],
|
||||
next_door_target: null,
|
||||
}),
|
||||
|
@ -48,39 +42,29 @@ export const advent22Store = defineStore({
|
|||
this.update().then(() => this.on_initialized.forEach((fn) => fn()));
|
||||
},
|
||||
|
||||
update(): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
API.request("user/favicon");
|
||||
this.advent22
|
||||
.api_get_blob("user/favicon")
|
||||
.then((favicon_src) => {
|
||||
async update(): Promise<void> {
|
||||
try {
|
||||
const favicon = await API.request<ImageData>("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_src;
|
||||
link.href = favicon.data_url;
|
||||
|
||||
if (link.parentElement === null)
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
})
|
||||
.catch(() => {});
|
||||
} catch {}
|
||||
|
||||
Promise.all([
|
||||
const [is_admin, site_config, background_image, user_doors, next_door] =
|
||||
await Promise.all([
|
||||
this.update_is_admin(),
|
||||
this.advent22.api_get<SiteConfigModel>("user/site_config"),
|
||||
this.advent22.api_get_blob("user/background_image"),
|
||||
this.advent22.api_get<DoorSaved[]>("user/doors"),
|
||||
this.advent22.api_get<number | null>("user/next_door"),
|
||||
])
|
||||
.then(
|
||||
([
|
||||
is_admin,
|
||||
site_config,
|
||||
background_image,
|
||||
user_doors,
|
||||
next_door,
|
||||
]) => {
|
||||
API.request<SiteConfigModel>("user/site_config"),
|
||||
API.request<ImageData>("user/background_image"),
|
||||
API.request<DoorSaved[]>("user/doors"),
|
||||
API.request<number | null>("user/next_door"),
|
||||
]);
|
||||
is_admin; // discard value
|
||||
|
||||
document.title = site_config.title;
|
||||
|
@ -89,42 +73,27 @@ export const advent22Store = defineStore({
|
|||
document.title += " – " + site_config.subtitle;
|
||||
|
||||
this.site_config = site_config;
|
||||
|
||||
this.calendar_background_image = background_image;
|
||||
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;
|
||||
|
||||
resolve();
|
||||
},
|
||||
)
|
||||
.catch(reject);
|
||||
});
|
||||
if (next_door !== null) this.next_door_target = Date.now() + next_door;
|
||||
},
|
||||
|
||||
when_initialized(callback: () => void): void {
|
||||
if (this.is_initialized) {
|
||||
if (loading_success(this.site_config)) {
|
||||
callback();
|
||||
} else {
|
||||
this.on_initialized.push(callback);
|
||||
}
|
||||
},
|
||||
|
||||
update_is_admin(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.advent22
|
||||
.api_get<boolean>("admin/is_admin")
|
||||
.then((is_admin) => {
|
||||
this.is_admin = is_admin;
|
||||
resolve(is_admin);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
async update_is_admin(): Promise<boolean> {
|
||||
this.is_admin = await API.request<boolean>("admin/is_admin");
|
||||
return this.is_admin;
|
||||
},
|
||||
|
||||
login(creds: Credentials): Promise<boolean> {
|
||||
|
@ -139,14 +108,6 @@ export const advent22Store = defineStore({
|
|||
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;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue