From c9ac0c75d9273d3df86e66f2dad830146b7b1008 Mon Sep 17 00:00:00 2001 From: Zero~Informatique Date: Thu, 1 Jul 2021 20:19:47 +0200 Subject: viewer: Upgraded dependencies for Vue 2 Removed obsolete deps core-js ; resize-observer-polyfill --- viewer/src/store/galleryStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'viewer/src/store') diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts index 5d599aa..6d64e12 100644 --- a/viewer/src/store/galleryStore.ts +++ b/viewer/src/store/galleryStore.ts @@ -126,7 +126,7 @@ export default class GalleryStore extends VuexModule { } private static getUrlConfig() { - let search = window.location.search; + const search = window.location.search; if (search.length > 1) return search.substr(1) + ".json"; return "config.json"; } -- cgit v1.2.3 From 9165cc1efcf7791f78b61b2c51a9de651b1b09aa Mon Sep 17 00:00:00 2001 From: Zero~Informatique Date: Fri, 2 Jul 2021 22:53:16 +0200 Subject: viewer: types normalization - gallery.d.ts GitHub: closes #301 --- viewer/src/store/galleryStore.ts | 15 ++++++++------- viewer/src/store/index.ts | 7 +++---- viewer/src/store/uiStore.ts | 5 +++-- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'viewer/src/store') diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts index 6d64e12..3ef2036 100644 --- a/viewer/src/store/galleryStore.ts +++ b/viewer/src/store/galleryStore.ts @@ -17,9 +17,10 @@ -- along with this program. If not, see . */ -import { createModule, mutation, action } from "vuex-class-component"; +import { Config, Index, Item } from "@/@types/gallery"; import IndexFactory from "@/services/indexfactory"; import Navigation from "@/services/navigation"; +import { action, createModule, mutation } from "vuex-class-component"; const VuexModule = createModule({ namespaced: "galleryStore", @@ -27,8 +28,8 @@ const VuexModule = createModule({ }); export default class GalleryStore extends VuexModule { - config: Gallery.Config | null = null; - galleryIndex: Gallery.Index | null = null; + config: Config | null = null; + galleryIndex: Index | null = null; tagsIndex: Tag.Index = {}; tagsCategories: Tag.Category[] = []; currentPath: string | null = null; @@ -36,11 +37,11 @@ export default class GalleryStore extends VuexModule { // --- - @mutation private setConfig(config: Gallery.Config) { + @mutation private setConfig(config: Config) { this.config = config; } - @mutation setGalleryIndex(galleryIndex: Gallery.Index) { + @mutation setGalleryIndex(galleryIndex: Index) { this.galleryIndex = Object.freeze(galleryIndex); } @@ -62,13 +63,13 @@ export default class GalleryStore extends VuexModule { // --- - get currentItemPath(): Gallery.Item[] { + get currentItemPath(): Item[] { const root = this.galleryIndex?.tree; if (root && this.currentPath) return Navigation.searchCurrentItemPath(root, this.currentPath); return []; } - get currentItem(): Gallery.Item | null { + get currentItem(): Item | null { const path = this.currentItemPath; return path.length > 0 ? path[path.length - 1] : null; } diff --git a/viewer/src/store/index.ts b/viewer/src/store/index.ts index f86d66b..1f49589 100644 --- a/viewer/src/store/index.ts +++ b/viewer/src/store/index.ts @@ -17,12 +17,11 @@ -- along with this program. If not, see . */ +import GalleryStore from "@/store/galleryStore"; +import UIStore from "@/store/uiStore"; import Vue from "vue"; import Vuex from "vuex"; -import { extractVuexModule } from "vuex-class-component"; -import { createProxy } from "vuex-class-component"; -import UIStore from "@/store/uiStore"; -import GalleryStore from "@/store/galleryStore"; +import { createProxy, extractVuexModule } from "vuex-class-component"; Vue.use(Vuex); diff --git a/viewer/src/store/uiStore.ts b/viewer/src/store/uiStore.ts index f065cdd..f5bb898 100644 --- a/viewer/src/store/uiStore.ts +++ b/viewer/src/store/uiStore.ts @@ -17,8 +17,9 @@ -- along with this program. If not, see . */ -import { createModule, mutation, action } from "vuex-class-component"; +import { Config } from "@/@types/gallery"; import ItemComparators, { ItemSort } from "@/services/itemComparators"; +import { action, createModule, mutation } from "vuex-class-component"; const VuexModule = createModule({ namespaced: "uiStore", @@ -49,7 +50,7 @@ export default class UIStore extends VuexModule { this.sort = sort; } - @action async initFromConfig(config: Gallery.Config) { + @action async initFromConfig(config: Config) { if (config.initialItemSort) { const itemSort = ItemComparators.ITEM_SORTS[config.initialItemSort]; if (itemSort) this.setSort(itemSort); -- cgit v1.2.3 From 92cb34b719b481faf417760f307241e8f6d777a9 Mon Sep 17 00:00:00 2001 From: Zero~Informatique Date: Fri, 2 Jul 2021 22:59:56 +0200 Subject: viewer: types normalization - tag.d.ts GitHub: closes #301 --- viewer/src/store/galleryStore.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'viewer/src/store') diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts index 3ef2036..e2adf18 100644 --- a/viewer/src/store/galleryStore.ts +++ b/viewer/src/store/galleryStore.ts @@ -18,6 +18,7 @@ */ import { Config, Index, Item } from "@/@types/gallery"; +import { TagCategory, TagIndex, TagSearch } from "@/@types/tag"; import IndexFactory from "@/services/indexfactory"; import Navigation from "@/services/navigation"; import { action, createModule, mutation } from "vuex-class-component"; @@ -30,10 +31,10 @@ const VuexModule = createModule({ export default class GalleryStore extends VuexModule { config: Config | null = null; galleryIndex: Index | null = null; - tagsIndex: Tag.Index = {}; - tagsCategories: Tag.Category[] = []; + tagsIndex: TagIndex = {}; + tagsCategories: TagCategory[] = []; currentPath: string | null = null; - currentSearch: Tag.Search[] = []; + currentSearch: TagSearch[] = []; // --- @@ -45,11 +46,11 @@ export default class GalleryStore extends VuexModule { this.galleryIndex = Object.freeze(galleryIndex); } - @mutation private setTagsIndex(tagsIndex: Tag.Index) { + @mutation private setTagsIndex(tagsIndex: TagIndex) { this.tagsIndex = Object.freeze(tagsIndex); } - @mutation private setTagsCategories(tagsCategories: Tag.Category[]) { + @mutation private setTagsCategories(tagsCategories: TagCategory[]) { this.tagsCategories = tagsCategories; } @@ -57,7 +58,7 @@ export default class GalleryStore extends VuexModule { this.currentPath = currentPath; } - @mutation setCurrentSearch(currentSearch: Tag.Search[]) { + @mutation setCurrentSearch(currentSearch: TagSearch[]) { this.currentSearch = currentSearch; } -- cgit v1.2.3 From 928c501dda0c3580e3cb0389efc16fc1dde16b68 Mon Sep 17 00:00:00 2001 From: Zero~Informatique Date: Sat, 3 Jul 2021 05:06:44 +0200 Subject: viewer: optional user-defined markdown splash screen GitHub: closes #284 --- viewer/src/store/uiStore.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'viewer/src/store') diff --git a/viewer/src/store/uiStore.ts b/viewer/src/store/uiStore.ts index f5bb898..2c45136 100644 --- a/viewer/src/store/uiStore.ts +++ b/viewer/src/store/uiStore.ts @@ -18,6 +18,7 @@ */ import { Config } from "@/@types/gallery"; +import { SplashScreenConfig } from "@/@types/splashscreen"; import ItemComparators, { ItemSort } from "@/services/itemComparators"; import { action, createModule, mutation } from "vuex-class-component"; @@ -26,12 +27,17 @@ const VuexModule = createModule({ strict: true, }); +const STORAGE_SPLASHSCREEN_VALIDATION = "splashScreenValidation"; + export default class UIStore extends VuexModule { fullscreen: boolean = false; fullWidth: boolean = window.innerWidth < Number(process.env.VUE_APP_FULLWIDTH_LIMIT); searchMode: boolean = false; sort: ItemSort = ItemComparators.DEFAULT; + splashScreenConfig: SplashScreenConfig | null = null; + splashScreenEnabled: boolean = false; + // --- @mutation toggleFullscreen(value?: boolean) { @@ -50,11 +56,34 @@ export default class UIStore extends VuexModule { this.sort = sort; } + @mutation setSplashScreenConfig(splashScreenConfig: SplashScreenConfig) { + this.splashScreenConfig = splashScreenConfig; + } + + @mutation setSplashScreenEnabled(enabled: boolean) { + this.splashScreenEnabled = enabled; + } + + // --- + @action async initFromConfig(config: Config) { if (config.initialItemSort) { const itemSort = ItemComparators.ITEM_SORTS[config.initialItemSort]; if (itemSort) this.setSort(itemSort); else throw new Error("Unknown sort type: " + config.initialItemSort); } + if (config.splashScreen) { + this.setSplashScreenConfig(config.splashScreen); + const uid = config.splashScreen.dontshowagainUID; + this.setSplashScreenEnabled(!uid || localStorage.getItem(STORAGE_SPLASHSCREEN_VALIDATION) !== uid); + } + } + + // --- + + @action async validateSpashScreen() { + this.setSplashScreenEnabled(false); + const uid = this.splashScreenConfig?.dontshowagainUID; + if (uid) localStorage.setItem(STORAGE_SPLASHSCREEN_VALIDATION, String(uid)); } } -- cgit v1.2.3 From c83f44cd69a227f873a026c01653ef434b6ae045 Mon Sep 17 00:00:00 2001 From: Zero~Informatique Date: Mon, 5 Jul 2021 19:10:20 +0200 Subject: viewer: viewer: optional user-defined markdown splash screen Code review changes --- viewer/src/store/uiStore.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'viewer/src/store') diff --git a/viewer/src/store/uiStore.ts b/viewer/src/store/uiStore.ts index 2c45136..520fcf4 100644 --- a/viewer/src/store/uiStore.ts +++ b/viewer/src/store/uiStore.ts @@ -27,7 +27,7 @@ const VuexModule = createModule({ strict: true, }); -const STORAGE_SPLASHSCREEN_VALIDATION = "splashScreenValidation"; +const STORAGE_SPLASHSCREEN_ACKNOWLEDGMENT = "splashScreenAcknowledgment"; export default class UIStore extends VuexModule { fullscreen: boolean = false; @@ -74,8 +74,8 @@ export default class UIStore extends VuexModule { } if (config.splashScreen) { this.setSplashScreenConfig(config.splashScreen); - const uid = config.splashScreen.dontshowagainUID; - this.setSplashScreenEnabled(!uid || localStorage.getItem(STORAGE_SPLASHSCREEN_VALIDATION) !== uid); + const uid = config.splashScreen.acknowledgmentKey; + this.setSplashScreenEnabled(!uid || localStorage.getItem(STORAGE_SPLASHSCREEN_ACKNOWLEDGMENT) !== uid); } } @@ -83,7 +83,7 @@ export default class UIStore extends VuexModule { @action async validateSpashScreen() { this.setSplashScreenEnabled(false); - const uid = this.splashScreenConfig?.dontshowagainUID; - if (uid) localStorage.setItem(STORAGE_SPLASHSCREEN_VALIDATION, String(uid)); + const uid = this.splashScreenConfig?.acknowledgmentKey; + if (uid) localStorage.setItem(STORAGE_SPLASHSCREEN_ACKNOWLEDGMENT, String(uid)); } } -- cgit v1.2.3 From 00510820a2794efcadbc83f7f8b54318fe198ecb Mon Sep 17 00:00:00 2001 From: Zéro~Informatique Date: Tue, 26 Jul 2022 08:44:34 +0200 Subject: viewer: migrate to vue 3, general refactoring and cleanup Non-exhaustive list of fixes and improvements done at the same time: - html default background to grey (avoids white flash during init) - unified links behavior - added more theme variables - removed the flex-expand transition (it wasn't working) and replaced it with a slide - fixed LdLoading not centered on the content - title on removable tags - fixed an issue with encoded URI from vue-router - unified Item resource URLs - removed the iframe for PlainTextViewer (it wasn't working properly) and replaced it with a pre - fixed clear and search buttons tabindex - fixed the information panel bumping up during the fade animation of tag's dropdown - fixed some focus outlines not appearing correctly - moved CSS variables to the :root context - Code cleaning GitHub: closes #217 GitHub: closes #300 GitHub: closes #297 GitHub: closes #105 GitHub: closes #267 GitHub: closes #275 GitHub: closes #228 GitHub: closes #215 GitHub: closes #112 --- viewer/src/store/galleryStore.ts | 201 ++++++++++++++++----------------------- viewer/src/store/index.ts | 46 --------- viewer/src/store/uiStore.ts | 116 +++++++++------------- 3 files changed, 129 insertions(+), 234 deletions(-) delete mode 100644 viewer/src/store/index.ts (limited to 'viewer/src/store') diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts index e2adf18..7ee660a 100644 --- a/viewer/src/store/galleryStore.ts +++ b/viewer/src/store/galleryStore.ts @@ -1,7 +1,7 @@ /* ldgallery - A static generator which turns a collection of tagged -- pictures into a searchable web gallery. -- --- Copyright (C) 2019-2020 Guillaume FOUET +-- Copyright (C) 2019-2022 Guillaume FOUET -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU Affero General Public License as @@ -17,124 +17,89 @@ -- along with this program. If not, see . */ -import { Config, Index, Item } from "@/@types/gallery"; -import { TagCategory, TagIndex, TagSearch } from "@/@types/tag"; -import IndexFactory from "@/services/indexfactory"; -import Navigation from "@/services/navigation"; -import { action, createModule, mutation } from "vuex-class-component"; +import { Config, Index, Item } from '@/@types/gallery'; +import { TagCategory, TagIndex, TagSearch } from '@/@types/tag'; +import { useIndexFactory } from '@/services/indexFactory'; +import { useNavigation } from '@/services/navigation'; +import { defineStore } from 'pinia'; -const VuexModule = createModule({ - namespaced: "galleryStore", - strict: true, -}); - -export default class GalleryStore extends VuexModule { - config: Config | null = null; - galleryIndex: Index | null = null; - tagsIndex: TagIndex = {}; - tagsCategories: TagCategory[] = []; - currentPath: string | null = null; - currentSearch: TagSearch[] = []; - - // --- - - @mutation private setConfig(config: Config) { - this.config = config; - } - - @mutation setGalleryIndex(galleryIndex: Index) { - this.galleryIndex = Object.freeze(galleryIndex); - } - - @mutation private setTagsIndex(tagsIndex: TagIndex) { - this.tagsIndex = Object.freeze(tagsIndex); - } - - @mutation private setTagsCategories(tagsCategories: TagCategory[]) { - this.tagsCategories = tagsCategories; - } - - @mutation setCurrentPath(currentPath: string) { - this.currentPath = currentPath; - } - - @mutation setCurrentSearch(currentSearch: TagSearch[]) { - this.currentSearch = currentSearch; - } - - // --- - - get currentItemPath(): Item[] { - const root = this.galleryIndex?.tree; - if (root && this.currentPath) return Navigation.searchCurrentItemPath(root, this.currentPath); - return []; - } - - get currentItem(): Item | null { - const path = this.currentItemPath; - return path.length > 0 ? path[path.length - 1] : null; - } +const navigation = useNavigation(); +const indexFactory = useIndexFactory(); - get galleryTitle(): string { - return this.galleryIndex?.properties.galleryTitle ?? "ldgallery"; - } - - get resourceRoot(): string { - return process.env.VUE_APP_DATA_URL + this.config!.galleryRoot; - } - - // --- - - // Fetches the gallery's JSON config - @action async fetchConfig() { - await fetch(`${process.env.VUE_APP_DATA_URL}${GalleryStore.getUrlConfig()}`, { cache: "no-cache" }) - .then(GalleryStore.responseToJson) - .then(this.setConfig); - return this.config!; - } - - // Fetches the gallery's JSON metadata - @action async fetchGalleryItems() { - const root = this.config?.galleryRoot ?? ""; - const index = this.config?.galleryIndex ?? "index.json"; - await fetch(`${process.env.VUE_APP_DATA_URL}${root}${index}`, { cache: "no-cache" }) - .then(GalleryStore.responseToJson) - .then(this.setGalleryIndex) - .then(this.indexTags) - .then(this.indexTagCategories); - return this.galleryIndex!; - } - - // Indexes the gallery - @action async indexTags() { - const root = this.galleryIndex?.tree ?? null; - const index = IndexFactory.generateTags(root); - this.setTagsIndex(index); - return index; - } - - // Indexes the proposed categories - @action async indexTagCategories() { - const categories = IndexFactory.generateCategories(this.tagsIndex, this.galleryIndex?.properties.tagCategories); - this.setTagsCategories(categories); - return categories; - } - - // Searches for tags - @action async search(filters: string[]) { - const results = filters.flatMap(filter => IndexFactory.searchTags(this.tagsIndex, filter, true)); - this.setCurrentSearch(results); - return results; - } - - private static getUrlConfig() { - const search = window.location.search; - if (search.length > 1) return search.substr(1) + ".json"; - return "config.json"; - } +function getUrlConfig() { + const search = window.location.search; + if (search.length > 1) return search.substring(1) + '.json'; + return 'config.json'; +} - private static responseToJson(response: Response) { - if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`); - return response.json(); - } +function responseToJson(response: Response) { + if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`); + return response.json(); } + +export const useGalleryStore = defineStore('gallery', { + state: () => ({ + config: null as Config | null, + galleryIndex: null as Index | null, + tagsIndex: {} as TagIndex, + tagsCategories: [] as TagCategory[], + currentPath: null as string | null, + currentSearch: [] as TagSearch[], + }), + getters: { + currentItemPath(): Item[] { + const root = this.galleryIndex?.tree; + if (root && this.currentPath) return navigation.searchCurrentItemPath(root, this.currentPath); + return []; + }, + currentItem(): Item | null { + const path = this.currentItemPath; + return path.length > 0 ? path[path.length - 1] : null; + }, + galleryTitle(): string { + return this.galleryIndex?.properties.galleryTitle ?? 'ldgallery'; + }, + resourceRoot(): string { + return process.env.VUE_APP_DATA_URL + (this.config?.galleryRoot ?? ''); + }, + }, + actions: { + // Fetches the gallery's JSON config + async fetchConfig() { + await fetch(`${process.env.VUE_APP_DATA_URL}${getUrlConfig()}`, { cache: 'no-cache' }) + .then(responseToJson) + .then(v => (this.config = v)); + return this.config as Config; + }, + // Fetches the gallery's JSON metadata + async fetchGalleryItems() { + const root = this.config?.galleryRoot ?? ''; + const index = this.config?.galleryIndex ?? 'index.json'; + await fetch(`${process.env.VUE_APP_DATA_URL}${root}${index}`, { cache: 'no-cache' }) + .then(responseToJson) + .then(v => (this.galleryIndex = v)) + .then(this.indexTags) + .then(this.indexTagCategories); + return this.galleryIndex; + }, + // Indexes the gallery + async indexTags() { + const root = this.galleryIndex?.tree ?? null; + const index = indexFactory.generateTags(root); + this.tagsIndex = index; + return index; + }, + // Indexes the proposed categories + async indexTagCategories() { + const categories = indexFactory.generateCategories(this.tagsIndex, this.galleryIndex?.properties.tagCategories); + this.tagsCategories = categories; + return categories; + }, + // Searches for tags + async search(filters: string[]) { + const results = filters.flatMap(filter => indexFactory.searchTags(this.tagsIndex, filter, true)); + this.currentSearch = results; + return results; + }, + }, +}); diff --git a/viewer/src/store/index.ts b/viewer/src/store/index.ts deleted file mode 100644 index 1f49589..0000000 --- a/viewer/src/store/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* ldgallery - A static generator which turns a collection of tagged --- pictures into a searchable web gallery. --- --- Copyright (C) 2019-2020 Guillaume FOUET --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU Affero General Public License as --- published by the Free Software Foundation, either version 3 of the --- License, or (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Affero General Public License for more details. --- --- You should have received a copy of the GNU Affero General Public License --- along with this program. If not, see . -*/ - -import GalleryStore from "@/store/galleryStore"; -import UIStore from "@/store/uiStore"; -import Vue from "vue"; -import Vuex from "vuex"; -import { createProxy, extractVuexModule } from "vuex-class-component"; - -Vue.use(Vuex); - -const store = new Vuex.Store({ - modules: { - ...extractVuexModule(UIStore), - ...extractVuexModule(GalleryStore), - }, - strict: process.env.NODE_ENV !== "production", -}); - -Vue.use(vue => (vue.prototype.$uiStore = createProxy(store, UIStore))); -Vue.use(vue => (vue.prototype.$galleryStore = createProxy(store, GalleryStore))); - -declare module "vue/types/vue" { - interface Vue { - $uiStore: UIStore; - $galleryStore: GalleryStore; - } -} - -export default store; diff --git a/viewer/src/store/uiStore.ts b/viewer/src/store/uiStore.ts index 520fcf4..df8dacc 100644 --- a/viewer/src/store/uiStore.ts +++ b/viewer/src/store/uiStore.ts @@ -1,7 +1,7 @@ /* ldgallery - A static generator which turns a collection of tagged -- pictures into a searchable web gallery. -- --- Copyright (C) 2019-2020 Guillaume FOUET +-- Copyright (C) 2019-2022 Guillaume FOUET -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU Affero General Public License as @@ -17,73 +17,49 @@ -- along with this program. If not, see . */ -import { Config } from "@/@types/gallery"; -import { SplashScreenConfig } from "@/@types/splashscreen"; -import ItemComparators, { ItemSort } from "@/services/itemComparators"; -import { action, createModule, mutation } from "vuex-class-component"; - -const VuexModule = createModule({ - namespaced: "uiStore", - strict: true, +import { Config } from '@/@types/gallery'; +import { SplashScreenConfig } from '@/@types/splashscreen'; +import { ItemSort, useItemComparator } from '@/services/itemComparator'; +import { useLocalStorage } from '@vueuse/core'; +import { defineStore } from 'pinia'; + +const itemComparator = useItemComparator(); +const splashScreenAcknowledgment = useLocalStorage('splashScreenAcknowledgment', ''); + +export const useUiStore = defineStore('ui', { + state: () => ({ + fullscreen: false, + fullWidth: window.innerWidth < Number(process.env.VUE_APP_FULLWIDTH_LIMIT), + searchMode: false, + sort: itemComparator.DEFAULT as ItemSort, + + splashScreenConfig: null as SplashScreenConfig | null, + splashScreenEnabled: false, + }), + getters: { + }, + actions: { + toggleFullscreen(value?: boolean) { + this.fullscreen = value ?? !this.fullscreen; + }, + toggleFullWidth(value?: boolean) { + this.fullWidth = value ?? !this.fullWidth; + }, + validateSpashScreen() { + this.splashScreenEnabled = false; + splashScreenAcknowledgment.value = this.splashScreenConfig?.acknowledgmentKey ?? ''; + }, + async initFromConfig(config: Config) { + if (config.initialItemSort) { + const itemSort = itemComparator.ITEM_SORTS.find(sort => sort.name === config.initialItemSort); + if (itemSort) this.sort = itemSort; + else throw new Error('Unknown sort type: ' + config.initialItemSort); + } + if (config.splashScreen) { + this.splashScreenConfig = config.splashScreen; + const uid = config.splashScreen.acknowledgmentKey; + this.splashScreenEnabled = !uid || splashScreenAcknowledgment.value !== uid; + } + }, + }, }); - -const STORAGE_SPLASHSCREEN_ACKNOWLEDGMENT = "splashScreenAcknowledgment"; - -export default class UIStore extends VuexModule { - fullscreen: boolean = false; - fullWidth: boolean = window.innerWidth < Number(process.env.VUE_APP_FULLWIDTH_LIMIT); - searchMode: boolean = false; - sort: ItemSort = ItemComparators.DEFAULT; - - splashScreenConfig: SplashScreenConfig | null = null; - splashScreenEnabled: boolean = false; - - // --- - - @mutation toggleFullscreen(value?: boolean) { - this.fullscreen = value ?? !this.fullscreen; - } - - @mutation toggleFullWidth(value?: boolean) { - this.fullWidth = value ?? !this.fullWidth; - } - - @mutation toggleSearchMode(value?: boolean) { - this.searchMode = value ?? !this.searchMode; - } - - @mutation setSort(sort: ItemSort) { - this.sort = sort; - } - - @mutation setSplashScreenConfig(splashScreenConfig: SplashScreenConfig) { - this.splashScreenConfig = splashScreenConfig; - } - - @mutation setSplashScreenEnabled(enabled: boolean) { - this.splashScreenEnabled = enabled; - } - - // --- - - @action async initFromConfig(config: Config) { - if (config.initialItemSort) { - const itemSort = ItemComparators.ITEM_SORTS[config.initialItemSort]; - if (itemSort) this.setSort(itemSort); - else throw new Error("Unknown sort type: " + config.initialItemSort); - } - if (config.splashScreen) { - this.setSplashScreenConfig(config.splashScreen); - const uid = config.splashScreen.acknowledgmentKey; - this.setSplashScreenEnabled(!uid || localStorage.getItem(STORAGE_SPLASHSCREEN_ACKNOWLEDGMENT) !== uid); - } - } - - // --- - - @action async validateSpashScreen() { - this.setSplashScreenEnabled(false); - const uid = this.splashScreenConfig?.acknowledgmentKey; - if (uid) localStorage.setItem(STORAGE_SPLASHSCREEN_ACKNOWLEDGMENT, String(uid)); - } -} -- cgit v1.2.3