aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/store
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/store')
-rw-r--r--viewer/src/store/galleryStore.ts201
-rw-r--r--viewer/src/store/index.ts46
-rw-r--r--viewer/src/store/uiStore.ts116
3 files changed, 129 insertions, 234 deletions
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 @@
1/* ldgallery - A static generator which turns a collection of tagged 1/* ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery. 2-- pictures into a searchable web gallery.
3-- 3--
4-- Copyright (C) 2019-2020 Guillaume FOUET 4-- Copyright (C) 2019-2022 Guillaume FOUET
5-- 5--
6-- This program is free software: you can redistribute it and/or modify 6-- This program is free software: you can redistribute it and/or modify
7-- it under the terms of the GNU Affero General Public License as 7-- it under the terms of the GNU Affero General Public License as
@@ -17,124 +17,89 @@
17-- along with this program. If not, see <https://www.gnu.org/licenses/>. 17-- along with this program. If not, see <https://www.gnu.org/licenses/>.
18*/ 18*/
19 19
20import { Config, Index, Item } from "@/@types/gallery"; 20import { Config, Index, Item } from '@/@types/gallery';
21import { TagCategory, TagIndex, TagSearch } from "@/@types/tag"; 21import { TagCategory, TagIndex, TagSearch } from '@/@types/tag';
22import IndexFactory from "@/services/indexfactory"; 22import { useIndexFactory } from '@/services/indexFactory';
23import Navigation from "@/services/navigation"; 23import { useNavigation } from '@/services/navigation';
24import { action, createModule, mutation } from "vuex-class-component"; 24import { defineStore } from 'pinia';
25 25
26const VuexModule = createModule({ 26const navigation = useNavigation();
27 namespaced: "galleryStore", 27const indexFactory = useIndexFactory();
28 strict: true,
29});
30
31export default class GalleryStore extends VuexModule {
32 config: Config | null = null;
33 galleryIndex: Index | null = null;
34 tagsIndex: TagIndex = {};
35 tagsCategories: TagCategory[] = [];
36 currentPath: string | null = null;
37 currentSearch: TagSearch[] = [];
38
39 // ---
40
41 @mutation private setConfig(config: Config) {
42 this.config = config;
43 }
44
45 @mutation setGalleryIndex(galleryIndex: Index) {
46 this.galleryIndex = Object.freeze(galleryIndex);
47 }
48
49 @mutation private setTagsIndex(tagsIndex: TagIndex) {
50 this.tagsIndex = Object.freeze(tagsIndex);
51 }
52
53 @mutation private setTagsCategories(tagsCategories: TagCategory[]) {
54 this.tagsCategories = tagsCategories;
55 }
56
57 @mutation setCurrentPath(currentPath: string) {
58 this.currentPath = currentPath;
59 }
60
61 @mutation setCurrentSearch(currentSearch: TagSearch[]) {
62 this.currentSearch = currentSearch;
63 }
64
65 // ---
66
67 get currentItemPath(): Item[] {
68 const root = this.galleryIndex?.tree;
69 if (root && this.currentPath) return Navigation.searchCurrentItemPath(root, this.currentPath);
70 return [];
71 }
72
73 get currentItem(): Item | null {
74 const path = this.currentItemPath;
75 return path.length > 0 ? path[path.length - 1] : null;
76 }
77 28
78 get galleryTitle(): string { 29function getUrlConfig() {
79 return this.galleryIndex?.properties.galleryTitle ?? "ldgallery"; 30 const search = window.location.search;
80 } 31 if (search.length > 1) return search.substring(1) + '.json';
81 32 return 'config.json';
82 get resourceRoot(): string { 33}
83 return process.env.VUE_APP_DATA_URL + this.config!.galleryRoot;
84 }
85
86 // ---
87
88 // Fetches the gallery's JSON config
89 @action async fetchConfig() {
90 await fetch(`${process.env.VUE_APP_DATA_URL}${GalleryStore.getUrlConfig()}`, { cache: "no-cache" })
91 .then(GalleryStore.responseToJson)
92 .then(this.setConfig);
93 return this.config!;
94 }
95
96 // Fetches the gallery's JSON metadata
97 @action async fetchGalleryItems() {
98 const root = this.config?.galleryRoot ?? "";
99 const index = this.config?.galleryIndex ?? "index.json";
100 await fetch(`${process.env.VUE_APP_DATA_URL}${root}${index}`, { cache: "no-cache" })
101 .then(GalleryStore.responseToJson)
102 .then(this.setGalleryIndex)
103 .then(this.indexTags)
104 .then(this.indexTagCategories);
105 return this.galleryIndex!;
106 }
107
108 // Indexes the gallery
109 @action async indexTags() {
110 const root = this.galleryIndex?.tree ?? null;
111 const index = IndexFactory.generateTags(root);
112 this.setTagsIndex(index);
113 return index;
114 }
115
116 // Indexes the proposed categories
117 @action async indexTagCategories() {
118 const categories = IndexFactory.generateCategories(this.tagsIndex, this.galleryIndex?.properties.tagCategories);
119 this.setTagsCategories(categories);
120 return categories;
121 }
122
123 // Searches for tags
124 @action async search(filters: string[]) {
125 const results = filters.flatMap(filter => IndexFactory.searchTags(this.tagsIndex, filter, true));
126 this.setCurrentSearch(results);
127 return results;
128 }
129
130 private static getUrlConfig() {
131 const search = window.location.search;
132 if (search.length > 1) return search.substr(1) + ".json";
133 return "config.json";
134 }
135 34
136 private static responseToJson(response: Response) { 35function responseToJson(response: Response) {
137 if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`); 36 if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`);
138 return response.json(); 37 return response.json();
139 }
140} 38}
39
40export const useGalleryStore = defineStore('gallery', {
41 state: () => ({
42 config: null as Config | null,
43 galleryIndex: null as Index | null,
44 tagsIndex: {} as TagIndex,
45 tagsCategories: [] as TagCategory[],
46 currentPath: null as string | null,
47 currentSearch: [] as TagSearch[],
48 }),
49 getters: {
50 currentItemPath(): Item[] {
51 const root = this.galleryIndex?.tree;
52 if (root && this.currentPath) return navigation.searchCurrentItemPath(root, this.currentPath);
53 return [];
54 },
55 currentItem(): Item | null {
56 const path = this.currentItemPath;
57 return path.length > 0 ? path[path.length - 1] : null;
58 },
59 galleryTitle(): string {
60 return this.galleryIndex?.properties.galleryTitle ?? 'ldgallery';
61 },
62 resourceRoot(): string {
63 return process.env.VUE_APP_DATA_URL + (this.config?.galleryRoot ?? '');
64 },
65 },
66 actions: {
67 // Fetches the gallery's JSON config
68 async fetchConfig() {
69 await fetch(`${process.env.VUE_APP_DATA_URL}${getUrlConfig()}`, { cache: 'no-cache' })
70 .then(responseToJson)
71 .then(v => (this.config = v));
72 return this.config as Config;
73 },
74 // Fetches the gallery's JSON metadata
75 async fetchGalleryItems() {
76 const root = this.config?.galleryRoot ?? '';
77 const index = this.config?.galleryIndex ?? 'index.json';
78 await fetch(`${process.env.VUE_APP_DATA_URL}${root}${index}`, { cache: 'no-cache' })
79 .then(responseToJson)
80 .then(v => (this.galleryIndex = v))
81 .then(this.indexTags)
82 .then(this.indexTagCategories);
83 return this.galleryIndex;
84 },
85 // Indexes the gallery
86 async indexTags() {
87 const root = this.galleryIndex?.tree ?? null;
88 const index = indexFactory.generateTags(root);
89 this.tagsIndex = index;
90 return index;
91 },
92 // Indexes the proposed categories
93 async indexTagCategories() {
94 const categories = indexFactory.generateCategories(this.tagsIndex, this.galleryIndex?.properties.tagCategories);
95 this.tagsCategories = categories;
96 return categories;
97 },
98 // Searches for tags
99 async search(filters: string[]) {
100 const results = filters.flatMap(filter => indexFactory.searchTags(this.tagsIndex, filter, true));
101 this.currentSearch = results;
102 return results;
103 },
104 },
105});
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 @@
1/* ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2019-2020 Guillaume FOUET
5--
6-- This program is free software: you can redistribute it and/or modify
7-- it under the terms of the GNU Affero General Public License as
8-- published by the Free Software Foundation, either vers