aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/store
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/store')
-rw-r--r--viewer/src/store/galleryStore.ts180
-rw-r--r--viewer/src/store/index.ts13
-rw-r--r--viewer/src/store/uiStore.ts40
3 files changed, 118 insertions, 115 deletions
diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts
index c4a039f..0cffdd9 100644
--- a/viewer/src/store/galleryStore.ts
+++ b/viewer/src/store/galleryStore.ts
@@ -18,93 +18,105 @@
18*/ 18*/
19 19
20import { createModule, mutation, action } from "vuex-class-component"; 20import { createModule, mutation, action } from "vuex-class-component";
21import IndexFactory from "@/services/indexfactory";
22import Navigation from "@/services/navigation";
21 23
22const VuexModule = createModule({ 24const VuexModule = createModule({
23 namespaced: "galleryStore", 25 namespaced: "galleryStore",
24 strict: true 26 strict: true
25}) 27})
26 28
27export default class GalleryStore extends VuexModule { 29export default class GalleryStore extends VuexModule {
28 30
29 galleryItemsRoot: Gallery.Item | null = null; 31 config: Gallery.Config | null = null;
30 tags: Tag.Index = {}; 32 galleryIndex: Gallery.Index | null = null;
31 currentPath: string = "/"; 33 tagsIndex: Tag.Index = {};
32 34 tagsCategories: Tag.Category[] = [];
33 // --- 35 currentPath: string = "/";
34 36 currentSearch: Tag.Search[] = [];
35 @mutation setGalleryItemsRoot(galleryItemsRoot: Gallery.Item) { 37
36 this.galleryItemsRoot = galleryItemsRoot; 38 // ---
37 } 39
38 40 @mutation private setConfig(config: Gallery.Config) {
39 @mutation private setTags(tags: Tag.Index) { 41 this.config = config;
40 this.tags = tags; 42 }
41 } 43
42 44 @mutation setGalleryIndex(galleryIndex: Gallery.Index) {
43 @mutation setCurrentPath(currentPath: string) { 45 this.galleryIndex = Object.freeze(galleryIndex);
44 this.currentPath = currentPath; 46 }
45 } 47
46 48 @mutation private setTagsIndex(tagsIndex: Tag.Index) {
47 get currentItemPath(): Gallery.Item[] { 49 this.tagsIndex = Object.freeze(tagsIndex);
48 const galleryItemsRoot = this.galleryItemsRoot; 50 }
49 if (galleryItemsRoot) 51
50 return GalleryStore.searchCurrentItemPath(galleryItemsRoot, this.currentPath); 52 @mutation private setTagsCategories(tagsCategories: Tag.Category[]) {
51 return []; 53 this.tagsCategories = tagsCategories;
52 } 54 }
53 55
54 get currentItem(): Gallery.Item | null { 56 @mutation setCurrentPath(currentPath: string) {
55 const currentItemPath = this.currentItemPath; 57 this.currentPath = currentPath;
56 return currentItemPath.length > 0 ? currentItemPath[currentItemPath.length - 1] : null; 58 }
57 } 59
58 60 @mutation setCurrentSearch(currentSearch: Tag.Search[]) {
59 // --- 61 this.currentSearch = currentSearch;
60 62 }
61 // Fetches the gallery's JSON metadata 63
62 @action async fetchGalleryItems(url: string) { 64 // ---
63 fetch(url) 65
64 .then(response => response.json()) 66 get currentItemPath(): Gallery.Item[] {
65 .then(this.setGalleryItemsRoot) 67 const root = this.galleryIndex?.tree;
66 .then(this.indexTags); 68 if (root)
67 } 69 return Navigation.searchCurrentItemPath(root, this.currentPath);
68 70 return [];
69 // Indexes the gallery 71 }
70 @action async indexTags() { 72
71 let index = {}; 73 get currentItem(): Gallery.Item | null {
72 if (this.galleryItemsRoot) 74 const path = this.currentItemPath;
73 GalleryStore.pushTagsForItem(index, this.galleryItemsRoot); 75 return path.length > 0 ? path[path.length - 1] : null;
74 console.log("Index: ", index); 76 }
75 this.setTags(index); 77
76 } 78 get galleryTitle(): string {
77 79 return this.galleryIndex?.properties.galleryTitle ?? "ldgallery";
78 // --- 80 }
79 81
80 // Pushes all tags for a root item (and its children) to the index 82 // ---
81 private static pushTagsForItem(index: Tag.Index, item: Gallery.Item) { 83
82 console.log("IndexingTagsFor: ", item.path); 84 // Fetches the gallery's JSON config
83 if (item.properties.type === "directory") { 85 @action async fetchConfig() {
84 item.properties.items.forEach(item => this.pushTagsForItem(index, item)); 86 return fetch(`${process.env.VUE_APP_DATA_URL}config.json`, { cache: "no-cache" })
85 return; // Directories are not indexed 87 .then(response => response.json())
86 } 88 .then(this.setConfig);
87 for (const tag of item.tags) { 89 }
88 const parts = tag.split('.'); 90
89 let lastPart: string | null = null; 91 // Fetches the gallery's JSON metadata
90 for (const part of parts) { 92 @action async fetchGalleryItems() {
91 if (!index[part]) index[part] = { tag: part, items: [], children: {} }; 93 const root = this.config?.galleryRoot ?? "";
92 if (!index[part].items.includes(item)) index[part].items.push(item); 94 return fetch(`${process.env.VUE_APP_DATA_URL}${root}index.json`, { cache: "no-cache" })
93 if (lastPart) index[lastPart].children[part] = index[part]; 95 .then(response => response.json())
94 lastPart = part; 96 .then(this.setGalleryIndex)
95 } 97 .then(this.indexTags)
96 } 98 .then(this.indexTagCategories);
97 } 99 }
98 100
99 // Searches for an item by path from a root item (navigation) 101 // Indexes the gallery
100 private static searchCurrentItemPath(item: Gallery.Item, path: string): Gallery.Item[] { 102 @action async indexTags() {
101 if (path === item.path) return [item]; 103 const root = this.galleryIndex?.tree ?? null;
102 if (item.properties.type === "directory" && path.startsWith(item.path)) { 104 const index = IndexFactory.generateTags(root);
103 const itemChain = item.properties.items 105 this.setTagsIndex(index);
104 .map(item => this.searchCurrentItemPath(item, path)) 106 return index;
105 .find(itemChain => itemChain.length > 0); 107 }
106 if (itemChain) return [item, ...itemChain]; 108
107 } 109 // Indexes the proposed categories
108 return []; 110 @action async indexTagCategories() {
109 } 111 const categories = IndexFactory.generateCategories(this.tagsIndex, this.galleryIndex?.properties.tagCategories);
110} \ No newline at end of file 112 this.setTagsCategories(categories);
113 return categories;
114 }
115
116 // Searches for tags
117 @action async search(filters: string[]) {
118 const results = filters.flatMap(filter => IndexFactory.searchTags(this.tagsIndex, filter, true));
119 this.setCurrentSearch(results);
120 return results;
121 }
122}
diff --git a/viewer/src/store/index.ts b/viewer/src/store/index.ts
index 0277fa4..d5339e8 100644
--- a/viewer/src/store/index.ts
+++ b/viewer/src/store/index.ts
@@ -17,12 +17,12 @@
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 Vue from 'vue' 20import Vue from "vue"
21import Vuex from 'vuex' 21import Vuex from "vuex"
22import { extractVuexModule } from "vuex-class-component"; 22import { extractVuexModule } from "vuex-class-component";
23import { createProxy } from "vuex-class-component"; 23import { createProxy } from "vuex-class-component";
24import UIStore from '@/store/uiStore'; 24import UIStore from "@/store/uiStore";
25import GalleryStore from '@/store/galleryStore'; 25import GalleryStore from "@/store/galleryStore";
26 26
27Vue.use(Vuex) 27Vue.use(Vuex)
28 28
@@ -30,13 +30,14 @@ const store = new Vuex.Store({
30 modules: { 30 modules: {
31 ...extractVuexModule(UIStore), 31 ...extractVuexModule(UIStore),
32 ...extractVuexModule(GalleryStore) 32 ...extractVuexModule(GalleryStore)
33 } 33 },
34 strict: process.env.NODE_ENV !== "production",
34}); 35});
35 36
36Vue.use((vue) => vue.prototype.$uiStore = createProxy(store, UIStore)); 37Vue.use((vue) => vue.prototype.$uiStore = createProxy(store, UIStore));
37Vue.use((vue) => vue.prototype.$galleryStore = createProxy(store, GalleryStore)); 38Vue.use((vue) => vue.prototype.$galleryStore = createProxy(store, GalleryStore));
38 39
39declare module 'vue/types/vue' { 40declare module "vue/types/vue" {
40 interface Vue { 41 interface Vue {
41 $uiStore: UIStore, 42 $uiStore: UIStore,
42 $galleryStore: GalleryStore 43 $galleryStore: GalleryStore
diff --git a/viewer/src/store/uiStore.ts b/viewer/src/store/uiStore.ts
index 6bcc538..892d35e 100644
--- a/viewer/src/store/uiStore.ts
+++ b/viewer/src/store/uiStore.ts
@@ -20,37 +20,27 @@
20import { createModule, mutation, action } from "vuex-class-component"; 20import { createModule, mutation, action } from "vuex-class-component";
21 21
22const VuexModule = createModule({ 22const VuexModule = createModule({
23 namespaced: "uiStore", 23 namespaced: "uiStore",
24 strict: false 24 strict: true
25}) 25})
26 26
27export default class UIStore extends VuexModule { 27export default class UIStore extends VuexModule {
28 28
29 fullscreen: boolean = false; 29 fullscreen: boolean = false;
30 mode: "navigation" | "search" = "navigation"; 30 fullWidth: boolean = window.innerWidth < Number(process.env.VUE_APP_FULLWIDTH_LIMIT);
31 currentTags: Tag.Search[] = []; 31 searchMode: boolean = false;
32 32
33 // --- 33 // ---
34 34
35 get isModeSearch() { 35 @mutation toggleFullscreen(value?: boolean) {
36 return this.mode === "search"; 36 this.fullscreen = value ?? !this.fullscreen;
37 }