From a681accaa7617892bb7c53248aa9030a4eb47f50 Mon Sep 17 00:00:00 2001
From: Zero~Informatique
Date: Sat, 28 Dec 2019 04:52:30 +0100
Subject: viewer: Tag propositions. Disabled directory indexation. Note: The
 propositions are not based on the current search results, but on the searched
 tags, which doesn't seem to be the correct way. We'll probably have to move
 the search results to a store for global visibility.

---
 viewer/src/components/LdProposition.vue | 75 +++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)
 create mode 100644 viewer/src/components/LdProposition.vue

(limited to 'viewer/src/components/LdProposition.vue')

diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue
new file mode 100644
index 0000000..b23c14a
--- /dev/null
+++ b/viewer/src/components/LdProposition.vue
@@ -0,0 +1,75 @@
+<template>
+  <div>
+    <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition">
+      <fa-icon icon="minus" @click="add(Operation.SUBSTRACTION, proposed.rawTag)" />
+      <span
+        @click="add(Operation.INTERSECTION, proposed.rawTag)"
+      >{{proposed.rawTag}}&nbsp;x{{proposed.count}}</span>
+      <fa-icon icon="plus" @click="add(Operation.ADDITION, proposed.rawTag)" />
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Vue } from "vue-property-decorator";
+import { Operation } from "@/@types/tag/Operation";
+import Gallery from '../views/Gallery.vue';
+
+@Component
+export default class LdTagInput extends Vue {
+  get Operation() {
+    return Operation;
+  }
+
+  get proposedTags() {
+    const currentTags = this.$uiStore.currentTags;
+    let propositions: { [index: string]: number } = {};
+    if (currentTags.length > 0) {
+      // Tags count from current search
+      this.extractDistinctItems(currentTags)
+        .flatMap(item => item.tags)
+        .map(this.rightmost)
+        .filter(rawTag => !currentTags.find(currentTag => currentTag.tag === rawTag))
+        .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1));
+    } else {
+      // Tags count from the whole gallery
+      Object.entries(this.$galleryStore.tags)
+        .forEach(entry => (propositions[entry[0]] = entry[1].items.length));
+    }
+    
+    return Object.entries(propositions)
+      .sort((a,b) => b[1] - a[1])
+      .map(entry => ({rawTag: entry[0], count: entry[1]}));
+  }
+
+  extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] {
+    return [...new Set(currentTags.flatMap(tag => tag.items))];
+  }
+
+  rightmost(tag: Gallery.RawTag): Gallery.RawTag {
+    const dot = tag.lastIndexOf(".");
+    return dot <= 0 ? tag : tag.substr(dot + 1);
+  }
+
+  add(operation: Operation, rawTag: Gallery.RawTag) {
+    const node = this.$galleryStore.tags[rawTag];
+    const search: Tag.Search = { ...node, operation, display: `${operation}${node.tag}` };
+    this.$uiStore.currentTags.push(search);
+    this.$uiStore.mode = "search";
+  }
+}
+</script>
+
+<style lang="scss">
+.proposition {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin: 10px;
+  color: lightcyan;
+  cursor: pointer;
+}
+.proposition span {
+  padding: 0 10px;
+}
+</style>
-- 
cgit v1.2.3


From 89bcb2dbe5b5e6eb8e8ba13ceecee2770dfe4cd4 Mon Sep 17 00:00:00 2001
From: Zero~Informatique
Date: Thu, 9 Jan 2020 02:10:35 +0100
Subject: viewer: Changed "image" type to "picture". Adapted the code to the
 current compiler output format. The currentItem and currentPath are
 calculated in the store for easier multi-component access. Breadcrumb for
 current's position and navigation.

---
 viewer/src/components/LdProposition.vue | 1 -
 1 file changed, 1 deletion(-)

(limited to 'viewer/src/components/LdProposition.vue')

diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue
index b23c14a..9e8d9dd 100644
--- a/viewer/src/components/LdProposition.vue
+++ b/viewer/src/components/LdProposition.vue
@@ -13,7 +13,6 @@
 <script lang="ts">
 import { Component, Vue } from "vue-property-decorator";
 import { Operation } from "@/@types/tag/Operation";
-import Gallery from '../views/Gallery.vue';
 
 @Component
 export default class LdTagInput extends Vue {
-- 
cgit v1.2.3


From 27b51018525dbb7a6edb3073819d82245387ddd3 Mon Sep 17 00:00:00 2001
From: Zero~Informatique
Date: Fri, 10 Jan 2020 22:22:22 +0100
Subject: viewer: license headers

---
 viewer/src/components/LdProposition.vue | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

(limited to 'viewer/src/components/LdProposition.vue')

diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue
index 9e8d9dd..9a32e0a 100644
--- a/viewer/src/components/LdProposition.vue
+++ b/viewer/src/components/LdProposition.vue
@@ -1,3 +1,22 @@
+<!-- ldgallery - A static generator which turns a collection of tagged
+--             pictures into a searchable web gallery.
+--
+-- Copyright (C) 2019-2020  Guillaume FOUET
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Affero General Public License as
+-- published by the Free Software Foundation, either version 3 of the
+-- License, or (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Affero General Public License for more details.
+--
+-- You should have received a copy of the GNU Affero General Public License
+-- along with this program.  If not, see <https://www.gnu.org/licenses/>.
+-->
+
 <template>
   <div>
     <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition">
-- 
cgit v1.2.3