aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/store/galleryStore.ts
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/store/galleryStore.ts')
-rw-r--r--viewer/src/store/galleryStore.ts199
1 files changed, 83 insertions, 116 deletions
diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts
index 5d599aa..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,122 +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 { createModule, mutation, action } from "vuex-class-component"; 20import { Config, Index, Item } from '@/@types/gallery';
21import IndexFactory from "@/services/indexfactory"; 21import { TagCategory, TagIndex, TagSearch } from '@/@types/tag';
22import Navigation from "@/services/navigation"; 22import { useIndexFactory } from '@/services/indexFactory';
23import { useNavigation } from '@/services/navigation';
24import { defineStore } from 'pinia';
23 25
24const VuexModule = createModule({ 26const navigation = useNavigation();
25 namespaced: "galleryStore", 27const indexFactory = useIndexFactory();
26 strict: true,
27});
28
29export default class GalleryStore extends VuexModule {
30 config: Gallery.Config | null = null;
31 galleryIndex: Gallery.Index | null = null;
32 tagsIndex: Tag.Index = {};
33 tagsCategories: Tag.Category[] = [];
34 currentPath: string | null = null;
35 currentSearch: Tag.Search[] = [];
36
37 // ---
38
39 @mutation private setConfig(config: Gallery.Config) {
40 this.config = config;
41 }
42
43 @mutation setGalleryIndex(galleryIndex: Gallery.Index) {
44 this.galleryIndex = Object.freeze(galleryIndex);
45 }
46
47 @mutation private setTagsIndex(tagsIndex: Tag.Index) {
48 this.tagsIndex = Object.freeze(tagsIndex);
49 }
50
51 @mutation private setTagsCategories(tagsCategories: Tag.Category[]) {
52 this.tagsCategories = tagsCategories;
53 }
54
55 @mutation setCurrentPath(currentPath: string) {
56 this.currentPath = currentPath;
57 }
58
59 @mutation setCurrentSearch(currentSearch: Tag.Search[]) {
60 this.currentSearch = currentSearch;
61 }
62
63 // ---
64
65 get currentItemPath(): Gallery.Item[] {
66 const root = this.galleryIndex?.tree;
67 if (root && this.currentPath) return Navigation.searchCurrentItemPath(root, this.currentPath);
68 return [];
69 }
70
71 get currentItem(): Gallery.Item | null {
72 const path = this.currentItemPath;
73 return path.length > 0 ? path[path.length - 1] : null;
74 }
75 28
76 get galleryTitle(): string { 29function getUrlConfig() {
77 return this.galleryIndex?.properties.galleryTitle ?? "ldgallery"; 30 const search = window.location.search;
78 } 31 if (search.length > 1) return search.substring(1) + '.json';
79 32 return 'config.json';
80 get resourceRoot(): string { 33}
81 return process.env.VUE_APP_DATA_URL + this.config!.galleryRoot;
82 }
83
84 // ---
85
86 // Fetches the gallery's JSON config
87 @action async fetchConfig() {
88 await fetch(`${process.env.VUE_APP_DATA_URL}${GalleryStore.getUrlConfig()}`, { cache: "no-cache" })
89 .then(GalleryStore.responseToJson)
90 .then(this.setConfig);
91 return this.config!;
92 }
93
94 // Fetches the gallery's JSON metadata
95 @action async fetchGalleryItems() {
96 const root = this.config?.galleryRoot ?? "";
97 const index = this.config?.galleryIndex ?? "index.json";
98 await fetch(`${process.env.VUE_APP_DATA_URL}${root}${index}`, { cache: "no-cache" })
99 .then(GalleryStore.responseToJson)
100 .then(this.setGalleryIndex)
101 .then(this.indexTags)
102 .then(this.indexTagCategories);
103 return this.galleryIndex!;
104 }
105
106 // Indexes the gallery
107 @action async indexTags() {
108 const root = this.galleryIndex?.tree ?? null;
109 const index = IndexFactory.generateTags(root);
110 this.setTagsIndex(index);
111 return index;
112 }
113
114 // Indexes the proposed categories
115 @action async indexTagCategories() {
116 const categories = IndexFactory.generateCategories(this.tagsIndex, this.galleryIndex?.properties.tagCategories);
117 this.setTagsCategories(categories);
118 return categories;
119 }
120
121 // Searches for tags
122 @action async search(filters: string[]) {
123 const results = filters.flatMap(filter => IndexFactory.searchTags(this.tagsIndex, filter, true));
124 this.setCurrentSearch(results);
125 return results;
126 }
127
128 private static getUrlConfig() {
129 let search = window.location.search;
130 if (search.length > 1) return search.substr(1) + ".json";
131 return "config.json";
132 }
133 34
134 private static responseToJson(response: Response) { 35function responseToJson(response: Response) {
135 if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`); 36 if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`);
136 return response.json(); 37 return response.json();
137 }
138} 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});