From 590d8272d505483f2412c52ecc787c144d802ff6 Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Mon, 3 Jul 2023 17:07:50 -0700 Subject: [PATCH] Implement unclustered photos for recognize (fix #475) Signed-off-by: Varun Patil --- lib/ClustersBackend/RecognizeBackend.php | 2 +- src/components/SelectionManager.vue | 13 ++- src/components/Timeline.vue | 2 +- src/components/modal/FaceMoveModal.vue | 11 +- src/components/top-matter/FaceTopMatter.vue | 116 ++++++++++++++------ src/components/top-matter/TopMatter.vue | 25 +---- src/mixins/GlobalMixin.ts | 6 + src/services/dav/face.ts | 15 ++- src/services/utils/const.ts | 2 + src/types.ts | 13 +-- src/vue-globals.d.ts | 2 + 11 files changed, 125 insertions(+), 82 deletions(-) diff --git a/lib/ClustersBackend/RecognizeBackend.php b/lib/ClustersBackend/RecognizeBackend.php index 5266c8f3..162dc6e2 100644 --- a/lib/ClustersBackend/RecognizeBackend.php +++ b/lib/ClustersBackend/RecognizeBackend.php @@ -94,7 +94,7 @@ class RecognizeBackend extends Backend // Join with cluster $clusterQuery = null; if ('NULL' === $faceName) { - $clusterQuery = $query->expr()->isNull('rfd.cluster_id'); + $clusterQuery = $query->expr()->eq('rfd.cluster_id', $query->expr()->literal(-1)); } else { $nameField = is_numeric($faceName) ? 'rfc.id' : 'rfc.title'; $query->innerJoin('m', 'recognize_face_clusters', 'rfc', $query->expr()->andX( diff --git a/src/components/SelectionManager.vue b/src/components/SelectionManager.vue index fb203f48..0b008fea 100644 --- a/src/components/SelectionManager.vue +++ b/src/components/SelectionManager.vue @@ -201,18 +201,25 @@ export default defineComponent({ if: (self: any) => self.config.albums_enabled && !self.routeIsAlbums, }, { + id: 'face-move', name: t('memories', 'Move to person'), icon: MoveIcon, callback: this.moveSelectionToPerson.bind(this), - if: () => this.$route.name === 'recognize', + if: () => this.routeIsRecognize, }, { name: t('memories', 'Remove from person'), icon: CloseIcon, callback: this.removeSelectionFromPerson.bind(this), - if: () => this.$route.name === 'recognize', + if: () => this.routeIsRecognize && !this.routeIsRecognizeUnassigned, }, ]; + + // Move face-move to start if unassigned faces + if (this.routeIsRecognizeUnassigned) { + const i = this.defaultActions.findIndex((a) => a.id === 'face-move'); + this.defaultActions.unshift(this.defaultActions.splice(i, 1)[0]); + } }, beforeDestroy() { @@ -800,7 +807,7 @@ export default defineComponent({ * Move selected photos to another person */ async moveSelectionToPerson(selection: Selection) { - if (!this.config.show_face_rect) { + if (!this.config.show_face_rect && !this.routeIsRecognizeUnassigned) { showError(this.t('memories', 'You must enable "Mark person in preview" to use this feature')); return; } diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue index bc9c8917..49103305 100644 --- a/src/components/Timeline.vue +++ b/src/components/Timeline.vue @@ -593,7 +593,7 @@ export default defineComponent({ API.DAYS_FILTER(query, filter, `${user}/${name}`); // Face rect - if (this.config.show_face_rect) { + if (this.config.show_face_rect || this.routeIsRecognizeUnassigned) { API.DAYS_FILTER(query, DaysFilterType.FACE_RECT); } } diff --git a/src/components/modal/FaceMoveModal.vue b/src/components/modal/FaceMoveModal.vue index 4ce07797..4c4e733d 100644 --- a/src/components/modal/FaceMoveModal.vue +++ b/src/components/modal/FaceMoveModal.vue @@ -90,16 +90,7 @@ export default defineComponent({ const name = this.$route.params.name || ''; const target = String(face.name || face.cluster_id); - if ( - !confirm( - this.t('memories', 'Are you sure you want to move the selected photos from {name} to {target}?', { - name, - target, - }) - ) - ) { - return; - } + if (!confirm(this.t('memories', 'Move the selected photos to {target}?', { target }))) return; try { this.show = false; diff --git a/src/components/top-matter/FaceTopMatter.vue b/src/components/top-matter/FaceTopMatter.vue index 5a1e41ea..fe441356 100644 --- a/src/components/top-matter/FaceTopMatter.vue +++ b/src/components/top-matter/FaceTopMatter.vue @@ -1,43 +1,54 @@