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/navigation.ts | 90 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 47 deletions(-) (limited to 'viewer/src/services/navigation.ts') diff --git a/viewer/src/services/navigation.ts b/viewer/src/services/navigation.ts index 5dcea88..b2e807b 100644 --- a/viewer/src/services/navigation.ts +++ b/viewer/src/services/navigation.ts @@ -1,7 +1,7 @@ /* ldgallery - A static generator which turns a collection of tagged -- pictures into a searchable web gallery. -- --- Copyright (C) 2019-2020 Guillaume FOUET +-- Copyright (C) 2019-2022 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 @@ -17,27 +17,31 @@ -- along with this program. If not, see . */ -import { DirectoryItem, Item } from "@/@types/gallery"; -import { ItemType } from "@/@types/ItemType"; +import { DirectoryItem, DownloadableItem, Item } from '@/@types/gallery'; +import { ItemType } from '@/@types/itemType'; +import { faFile, faFileAlt, faFileAudio, faFilePdf, faFileVideo, faFolder, faHome, faImage, IconDefinition } from '@fortawesome/free-solid-svg-icons'; +import { isDirectory } from './itemGuards'; -export default class Navigation { - static readonly ICON_BY_TYPE: Record = { - directory: "folder", - picture: "image", - plaintext: "file-alt", - markdown: "file-alt", - pdf: "file-pdf", - video: "file-video", - audio: "file-audio", - other: "file", - }; +const ICON_BY_TYPE: Record = { + directory: faFolder, + picture: faImage, + plaintext: faFileAlt, + markdown: faFileAlt, + pdf: faFilePdf, + video: faFileVideo, + audio: faFileAudio, + other: faFile, +}; + +// --- +export const useNavigation = () => { // Searches for an item by path from a root item (navigation) - public static searchCurrentItemPath(root: Item, path: string): Item[] { + function searchCurrentItemPath(root: Item, path: string): Item[] { if (path === root.path) return [root]; - if (root.properties.type === ItemType.DIRECTORY && path.startsWith(root.path)) { + if (isDirectory(root) && path.startsWith(root.path)) { const itemChain = root.properties.items - .map(item => this.searchCurrentItemPath(item, path)) + .map(item => searchCurrentItemPath(item, path)) .find(itemChain => itemChain.length > 0); if (itemChain) return [root, ...itemChain]; } @@ -45,47 +49,39 @@ export default class Navigation { } // Normalize a string to lowercase, no-accents - public static normalize(value: string) { + function normalize(value: string) { return value - .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "") + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') .toLowerCase(); } - // Checks if the type of an item matches - public static checkType(item: Item | null, type: ItemType | null): boolean { - return (item?.properties.type ?? null) === type; - } - - public static getLastDirectory(itemPath: Item[]): DirectoryItem { + function getLastDirectory(itemPath: Item[]): DirectoryItem { for (let idx = itemPath.length - 1; idx >= 0; idx--) { const item = itemPath[idx]; - if (Navigation.checkType(item, ItemType.DIRECTORY)) return item as DirectoryItem; + if (isDirectory(item)) return item; } - throw new Error("No directory found"); - } - - // Sort a list of items, moving the directories to the beginning of the list - public static directoriesFirst(items: Item[]) { - return [ - ...items - .filter(child => Navigation.checkType(child, ItemType.DIRECTORY)) - .sort((a, b) => a.title.localeCompare(b.title)), - - ...items.filter(child => !Navigation.checkType(child, ItemType.DIRECTORY)), - ]; + throw new Error('No directory found'); } // Get the icon for an item - public static getIcon(item: Item): string { - if (item.path.length <= 1) return "home"; - return Navigation.ICON_BY_TYPE[item.properties.type]; + function getIcon(item: Item): IconDefinition { + if (item.path.length <= 1) return faHome; + return ICON_BY_TYPE[item.properties.type]; } // Get the file name of an item, without its cache timestamp - public static getFileName(item: Item): string { - if (item.properties.type === ItemType.DIRECTORY) return item.title; - const timeStamped = item.properties.resource.split("/").pop() ?? ""; - return timeStamped.split("?")[0]; + function getFileName(item: Item): string { + if (isDirectory(item)) return item.title; + const timeStamped = (item as DownloadableItem).properties.resource.split('/').pop() ?? ''; + return timeStamped.split('?')[0]; } -} + + return { + searchCurrentItemPath, + normalize, + getLastDirectory, + getIcon, + getFileName, + }; +}; -- cgit v1.2.3