aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/components')
-rw-r--r--viewer/src/components/LdKeyPress.vue49
-rw-r--r--viewer/src/components/LdProposition.vue46
-rw-r--r--viewer/src/components/LdTagInput.vue1
3 files changed, 78 insertions, 18 deletions
diff --git a/viewer/src/components/LdKeyPress.vue b/viewer/src/components/LdKeyPress.vue
new file mode 100644
index 0000000..8276607
--- /dev/null
+++ b/viewer/src/components/LdKeyPress.vue
@@ -0,0 +1,49 @@
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<script lang="ts">
21import { Component, Vue, Prop, Emit } from "vue-property-decorator";
22
23@Component
24export default class LdKeyPress extends Vue {
25 @Prop({ type: Number, required: true }) readonly keycode!: number;
26 @Prop({ type: String, default: "keyup" }) readonly event!: "keyup" | "keydown" | "keypress";
27
28 mounted() {
29 window.addEventListener(this.event, this.onEvent);
30 }
31
32 destroyed() {
33 window.removeEventListener(this.event, this.onEvent);
34 }
35
36 render() {
37 return null;
38 }
39
40 private onEvent(e: KeyboardEvent) {
41 if (e.keyCode === this.keycode) this.action(e);
42 }
43
44 @Emit()
45 private action(e: KeyboardEvent) {
46 return e;
47 }
48}
49</script> \ No newline at end of file
diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue
index 9a32e0a..02f7fe4 100644
--- a/viewer/src/components/LdProposition.vue
+++ b/viewer/src/components/LdProposition.vue
@@ -20,11 +20,17 @@
20<template> 20<template>
21 <div> 21 <div>
22 <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition"> 22 <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition">
23 <fa-icon icon="minus" @click="add(Operation.SUBSTRACTION, proposed.rawTag)" /> 23 <div class="operation-btns link" @click="add(Operation.SUBSTRACTION, proposed.rawTag)">
24 <span 24 <fa-icon icon="minus" />
25 </div>
26 <div class="operation-btns link" @click="add(Operation.ADDITION, proposed.rawTag)">
27 <fa-icon icon="plus" />
28 </div>
29 <div
30 class="operation-tag link"
25 @click="add(Operation.INTERSECTION, proposed.rawTag)" 31 @click="add(Operation.INTERSECTION, proposed.rawTag)"
26 >{{proposed.rawTag}}&nbsp;x{{proposed.count}}</span> 32 >{{proposed.rawTag}}</div>
27 <fa-icon icon="plus" @click="add(Operation.ADDITION, proposed.rawTag)" /> 33 <div class="disabled">x{{proposed.count}}</div>
28 </div> 34 </div>
29 </div> 35 </div>
30</template> 36</template>
@@ -51,13 +57,12 @@ export default class LdTagInput extends Vue {
51 .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1)); 57 .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1));
52 } else { 58 } else {
53 // Tags count from the whole gallery 59 // Tags count from the whole gallery
54 Object.entries(this.$galleryStore.tags) 60 Object.entries(this.$galleryStore.tags).forEach(entry => (propositions[entry[0]] = entry[1].items.length));
55 .forEach(entry => (propositions[entry[0]] = entry[1].items.length));
56 } 61 }
57 62
58 return Object.entries(propositions) 63 return Object.entries(propositions)
59 .sort((a,b) => b[1] - a[1]) 64 .sort((a, b) => b[1] - a[1])
60 .map(entry => ({rawTag: entry[0], count: entry[1]})); 65 .map(entry => ({ rawTag: entry[0], count: entry[1] }));
61 } 66 }
62 67
63 extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] { 68 extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] {
@@ -73,21 +78,28 @@ export default class LdTagInput extends Vue {
73 const node = this.$galleryStore.tags[rawTag]; 78 const node = this.$galleryStore.tags[rawTag];
74 const search: Tag.Search = { ...node, operation, display: `${operation}${node.tag}` }; 79 const search: Tag.Search = { ...node, operation, display: `${operation}${node.tag}` };
75 this.$uiStore.currentTags.push(search); 80 this.$uiStore.currentTags.push(search);
76 this.$uiStore.mode = "search"; 81 setTimeout(() => this.$uiStore.setModeSearch()); // Give time for the UI to display the Tag change
77 } 82 }
78} 83}
79</script> 84</script>
80 85
81<style lang="scss"> 86<style lang="scss">
87@import "@/assets/scss/theme.scss";
88
82.proposition { 89.proposition {
83 display: flex; 90 display: flex;
84 justify-content: space-between;
85 align-items: center; 91 align-items: center;
86 margin: 10px; 92 padding-right: 7px;
87 color: lightcyan; 93 .operation-tag {
88 cursor: pointer; 94 text-overflow: ellipsis;
89} 95 white-space: nowrap;
90.proposition span { 96 overflow: hidden;
91 padding: 0 10px; 97 flex-grow: 1;
98 cursor: pointer;
99 }
100 .operation-btns {
101 padding: 2px 7px;
102 cursor: pointer;
103 }
92} 104}
93</style> 105</style>
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue
index 7c9981f..ff354c6 100644
--- a/viewer/src/components/LdTagInput.vue
+++ b/viewer/src/components/LdTagInput.vue
@@ -27,7 +27,6 @@
27 :data="filteredTags" 27 :data="filteredTags"
28 field="display" 28 field="display"
29 type="is-black" 29 type="is-black"
30 icon="tag"
31 size="is-medium" 30 size="is-medium"
32 class="panelTagInput" 31 class="panelTagInput"
33 @typing="searchTags" 32 @typing="searchTags"