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/services/indexfactory.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'viewer/src/services/indexfactory.ts') diff --git a/viewer/src/services/indexfactory.ts b/viewer/src/services/indexfactory.ts index 4b28a60..0c5fdc5 100644 --- a/viewer/src/services/indexfactory.ts +++ b/viewer/src/services/indexfactory.ts @@ -17,19 +17,20 @@ -- along with this program. If not, see . */ -import { Operation } from "@/@types/Operation"; +import { Item, RawTag } from "@/@types/gallery"; import { ItemType } from "@/@types/ItemType"; +import { Operation } from "@/@types/Operation"; import Navigation from "@/services/navigation"; export default class IndexFactory { - public static generateTags(root: Gallery.Item | null): Tag.Index { + public static generateTags(root: Item | null): Tag.Index { const tagsIndex: Tag.Index = {}; if (root) IndexFactory.pushTagsForItem(tagsIndex, root); return tagsIndex; } // Pushes all tags for a root item (and its children) to the index - private static pushTagsForItem(tagsIndex: Tag.Index, item: Gallery.Item): void { + private static pushTagsForItem(tagsIndex: Tag.Index, item: Item): void { if (item.properties.type === ItemType.DIRECTORY) { item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); return; // Directories are not indexed @@ -49,7 +50,7 @@ export default class IndexFactory { } } - private static pushPartToIndex(index: Tag.Node, part: string, item: Gallery.Item, rootPart: boolean): Tag.Node { + private static pushPartToIndex(index: Tag.Node, part: string, item: Item, rootPart: boolean): Tag.Node { if (!index) index = { tag: part, @@ -131,7 +132,7 @@ export default class IndexFactory { // --- - public static generateCategories(tagsIndex: Tag.Index, categoryTags?: Gallery.RawTag[]): Tag.Category[] { + public static generateCategories(tagsIndex: Tag.Index, categoryTags?: RawTag[]): Tag.Category[] { if (!categoryTags?.length) return [{ tag: "", index: tagsIndex }]; const tagsCategories: Tag.Category[] = []; @@ -149,7 +150,7 @@ export default class IndexFactory { return tagsCategories; } - private static isDiscriminantTagOnly(tags: Gallery.RawTag[], node: Tag.Node): boolean { + private static isDiscriminantTagOnly(tags: RawTag[], node: Tag.Node): boolean { return !tags.includes(node.tag) || !node.childPart; } } -- 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/services/indexfactory.ts | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'viewer/src/services/indexfactory.ts') diff --git a/viewer/src/services/indexfactory.ts b/viewer/src/services/indexfactory.ts index 0c5fdc5..691a765 100644 --- a/viewer/src/services/indexfactory.ts +++ b/viewer/src/services/indexfactory.ts @@ -20,17 +20,18 @@ import { Item, RawTag } from "@/@types/gallery"; import { ItemType } from "@/@types/ItemType"; import { Operation } from "@/@types/Operation"; +import { TagCategory, TagIndex, TagNode, TagSearch } from "@/@types/tag"; import Navigation from "@/services/navigation"; export default class IndexFactory { - public static generateTags(root: Item | null): Tag.Index { - const tagsIndex: Tag.Index = {}; + public static generateTags(root: Item | null): TagIndex { + const tagsIndex: TagIndex = {}; if (root) IndexFactory.pushTagsForItem(tagsIndex, root); return tagsIndex; } // Pushes all tags for a root item (and its children) to the index - private static pushTagsForItem(tagsIndex: Tag.Index, item: Item): void { + private static pushTagsForItem(tagsIndex: TagIndex, item: Item): void { if (item.properties.type === ItemType.DIRECTORY) { item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); return; // Directories are not indexed @@ -50,7 +51,7 @@ export default class IndexFactory { } } - private static pushPartToIndex(index: Tag.Node, part: string, item: Item, rootPart: boolean): Tag.Node { + private static pushPartToIndex(index: TagNode, part: string, item: Item, rootPart: boolean): TagNode { if (!index) index = { tag: part, @@ -69,8 +70,8 @@ export default class IndexFactory { // --- - public static searchTags(tagsIndex: Tag.Index, filter: string, strict: boolean): Tag.Search[] { - let search: Tag.Search[] = []; + public static searchTags(tagsIndex: TagIndex, filter: string, strict: boolean): TagSearch[] { + let search: TagSearch[] = []; if (tagsIndex && filter) { const operation = IndexFactory.extractOperation(filter); if (operation !== Operation.INTERSECTION) filter = filter.slice(1); @@ -96,12 +97,12 @@ export default class IndexFactory { } private static searchTagsFromFilterWithCategory( - tagsIndex: Tag.Index, + tagsIndex: TagIndex, operation: Operation, category: string, disambiguation: string, strict: boolean - ): Tag.Search[] { + ): TagSearch[] { category = Navigation.normalize(category); disambiguation = Navigation.normalize(disambiguation); return Object.values(tagsIndex) @@ -114,28 +115,28 @@ export default class IndexFactory { } private static searchTagsFromFilter( - tagsIndex: Tag.Index, + tagsIndex: TagIndex, operation: Operation, filter: string, strict: boolean - ): Tag.Search[] { + ): TagSearch[] { filter = Navigation.normalize(filter); return Object.values(tagsIndex) .filter(node => IndexFactory.matches(node, filter, strict)) .map(node => ({ ...node, operation, display: `${operation}${node.tag}` })); } - private static matches(node: Tag.Node, filter: string, strict: boolean): boolean { + private static matches(node: TagNode, filter: string, strict: boolean): boolean { if (strict) return node.tagfiltered === filter; return node.tagfiltered.includes(filter); } // --- - public static generateCategories(tagsIndex: Tag.Index, categoryTags?: RawTag[]): Tag.Category[] { + public static generateCategories(tagsIndex: TagIndex, categoryTags?: RawTag[]): TagCategory[] { if (!categoryTags?.length) return [{ tag: "", index: tagsIndex }]; - const tagsCategories: Tag.Category[] = []; + const tagsCategories: TagCategory[] = []; const tagsRemaining = new Map(Object.entries(tagsIndex)); categoryTags .map(tag => ({ tag, index: tagsIndex[tag]?.children })) @@ -150,7 +151,7 @@ export default class IndexFactory { return tagsCategories; } - private static isDiscriminantTagOnly(tags: RawTag[], node: Tag.Node): boolean { + private static isDiscriminantTagOnly(tags: RawTag[], node: TagNode): boolean { return !tags.includes(node.tag) || !node.childPart; } } -- 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/services/indexfactory.ts | 157 ------------------------------------ 1 file changed, 157 deletions(-) delete mode 100644 viewer/src/services/indexfactory.ts (limited to 'viewer/src/services/indexfactory.ts') diff --git a/viewer/src/services/indexfactory.ts b/viewer/src/services/indexfactory.ts deleted file mode 100644 index 691a765..0000000 --- a/viewer/src/services/indexfactory.ts +++ /dev/null @@ -1,157 +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 { Item, RawTag } from "@/@types/gallery"; -import { ItemType } from "@/@types/ItemType"; -import { Operation } from "@/@types/Operation"; -import { TagCategory, TagIndex, TagNode, TagSearch } from "@/@types/tag"; -import Navigation from "@/services/navigation"; - -export default class IndexFactory { - public static generateTags(root: Item | null): TagIndex { - const tagsIndex: TagIndex = {}; - if (root) IndexFactory.pushTagsForItem(tagsIndex, root); - return tagsIndex; - } - - // Pushes all tags for a root item (and its children) to the index - private static pushTagsForItem(tagsIndex: TagIndex, item: Item): void { - if (item.properties.type === ItemType.DIRECTORY) { - item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); - return; // Directories are not indexed - } - for (const tag of item.tags) { - const parts = tag.split(":"); - let lastPart: string | null = null; - for (const part of parts) { - tagsIndex[part] = IndexFactory.pushPartToIndex(tagsIndex[part], part, item, !Boolean(lastPart)); - if (lastPart) { - const children = tagsIndex[lastPart].children; - children[part] = IndexFactory.pushPartToIndex(children[part], part, item, false); - } - lastPart = part; - } - if (lastPart) tagsIndex[lastPart].childPart = true; - } - } - - private static pushPartToIndex(index: TagNode, part: string, item: Item, rootPart: boolean): TagNode { - if (!index) - index = { - tag: part, - tagfiltered: Navigation.normalize(part), - rootPart, - childPart: !rootPart, - items: [], - children: {}, - }; - else if (rootPart) index.rootPart = true; - else index.childPart = true; - - if (!index.items.includes(item)) index.items.push(item); - return index; - } - - // --- - - public static searchTags(tagsIndex: TagIndex, filter: string, strict: boolean): TagSearch[] { - let search: TagSearch[] = []; - if (tagsIndex && filter) { - const operation = IndexFactory.extractOperation(filter); - if (operation !== Operation.INTERSECTION) filter = filter.slice(1); - if (filter.includes(":")) { - const filterParts = filter.split(":"); - search = this.searchTagsFromFilterWithCategory(tagsIndex, operation, filterParts[0], filterParts[1], strict); - } else { - search = this.searchTagsFromFilter(tagsIndex, operation, filter, strict); - } - } - return search; - } - - private static extractOperation(filter: string): Operation { - const first = filter.slice(0, 1); - switch (first) { - case Operation.ADDITION: - case Operation.SUBSTRACTION: - return first; - default: - return Operation.INTERSECTION; - } - } - - private static searchTagsFromFilterWithCategory( - tagsIndex: TagIndex, - operation: Operation, - category: string, - disambiguation: string, - strict: boolean - ): TagSearch[] { - category = Navigation.normalize(category); - disambiguation = Navigation.normalize(disambiguation); - return Object.values(tagsIndex) - .filter(node => IndexFactory.matches(node, category, strict)) - .flatMap(node => - Object.values(node.children) - .filter(child => IndexFactory.matches(child, disambiguation, strict)) - .map(child => ({ ...child, parent: node, operation, display: `${operation}${node.tag}:${child.tag}` })) - ); - } - - private static searchTagsFromFilter( - tagsIndex: TagIndex, - operation: Operation, - filter: string, - strict: boolean - ): TagSearch[] { - filter = Navigation.normalize(filter); - return Object.values(tagsIndex) - .filter(node => IndexFactory.matches(node, filter, strict)) - .map(node => ({ ...node, operation, display: `${operation}${node.tag}` })); - } - - private static matches(node: TagNode, filter: string, strict: boolean): boolean { - if (strict) return node.tagfiltered === filter; - return node.tagfiltered.includes(filter); - } - - // --- - - public static generateCategories(tagsIndex: TagIndex, categoryTags?: RawTag[]): TagCategory[] { - if (!categoryTags?.length) return [{ tag: "", index: tagsIndex }]; - - const tagsCategories: TagCategory[] = []; - const tagsRemaining = new Map(Object.entries(tagsIndex)); - categoryTags - .map(tag => ({ tag, index: tagsIndex[tag]?.children })) - .filter(category => category.index && Object.keys(category.index).length) - .forEach(category => { - tagsCategories.push(category); - [category.tag, ...Object.values(category.index).map(node => node.tag)] - .filter(tag => IndexFactory.isDiscriminantTagOnly(categoryTags, tagsIndex[tag])) - .forEach(tag => tagsRemaining.delete(tag)); - }); - tagsCategories.push({ tag: "", index: Object.fromEntries(tagsRemaining) }); - return tagsCategories; - } - - private static isDiscriminantTagOnly(tags: RawTag[], node: TagNode): boolean { - return !tags.includes(node.tag) || !node.childPart; - } -} -- cgit v1.2.3