diff options
Diffstat (limited to 'viewer/src/components')
-rw-r--r-- | viewer/src/components/LdButtonFullscreen.vue | 44 | ||||
-rw-r--r-- | viewer/src/components/LdModeRadio.vue | 41 | ||||
-rw-r--r-- | viewer/src/components/LdProposition.vue | 93 | ||||
-rw-r--r-- | viewer/src/components/LdTagInput.vue | 123 | ||||
-rw-r--r-- | viewer/src/components/index.ts | 41 |
5 files changed, 342 insertions, 0 deletions
diff --git a/viewer/src/components/LdButtonFullscreen.vue b/viewer/src/components/LdButtonFullscreen.vue new file mode 100644 index 0000000..39d59af --- /dev/null +++ b/viewer/src/components/LdButtonFullscreen.vue | |||
@@ -0,0 +1,44 @@ | |||
1 | <!-- ldgallery - A static generator which turns a collection of tagged | ||
2 | -- pictures into a searchable web gallery. | ||
3 | -- | ||
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | ||
5 | -- | ||
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 | ||
8 | -- published by the Free Software Foundation, either version 3 of the | ||
9 | -- License, or (at your option) any later version. | ||
10 | -- | ||
11 | -- This program is distributed in the hope that it will be useful, | ||
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | -- GNU Affero General Public License for more details. | ||
15 | -- | ||
16 | -- You should have received a copy of the GNU Affero General Public License | ||
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
18 | --> | ||
19 | |||
20 | <template> | ||
21 | <fa-icon icon="expand-arrows-alt" class="button-fullscreen" @click="$uiStore.toggleFullscreen()" /> | ||
22 | </template> | ||
23 | |||
24 | <script lang="ts"> | ||
25 | import { Component, Vue } from "vue-property-decorator"; | ||
26 | |||
27 | @Component | ||
28 | export default class LdButtonFullscreen extends Vue {} | ||
29 | </script> | ||
30 | |||
31 | <style lang="scss"> | ||
32 | .button-fullscreen { | ||
33 | position: fixed; | ||
34 | top: 0; | ||
35 | right: 0; | ||
36 | margin: 3px 10px; | ||
37 | opacity: 50%; | ||
38 | font-size: 1.5em; | ||
39 | color: white; | ||
40 | mix-blend-mode: difference; | ||
41 | cursor: pointer; | ||
42 | z-index: 4; | ||
43 | } | ||
44 | </style> | ||
diff --git a/viewer/src/components/LdModeRadio.vue b/viewer/src/components/LdModeRadio.vue new file mode 100644 index 0000000..c1d5702 --- /dev/null +++ b/viewer/src/components/LdModeRadio.vue | |||
@@ -0,0 +1,41 @@ | |||
1 | <!-- ldgallery - A static generator which turns a collection of tagged | ||
2 | -- pictures into a searchable web gallery. | ||
3 | -- | ||
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | ||
5 | -- | ||
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 | ||
8 | -- published by the Free Software Foundation, either version 3 of the | ||
9 | -- License, or (at your option) any later version. | ||
10 | -- | ||
11 | -- This program is distributed in the hope that it will be useful, | ||
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | -- GNU Affero General Public License for more details. | ||
15 | -- | ||
16 | -- You should have received a copy of the GNU Affero General Public License | ||
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
18 | --> | ||
19 | |||
20 | <template> | ||
21 | <div class="flex"> | ||
22 | <b-radio-button v-model="$uiStore.mode" native-value="navigation" type="is-green"> | ||
23 | <fa-icon icon="folder" /> | ||
24 | <span>{{$t('mode.navigation')}}</span> | ||
25 | </b-radio-button> | ||
26 | <b-radio-button v-model="$uiStore.mode" native-value="search" type="is-purple"> | ||
27 | <fa-icon icon="search" /> | ||
28 | <span>{{$t('mode.search')}}</span> | ||
29 | </b-radio-button> | ||
30 | </div> | ||
31 | </template> | ||
32 | |||
33 | <script lang="ts"> | ||
34 | import { Component, Vue } from "vue-property-decorator"; | ||
35 | |||
36 | @Component | ||
37 | export default class LdModeRadio extends Vue {} | ||
38 | </script> | ||
39 | |||
40 | <style lang="scss"> | ||
41 | </style> | ||
diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue new file mode 100644 index 0000000..9a32e0a --- /dev/null +++ b/viewer/src/components/LdProposition.vue | |||
@@ -0,0 +1,93 @@ | |||
1 | <!-- ldgallery - A static generator which turns a collection of tagged | ||
2 | -- pictures into a searchable web gallery. | ||
3 | -- | ||
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | ||
5 | -- | ||
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 | ||
8 | -- published by the Free Software Foundation, either version 3 of the | ||
9 | -- License, or (at your option) any later version. | ||
10 | -- | ||
11 | -- This program is distributed in the hope that it will be useful, | ||
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | -- GNU Affero General Public License for more details. | ||
15 | -- | ||
16 | -- You should have received a copy of the GNU Affero General Public License | ||
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
18 | --> | ||
19 | |||
20 | <template> | ||
21 | <div> | ||
22 | <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition"> | ||
23 | <fa-icon icon="minus" @click="add(Operation.SUBSTRACTION, proposed.rawTag)" /> | ||
24 | <span | ||
25 | @click="add(Operation.INTERSECTION, proposed.rawTag)" | ||
26 | >{{proposed.rawTag}} x{{proposed.count}}</span> | ||
27 | <fa-icon icon="plus" @click="add(Operation.ADDITION, proposed.rawTag)" /> | ||
28 | </div> | ||
29 | </div> | ||
30 | </template> | ||
31 | |||
32 | <script lang="ts"> | ||
33 | import { Component, Vue } from "vue-property-decorator"; | ||
34 | import { Operation } from "@/@types/tag/Operation"; | ||
35 | |||
36 | @Component | ||
37 | export default class LdTagInput extends Vue { | ||
38 | get Operation() { | ||
39 | return Operation; | ||
40 | } | ||
41 | |||
42 | get proposedTags() { | ||
43 | const currentTags = this.$uiStore.currentTags; | ||
44 | let propositions: { [index: string]: number } = {}; | ||
45 | if (currentTags.length > 0) { | ||
46 | // Tags count from current search | ||
47 | this.extractDistinctItems(currentTags) | ||
48 | .flatMap(item => item.tags) | ||
49 | .map(this.rightmost) | ||
50 | .filter(rawTag => !currentTags.find(currentTag => currentTag.tag === rawTag)) | ||
51 | .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1)); | ||
52 | } else { | ||
53 | // Tags count from the whole gallery | ||
54 | Object.entries(this.$galleryStore.tags) | ||
55 | .forEach(entry => (propositions[entry[0]] = entry[1].items.length)); | ||
56 | } | ||
57 | |||
58 | return Object.entries(propositions) | ||
59 | .sort((a,b) => b[1] - a[1]) | ||
60 | .map(entry => ({rawTag: entry[0], count: entry[1]})); | ||
61 | } | ||
62 | |||
63 | extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] { | ||
64 | return [...new Set(currentTags.flatMap(tag => tag.items))]; | ||
65 | } | ||
66 | |||
67 | rightmost(tag: Gallery.RawTag): Gallery.RawTag { | ||
68 | const dot = tag.lastIndexOf("."); | ||
69 | return dot <= 0 ? tag : tag.substr(dot + 1); | ||
70 | } | ||
71 | |||
72 | add(operation: Operation, rawTag: Gallery.RawTag) { | ||
73 | const node = this.$galleryStore.tags[rawTag]; | ||
74 | const search: Tag.Search = { ...node, operation, display: `${operation}${node.tag}` }; | ||
75 | this.$uiStore.currentTags.push(search); | ||
76 | this.$uiStore.mode = "search"; | ||
77 | } | ||
78 | } | ||
79 | </script> | ||
80 | |||
81 | <style lang="scss"> | ||
82 | .proposition { | ||
83 | display: flex; | ||
84 | justify-content: space-between; | ||
85 | align-items: center; | ||
86 | margin: 10px; | ||
87 | color: lightcyan; | ||
88 | cursor: pointer; | ||
89 | } | ||
90 | .proposition span { | ||
91 | padding: 0 10px; | ||
92 | } | ||
93 | </style> | ||
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue new file mode 100644 index 0000000..71131e6 --- /dev/null +++ b/viewer/src/components/LdTagInput.vue | |||
@@ -0,0 +1,123 @@ | |||
1 | <!-- ldgallery - A static generator which turns a collection of tagged | ||
2 | -- pictures into a searchable web gallery. | ||
3 | -- | ||
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | ||
5 | -- | ||
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 | ||
8 | -- published by the Free Software Foundation, either version 3 of the | ||
9 | -- License, or (at your option) any later version. | ||
10 | -- | ||
11 | -- This program is distributed in the hope that it will be useful, | ||
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | -- GNU Affero General Public License for more details. | ||
15 | -- | ||
16 | -- You should have received a copy of the GNU Affero General Public License | ||
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
18 | --> | ||
19 | |||
20 | <template> | ||
21 | <b-taginput | ||
22 | v-model="$uiStore.currentTags" | ||
23 | :placeholder="$t('tagInput.placeholder')" | ||
24 | autocomplete | ||
25 | ellipsis | ||
26 | attached | ||
27 | :data="filteredTags" | ||
28 | field="display" | ||
29 | type="is-black" | ||
30 | icon="tag" | ||
31 | size="is-medium" | ||
32 | class="panelTagInput" | ||
33 | @typing="searchTags" | ||
34 | @add="onAdd" | ||
35 | @remove="onRemove" | ||
36 | > | ||
37 | <template slot-scope="props">{{displayOption(props.option)}}</template> | ||
38 | <template slot="empty">{{$t('tagInput.nomatch')}}</template> | ||
39 | </b-taginput> | ||
40 | </template> | ||