diff options
Diffstat (limited to 'viewer/src/services/navigation.ts')
-rw-r--r-- | viewer/src/services/navigation.ts | 90 |
1 files changed, 43 insertions, 47 deletions
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 @@ | |||
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,27 +17,31 @@ | |||
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 | ||
20 | import { DirectoryItem, Item } from "@/@types/gallery"; | 20 | import { DirectoryItem, DownloadableItem, Item } from '@/@types/gallery'; |
21 | import { ItemType } from "@/@types/ItemType"; | 21 | import { ItemType } from '@/@types/itemType'; |
22 | import { faFile, faFileAlt, faFileAudio, faFilePdf, faFileVideo, faFolder, faHome, faImage, IconDefinition } from '@fortawesome/free-solid-svg-icons'; | ||
23 | import { isDirectory } from './itemGuards'; | ||
22 | 24 | ||
23 | export default class Navigation { | 25 | const ICON_BY_TYPE: Record<ItemType, IconDefinition> = { |
24 | static readonly ICON_BY_TYPE: Record<ItemType, string> = { | 26 | directory: faFolder, |
25 | directory: "folder", | 27 | picture: faImage, |
26 | picture: "image", | 28 | plaintext: faFileAlt, |
27 | plaintext: "file-alt", | 29 | markdown: faFileAlt, |
28 | markdown: "file-alt", | 30 | pdf: faFilePdf, |
29 | pdf: "file-pdf", | 31 | video: faFileVideo, |
30 | video: "file-video", | 32 | audio: faFileAudio, |
31 | audio: "file-audio", | 33 | other: faFile, |
32 | other: "file", | 34 | }; |
33 | }; | 35 | |
36 | // --- | ||
34 | 37 | ||
38 | export const useNavigation = () => { | ||
35 | // Searches for an item by path from a root item (navigation) | 39 | // Searches for an item by path from a root item (navigation) |
36 | public static searchCurrentItemPath(root: Item, path: string): Item[] { | 40 | function searchCurrentItemPath(root: Item, path: string): Item[] { |
37 | if (path === root.path) return [root]; | 41 | if (path === root.path) return [root]; |
38 | if (root.properties.type === ItemType.DIRECTORY && path.startsWith(root.path)) { | 42 | if (isDirectory(root) && path.startsWith(root.path)) { |
39 | const itemChain = root.properties.items | 43 | const itemChain = root.properties.items |
40 | .map(item => this.searchCurrentItemPath(item, path)) | 44 | .map(item => searchCurrentItemPath(item, path)) |
41 | .find(itemChain => itemChain.length > 0); | 45 | .find(itemChain => itemChain.length > 0); |
42 | if (itemChain) return [root, ...itemChain]; | 46 | if (itemChain) return [root, ...itemChain]; |
43 | } | 47 | } |
@@ -45,47 +49,39 @@ export default class Navigation { | |||
45 | } | 49 | } |
46 | 50 | ||
47 | // Normalize a string to lowercase, no-accents | 51 | // Normalize a string to lowercase, no-accents |
48 | public static normalize(value: string) { | 52 | function normalize(value: string) { |
49 | return value | 53 | return value |
50 | .normalize("NFD") | 54 | .normalize('NFD') |
51 | .replace(/[\u0300-\u036f]/g, "") | 55 | .replace(/[\u0300-\u036f]/g, '') |
52 | .toLowerCase(); | 56 | .toLowerCase(); |
53 | } | 57 | } |
54 | 58 | ||
55 | // Checks if the type of an item matches | 59 | function getLastDirectory(itemPath: Item[]): DirectoryItem { |
56 | public static checkType(item: Item | null, type: ItemType | null): boolean { | ||
57 | return (item?.properties.type ?? null) === type; | ||
58 | } | ||
59 | |||
60 | public static getLastDirectory(itemPath: Item[]): DirectoryItem { | ||
61 | for (let idx = itemPath.length - 1; idx >= 0; idx--) { | 60 | for (let idx = itemPath.length - 1; idx >= 0; idx--) { |
62 | const item = itemPath[idx]; | 61 | const item = itemPath[idx]; |
63 | if (Navigation.checkType(item, ItemType.DIRECTORY)) return item as DirectoryItem; | 62 | if (isDirectory(item)) return item; |
64 | } | 63 | } |
65 | throw new Error("No directory found"); | 64 | throw new Error('No directory found'); |
66 | } | ||
67 | |||
68 | // Sort a list of items, moving the directories to the beginning of the list | ||
69 | public static directoriesFirst(items: Item[]) { | ||
70 | return [ | ||
71 | ...items | ||
72 | .filter(child => Navigation.checkType(child, ItemType.DIRECTORY)) | ||
73 | .sort((a, b) => a.title.localeCompare(b.title)), | ||
74 | |||
75 | ...items.filter(child => !Navigation.checkType(child, ItemType.DIRECTORY)), | ||
76 | ]; | ||
77 | } | 65 | } |
78 | 66 | ||
79 | // Get the icon for an item | 67 | // Get the icon for an item |
80 | public static getIcon(item: Item): string { | 68 | function getIcon(item: Item): IconDefinition { |
81 | if (item.path.length <= 1) return "home"; | 69 | if (item.path.length <= 1) return faHome; |
82 | return Navigation.ICON_BY_TYPE[item.properties.type]; | 70 | return ICON_BY_TYPE[item.properties.type]; |
83 | } | 71 | } |
84 | 72 | ||
85 | // Get the file name of an item, without its cache timestamp | 73 | // Get the file name of an item, without its cache timestamp |
86 | public static getFileName(item: Item): string { | 74 | function getFileName(item: Item): string { |
87 | if (item.properties.type === ItemType.DIRECTORY) return item.title; | 75 | if (isDirectory(item)) return item.title; |
88 | const timeStamped = item.properties.resource.split("/").pop() ?? ""; | 76 | const timeStamped = (item as DownloadableItem).properties.resource.split('/').pop() ?? ''; |
89 | return timeStamped.split("?")[0]; | 77 | return timeStamped.split('?')[0]; |
90 | } | 78 | } |
91 | } | 79 | |
80 | return { | ||
81 | searchCurrentItemPath, | ||
82 | normalize, | ||
83 | getLastDirectory, | ||
84 | getIcon, | ||
85 | getFileName, | ||
86 | }; | ||
87 | }; | ||