diff options
Diffstat (limited to 'viewer/src/services')
-rw-r--r-- | viewer/src/services/fetchWithCheck.ts | 7 | ||||
-rw-r--r-- | viewer/src/services/indexfactory.ts | 32 | ||||
-rw-r--r-- | viewer/src/services/indexsearch.ts | 24 | ||||
-rw-r--r-- | viewer/src/services/itemComparators.ts | 13 | ||||
-rw-r--r-- | viewer/src/services/ldzoom.ts | 9 | ||||
-rw-r--r-- | viewer/src/services/navigation.ts | 15 |
6 files changed, 56 insertions, 44 deletions
diff --git a/viewer/src/services/fetchWithCheck.ts b/viewer/src/services/fetchWithCheck.ts new file mode 100644 index 0000000..e84e8b6 --- /dev/null +++ b/viewer/src/services/fetchWithCheck.ts | |||
@@ -0,0 +1,7 @@ | |||
1 | export default class FetchWithCheck { | ||
2 | static async get(url: RequestInfo): Promise<Response> { | ||
3 | const response = await fetch(url); | ||
4 | if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`); | ||
5 | return response; | ||
6 | } | ||
7 | } | ||
diff --git a/viewer/src/services/indexfactory.ts b/viewer/src/services/indexfactory.ts index 4b28a60..691a765 100644 --- a/viewer/src/services/indexfactory.ts +++ b/viewer/src/services/indexfactory.ts | |||
@@ -17,19 +17,21 @@ | |||
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 { Operation } from "@/@types/Operation"; | 20 | import { Item, RawTag } from "@/@types/gallery"; |
21 | import { ItemType } from "@/@types/ItemType"; | 21 | import { ItemType } from "@/@types/ItemType"; |
22 | import { Operation } from "@/@types/Operation"; | ||
23 | import { TagCategory, TagIndex, TagNode, TagSearch } from "@/@types/tag"; | ||
22 | import Navigation from "@/services/navigation"; | 24 | import Navigation from "@/services/navigation"; |
23 | 25 | ||
24 | export default class IndexFactory { | 26 | export default class IndexFactory { |
25 | public static generateTags(root: Gallery.Item | null): Tag.Index { | 27 | public static generateTags(root: Item | null): TagIndex { |
26 | const tagsIndex: Tag.Index = {}; | 28 | const tagsIndex: TagIndex = {}; |
27 | if (root) IndexFactory.pushTagsForItem(tagsIndex, root); | 29 | if (root) IndexFactory.pushTagsForItem(tagsIndex, root); |
28 | return tagsIndex; | 30 | return tagsIndex; |
29 | } | 31 | } |
30 | 32 | ||
31 | // Pushes all tags for a root item (and its children) to the index | 33 | // Pushes all tags for a root item (and its children) to the index |
32 | private static pushTagsForItem(tagsIndex: Tag.Index, item: Gallery.Item): void { | 34 | private static pushTagsForItem(tagsIndex: TagIndex, item: Item): void { |
33 | if (item.properties.type === ItemType.DIRECTORY) { | 35 | if (item.properties.type === ItemType.DIRECTORY) { |
34 | item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); | 36 | item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); |
35 | return; // Directories are not indexed | 37 | return; // Directories are not indexed |
@@ -49,7 +51,7 @@ export default class IndexFactory { | |||
49 | } | 51 | } |
50 | } | 52 | } |
51 | 53 | ||
52 | private static pushPartToIndex(index: Tag.Node, part: string, item: Gallery.Item, rootPart: boolean): Tag.Node { | 54 | private static pushPartToIndex(index: TagNode, part: string, item: Item, rootPart: boolean): TagNode { |
53 | if (!index) | 55 | if (!index) |
54 | index = { | 56 | index = { |
55 | tag: part, | 57 | tag: part, |
@@ -68,8 +70,8 @@ export default class IndexFactory { | |||
68 | 70 | ||
69 | // --- | 71 | // --- |
70 | 72 | ||
71 | public static searchTags(tagsIndex: Tag.Index, filter: string, strict: boolean): Tag.Search[] { | 73 | public static searchTags(tagsIndex: TagIndex, filter: string, strict: boolean): TagSearch[] { |
72 | let search: Tag.Search[] = []; | 74 | let search: TagSearch[] = []; |
73 | if (tagsIndex && filter) { | 75 | if (tagsIndex && filter) { |
74 | const operation = IndexFactory.extractOperation(filter); | 76 | const operation = IndexFactory.extractOperation(filter); |
75 | if (operation !== Operation.INTERSECTION) filter = filter.slice(1); | 77 | if (operation !== Operation.INTERSECTION) filter = filter.slice(1); |
@@ -95,12 +97,12 @@ export default class IndexFactory { | |||
95 | } | 97 | } |
96 | 98 | ||
97 | private static searchTagsFromFilterWithCategory( | 99 | private static searchTagsFromFilterWithCategory( |
98 | tagsIndex: Tag.Index, | 100 | tagsIndex: TagIndex, |
99 | operation: Operation, | 101 | operation: Operation, |
100 | category: string, | 102 | category: string, |
101 | disambiguation: string, | 103 | disambiguation: string, |
102 | strict: boolean | 104 | strict: boolean |
103 | ): Tag.Search[] { | 105 | ): TagSearch[] { |
104 | category = Navigation.normalize(category); | 106 | category = Navigation.normalize(category); |
105 | disambiguation = Navigation.normalize(disambiguation); | 107 | disambiguation = Navigation.normalize(disambiguation); |
106 | return Object.values(tagsIndex) | 108 | return Object.values(tagsIndex) |
@@ -113,28 +115,28 @@ export default class IndexFactory { | |||
113 | } | 115 | } |
114 | 116 | ||
115 | private static searchTagsFromFilter( | 117 | private static searchTagsFromFilter( |
116 | tagsIndex: Tag.Index, | 118 | tagsIndex: TagIndex, |
117 | operation: Operation, | 119 | operation: Operation, |
118 | filter: string, | 120 | filter: string, |
119 | strict: boolean | 121 | strict: boolean |
120 | ): Tag.Search[] { | 122 | ): TagSearch[] { |
121 | filter = Navigation.normalize(filter); | 123 | filter = Navigation.normalize(filter); |
122 | return Object.values(tagsIndex) | 124 | return Object.values(tagsIndex) |
123 | .filter(node => IndexFactory.matches(node, filter, strict)) | 125 | .filter(node => IndexFactory.matches(node, filter, strict)) |
124 | .map(node => ({ ...node, operation, display: `${operation}${node.tag}` })); | 126 | .map(node => ({ ...node, operation, display: `${operation}${node.tag}` })); |
125 | } | 127 | } |
126 | 128 | ||
127 | private static matches(node: Tag.Node, filter: string, strict: boolean): boolean { | 129 | private static matches(node: TagNode, filter: string, strict: boolean): boolean { |
128 | if (strict) return node.tagfiltered === filter; | 130 | if (strict) return node.tagfiltered === filter; |
129 | return node.tagfiltered.includes(filter); | 131 | return node.tagfiltered.includes(filter); |
130 | } | 132 | } |
131 | 133 | ||
132 | // --- | 134 | // --- |
133 | 135 | ||
134 | public static generateCategories(tagsIndex: Tag.Index, categoryTags?: Gallery.RawTag[]): Tag.Category[] { | 136 | public static generateCategories(tagsIndex: TagIndex, categoryTags?: RawTag[]): TagCategory[] { |
135 | if (!categoryTags?.length) return [{ tag: "", index: tagsIndex }]; | 137 | if (!categoryTags?.length) return [{ tag: "", index: tagsIndex }]; |
136 | 138 | ||
137 | const tagsCategories: Tag.Category[] = []; | 139 | const tagsCategories: TagCategory[] = []; |
138 | const tagsRemaining = new Map(Object.entries(tagsIndex)); | 140 | const tagsRemaining = new Map(Object.entries(tagsIndex)); |
139 | categoryTags | 141 | categoryTags |
140 | .map(tag => ({ tag, index: tagsIndex[tag]?.children })) | 142 | .map(tag => ({ tag, index: tagsIndex[tag]?.children })) |
@@ -149,7 +151,7 @@ export default class IndexFactory { | |||
149 | return tagsCategories; | 151 | return tagsCategories; |
150 | } | 152 | } |
151 | 153 | ||
152 | private static isDiscriminantTagOnly(tags: Gallery.RawTag[], node: Tag.Node): boolean { | 154 | private static isDiscriminantTagOnly(tags: RawTag[], node: TagNode): boolean { |
153 | return !tags.includes(node.tag) || !node.childPart; | 155 | return !tags.includes(node.tag) || !node.childPart; |
154 | } | 156 | } |
155 | } | 157 | } |
diff --git a/viewer/src/services/indexsearch.ts b/viewer/src/services/indexsearch.ts index 00f8cfc..57bd03c 100644 --- a/viewer/src/services/indexsearch.ts +++ b/viewer/src/services/indexsearch.ts | |||
@@ -17,27 +17,29 @@ | |||
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 { Item } from "@/@types/gallery"; | ||
20 | import { Operation } from "@/@types/Operation"; | 21 | import { Operation } from "@/@types/Operation"; |
22 | import { TagSearch, TagSearchByOperation } from "@/@types/tag"; | ||
21 | 23 | ||
22 | export default class IndexSearch { | 24 | export default class IndexSearch { |
23 | // Results of the search (by tags) | 25 | // Results of the search (by tags) |
24 | public static search(searchTags: Tag.Search[]): Gallery.Item[] { | 26 | public static search(searchTags: TagSearch[]): Item[] { |
25 | const byOperation = this.extractTagsByOperation(searchTags); | 27 | const byOperation = this.extractTagsByOperation(searchTags); |
26 | const intersection = this.extractIntersection(byOperation); | 28 | const intersection = this.extractIntersection(byOperation); |
27 | const substraction = this.extractSubstraction(byOperation); | 29 | const substraction = this.extractSubstraction(byOperation); |
28 | return this.aggregateAll(byOperation, intersection, substraction); | 30 | return this.aggregateAll(byOperation, intersection, substraction); |
29 | } | 31 | } |
30 | 32 | ||
31 | private static extractTagsByOperation(searchTags: Tag.Search[]): Tag.SearchByOperation { | 33 | private static extractTagsByOperation(searchTags: TagSearch[]): TagSearchByOperation { |
32 | const byOperation: Tag.SearchByOperation = {}; | 34 | const byOperation: TagSearchByOperation = {}; |
33 | Object.values(Operation).forEach( | 35 | Object.values(Operation).forEach( |
34 | operation => (byOperation[operation] = searchTags.filter(tag => tag.operation === operation)) | 36 | operation => (byOperation[operation] = searchTags.filter(tag => tag.operation === operation)) |
35 | ); | 37 | ); |
36 | return byOperation; | 38 | return byOperation; |
37 | } | 39 | } |
38 | 40 | ||
39 | private static extractIntersection(byOperation: Tag.SearchByOperation): Set<Gallery.Item> { | 41 | private static extractIntersection(byOperation: TagSearchByOperation): Set<Item> { |
40 | const intersection = new Set<Gallery.Item>(); | 42 | const intersection = new Set<Item>(); |
41 | if (byOperation[Operation.INTERSECTION].length > 0) { | 43 | if (byOperation[Operation.INTERSECTION].length > 0) { |
42 | byOperation[Operation.INTERSECTION] | 44 | byOperation[Operation.INTERSECTION] |
43 | .map(tag => tag.items) | 45 | .map(tag => tag.items) |
@@ -48,8 +50,8 @@ export default class IndexSearch { | |||
48 | return intersection; | 50 | return intersection; |
49 | } | 51 | } |
50 | 52 | ||
51 | private static extractSubstraction(byOperation: Tag.SearchByOperation): Set<Gallery.Item> { | 53 | private static extractSubstraction(byOperation: TagSearchByOperation): Set<Item> { |
52 | const substraction = new Set<Gallery.Item>(); | 54 | const substraction = new Set<Item>(); |
53 | if (byOperation[Operation.SUBSTRACTION].length > 0) { | 55 | if (byOperation[Operation.SUBSTRACTION].length > 0) { |
54 | byOperation[Operation.SUBSTRACTION].flatMap(tag => tag.items).forEach(item => substraction.add(item)); | 56 | byOperation[Operation.SUBSTRACTION].flatMap(tag => tag.items).forEach(item => substraction.add(item)); |
55 | } | 57 | } |
@@ -57,10 +59,10 @@ export default class IndexSearch { | |||
57 | } | 59 | } |
58 | 60 | ||
59 | private static aggregateAll( | 61 | private static aggregateAll( |
60 | byOperation: Tag.SearchByOperation, | 62 | byOperation: TagSearchByOperation, |
61 | intersection: Set<Gallery.Item>, | 63 | intersection: Set<Item>, |
62 | substraction: Set<Gallery.Item> | 64 | substraction: Set<Item> |
63 | ): Gallery.Item[] { | 65 | ): Item[] { |
64 | byOperation[Operation.ADDITION].flatMap(tag => tag.items).forEach(item => intersection.add(item)); | 66 | byOperation[Operation.ADDITION].flatMap(tag => tag.items).forEach(item => intersection.add(item)); |
65 | substraction.forEach(item => intersection.delete(item)); | 67 | substraction.forEach(item => intersection.dele |