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