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.ts110
1 files changed, 110 insertions, 0 deletions
diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts
new file mode 100644
index 0000000..c4a039f
--- /dev/null
+++ b/viewer/src/store/galleryStore.ts
@@ -0,0 +1,110 @@
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 version 3 of the
9-- License, or (at your option) any later version.
10--
11-- This program is distributed in the hope that it will be useful,
12-- but WITHOUT ANY WARRANTY; without even the implied warranty of
13-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14-- GNU Affero General Public License for more details.
15--
16-- You should have received a copy of the GNU Affero General Public License
17-- along with this program. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20import { createModule, mutation, action } from "vuex-class-component";
21
22const VuexModule = createModule({
23 namespaced: "galleryStore",
24 strict: true
25})
26
27export default class GalleryStore extends VuexModule {
28
29 galleryItemsRoot: Gallery.Item | null = null;
30 tags: Tag.Index = {};
31 currentPath: string = "/";
32
33 // ---
34
35 @mutation setGalleryItemsRoot(galleryItemsRoot: Gallery.Item) {
36 this.galleryItemsRoot = galleryItemsRoot;
37 }
38
39 @mutation private setTags(tags: Tag.Index) {
40 this.tags = tags;
41 }
42
43 @mutation setCurrentPath(currentPath: string) {
44 this.currentPath = currentPath;
45 }
46
47 get currentItemPath(): Gallery.Item[] {
48 const galleryItemsRoot = this.galleryItemsRoot;
49 if (galleryItemsRoot)
50 return GalleryStore.searchCurrentItemPath(galleryItemsRoot, this.currentPath);
51 return [];
52 }
53
54 get currentItem(): Gallery.Item | null {
55 const currentItemPath = this.currentItemPath;
56 return currentItemPath.length > 0 ? currentItemPath[currentItemPath.length - 1] : null;
57 }
58
59 // ---
60
61 // Fetches the gallery's JSON metadata
62 @action async fetchGalleryItems(url: string) {
63 fetch(url)
64 .then(response => response.json())
65 .then(this.setGalleryItemsRoot)
66 .then(this.indexTags);
67 }
68
69 // Indexes the gallery
70 @action async indexTags() {
71 let index = {};
72 if (this.galleryItemsRoot)
73 GalleryStore.pushTagsForItem(index, this.galleryItemsRoot);
74 console.log("Index: ", index);
75 this.setTags(index);
76 }
77
78 // ---
79
80 // Pushes all tags for a root item (and its children) to the index
81 private static pushTagsForItem(index: Tag.Index, item: Gallery.Item) {
82 console.log("IndexingTagsFor: ", item.path);
83 if (item.properties.type === "directory") {
84 item.properties.items.forEach(item => this.pushTagsForItem(index, item));
85 return; // Directories are not indexed
86 }
87 for (const tag of item.tags) {
88 const parts = tag.split('.');
89 let lastPart: string | null = null;
90 for (const part of parts) {
91 if (!index[part]) index[part] = { tag: part, items: [], children: {} };
92 if (!index[part].items.includes(item)) index[part].items.push(item);
93 if (lastPart) index[lastPart].children[part] = index[part];
94 lastPart = part;
95 }
96 }
97 }
98
99 // Searches for an item by path from a root item (navigation)
100 private static searchCurrentItemPath(item: Gallery.Item, path: string): Gallery.Item[] {
101 if (path === item.path) return [item];
102 if (item.properties.type === "directory" && path.startsWith(item.path)) {
103 const itemChain = item.properties.items
104 .map(item => this.searchCurrentItemPath(item, path))
105 .find(itemChain => itemChain.length > 0);
106 if (itemChain) return [item, ...itemChain];
107 }
108 return [];
109 }
110} \ No newline at end of file