People: Improve naming, merging, and renaming #22 #1557

This commit is contained in:
Michael Mayer 2021-09-29 20:22:41 +02:00
parent 24eff21aa4
commit 2129e73cbf
15 changed files with 1142 additions and 1531 deletions

File diff suppressed because it is too large Load diff

View file

@ -188,6 +188,24 @@ export default class Config {
}
}
getPerson(name) {
name = name.toLowerCase();
const result = this.values.people.filter((m) => m.Name.toLowerCase() === name);
const l = result ? result.length : 0;
if (l === 0) {
return null;
} else if (l === 1) {
return result[0];
} else {
if (this.debug) {
console.warn("more than one person matching the same name", result);
}
return result[0];
}
}
onCount(ev, data) {
const type = ev.split(".")[1];

View file

@ -39,6 +39,7 @@ import PFileDeleteDialog from "./file/delete.vue";
import PAlbumEditDialog from "./album/edit.vue";
import PAlbumDeleteDialog from "./album/delete.vue";
import PLabelDeleteDialog from "./label/delete.vue";
import PPeopleMergeDialog from "./people/merge.vue";
import PUploadDialog from "./upload.vue";
import PVideoViewer from "./video/viewer.vue";
import PShareDialog from "./share.vue";
@ -61,6 +62,7 @@ dialogs.install = (Vue) => {
Vue.component("PAlbumEditDialog", PAlbumEditDialog);
Vue.component("PAlbumDeleteDialog", PAlbumDeleteDialog);
Vue.component("PLabelDeleteDialog", PLabelDeleteDialog);
Vue.component("PPeopleMergeDialog", PPeopleMergeDialog);
Vue.component("PUploadDialog", PUploadDialog);
Vue.component("PVideoViewer", PVideoViewer);
Vue.component("PShareDialog", PShareDialog);

View file

@ -0,0 +1,65 @@
<template>
<v-dialog v-model="show" lazy persistent max-width="350" class="p-people-merge-dialog" @keydown.esc="cancel">
<v-card raised elevation="24">
<v-container fluid class="pb-2 pr-2 pl-2">
<v-layout row wrap>
<v-flex xs3 text-xs-center>
<v-icon size="54" color="secondary-dark lighten-1">people</v-icon>
</v-flex>
<v-flex xs9 text-xs-left align-self-center>
<div class="subheading pr-1">
{{ prompt }}
</div>
</v-flex>
<v-flex xs12 text-xs-right class="pt-3">
<v-btn depressed color="secondary-light" class="action-cancel" @click.stop="cancel">
<translate key="No">No</translate>
</v-btn>
<v-btn color="primary-button" depressed dark class="action-confirm"
@click.stop="confirm">
<translate key="Yes">Yes</translate>
</v-btn>
</v-flex>
</v-layout>
</v-container>
</v-card>
</v-dialog>
</template>
<script>
import Subject from "model/subject";
export default {
name: 'PPeopleMergeDialog',
props: {
show: Boolean,
subj1: {
type: Object,
default: new Subject(),
},
subj2: {
type: Object,
default: new Subject(),
},
},
data() {
return {};
},
computed: {
prompt() {
if (!this.subj1 || !this.subj2) {
return "";
}
return this.$gettextInterpolate(this.$gettext("Merge %{a} with %{b}?"), {a: this.subj1.originalValue("Name"), b: this.subj2.Name});
},
},
methods: {
cancel() {
this.$emit('cancel');
},
confirm() {
this.$emit('confirm');
},
}
};
</script>

View file

@ -53,6 +53,7 @@
v-model="marker.Name"
:rules="[textRule]"
:disabled="busy"
:readonly="true"
browser-autocomplete="off"
class="input-name pa-0 ma-0"
hide-details

Binary file not shown.

View file

@ -37,7 +37,7 @@ msgstr "%{n} Ordner gefunden"
msgid "%{n} labels found"
msgstr "%{n} Kategorien gefunden"
#: src/pages/people/faces.vue:357 src/pages/people/subjects.vue:348
#: src/pages/people/faces.vue:364 src/pages/people/subjects.vue:389
msgid "%{n} people found"
msgstr "%{n} Personen gefunden"
@ -184,7 +184,7 @@ msgstr "Alle %{n} Einträge werden angezeigt"
msgid "All %{n} labels loaded"
msgstr "Alle %{n} Kategorien werden angezeigt"
#: src/pages/people/faces.vue:264 src/pages/people/subjects.vue:255
#: src/pages/people/faces.vue:271 src/pages/people/subjects.vue:296
msgid "All %{n} people loaded"
msgstr "Alle %{n} Personen geladen"
@ -330,7 +330,7 @@ msgstr ""
msgid "Automatically creates albums of special moments, trips, and places."
msgstr "Erstellt automatisch Alben mit besonderen Momenten, Reisen und Orten."
#: src/pages/people/subjects.vue:351
#: src/pages/people/subjects.vue:352
msgid "Bio"
msgstr "Biographie"
@ -393,9 +393,9 @@ msgstr "Limit erreicht, bitte Suche eingrenzen"
#: src/common/clipboard.js:105 src/common/clipboard.js:142
#: src/pages/albums.vue:387 src/pages/albums.vue:403 src/pages/labels.vue:182
#: src/pages/labels.vue:198 src/pages/library/files.vue:193
#: src/pages/library/files.vue:209 src/pages/people/faces.vue:200
#: src/pages/people/faces.vue:216 src/pages/people/subjects.vue:191
#: src/pages/people/subjects.vue:207 src/share/albums.vue:345
#: src/pages/library/files.vue:209 src/pages/people/faces.vue:207
#: src/pages/people/faces.vue:223 src/pages/people/subjects.vue:232
#: src/pages/people/subjects.vue:248 src/share/albums.vue:345
#: src/share/albums.vue:361
msgid "Can't select more items"
msgstr "Maximale Anzahl wurde selektiert"
@ -1302,6 +1302,10 @@ msgstr "Bildbereich"
msgid "Medium"
msgstr "Mittel"
#: src/dialog/people/merge.vue:25
msgid "Merge %{a} with %{b}?"
msgstr "%{a} und %{b} zusammenfassen?"
#: src/pages/about/feedback.vue:27
msgid "Message sent"
msgstr "Nachricht versendet"
@ -1335,7 +1339,7 @@ msgstr "Moonlight"
msgid "More than 20 albums found"
msgstr "Mehr als 20 Alben gefunden"
#: src/pages/people/faces.vue:360
#: src/pages/people/faces.vue:367
msgid "More than 20 faces found"
msgstr "Mehr als 20 Gesichter gefunden"
@ -1343,7 +1347,7 @@ msgstr "Mehr als 20 Gesichter gefunden"
msgid "More than 20 labels found"
msgstr "Mehr als 20 Labels gefunden"
#: src/pages/people/subjects.vue:351
#: src/pages/people/subjects.vue:392
msgid "More than 20 people found"
msgstr "Mehr als 20 Personen gefunden"
@ -1373,19 +1377,19 @@ msgstr "Dateien verschieben"
#: src/dialog/album/edit.vue:106 src/dialog/photo/files.vue:70
#: src/dialog/photo/files.vue:67 src/dialog/photo/files.vue:30
#: src/dialog/photo/info.vue:31 src/dialog/photo/labels.vue:48
#: src/dialog/photo/people.vue:18 src/dialog/photo/people.vue:228
#: src/dialog/photo/people.vue:19 src/dialog/photo/people.vue:229
#: src/pages/about/feedback.vue:144 src/pages/labels.vue:337
#: src/pages/login.vue:73 src/pages/people/faces.vue:46
#: src/pages/people/faces.vue:312 src/pages/people/subjects.vue:314
#: src/pages/login.vue:73 src/pages/people/faces.vue:47
#: src/pages/people/faces.vue:310 src/pages/people/subjects.vue:315
#: src/share/photo/cards.vue:30 src/share/photo/list.vue:34
#: src/share/photo/list.vue:216
msgid "Name"
msgstr "Name"
#: src/component/album/toolbar.vue:52 src/dialog/album/edit.vue:24
#: src/dialog/photo/labels.vue:22 src/dialog/photo/people.vue:21
#: src/dialog/photo/labels.vue:22 src/dialog/photo/people.vue:22
#: src/pages/labels.vue:38 src/pages/library/files.vue:40
#: src/pages/people/faces.vue:40 src/pages/people/subjects.vue:39
#: src/pages/people/faces.vue:41 src/pages/people/subjects.vue:40
msgid "Name too long"
msgstr "Name zu lang"
@ -1407,9 +1411,10 @@ msgstr "Neues Passwort"
msgid "Newest first"
msgstr "Neueste zuerst"
#: src/dialog/photo/archive.vue:15 src/dialog/photo/info.vue:284
#: src/dialog/photo/info.vue:305 src/dialog/photo/info.vue:325
#: src/dialog/photo/info.vue:345 src/dialog/photo/info.vue:365
#: src/dialog/people/merge.vue:15 src/dialog/photo/archive.vue:15
#: src/dialog/photo/info.vue:284 src/dialog/photo/info.vue:305
#: src/dialog/photo/info.vue:325 src/dialog/photo/info.vue:345
#: src/dialog/photo/info.vue:365
msgid "No"
msgstr "Nein"
@ -1428,8 +1433,8 @@ msgid "No labels found"
msgstr "Keine Kategorien gefunden"
#: src/dialog/photo/people.vue:5 src/pages/people/faces.vue:23
#: src/pages/people/faces.vue:353 src/pages/people/subjects.vue:26
#: src/pages/people/subjects.vue:344
#: src/pages/people/faces.vue:360 src/pages/people/subjects.vue:26
#: src/pages/people/subjects.vue:385
msgid "No people found"
msgstr "Keine Personen gefunden"
@ -1550,7 +1555,7 @@ msgstr "Ein Ordner gefunden"
msgid "One label found"
msgstr "Eine Kategorie gefunden"
#: src/pages/people/faces.vue:355 src/pages/people/subjects.vue:346
#: src/pages/people/faces.vue:362 src/pages/people/subjects.vue:387
msgid "One person found"
msgstr "Eine Person gefunden"
@ -1826,7 +1831,7 @@ msgstr "Rot"
#: src/component/album/toolbar.vue:54 src/component/photo/toolbar.vue:57
#: src/dialog/reload.vue:15 src/pages/albums.vue:134 src/pages/labels.vue:91
#: src/pages/library/errors.vue:69 src/pages/library/files.vue:100
#: src/pages/people/faces.vue:67 src/pages/people/subjects.vue:97
#: src/pages/people/faces.vue:67 src/pages/people/subjects.vue:98
msgid "Reload"
msgstr "Neu laden"
@ -1909,7 +1914,7 @@ msgstr "Scans"
#: src/component/navigation.vue:4 src/component/navigation.vue:280
#: src/component/photo/toolbar.vue:48 src/pages/albums.vue:109
#: src/pages/labels.vue:81 src/pages/library/errors.vue:60
#: src/pages/people/subjects.vue:80 src/pages/places.vue:30 src/routes.js:107
#: src/pages/people/subjects.vue:81 src/pages/places.vue:30 src/routes.js:107
msgid "Search"
msgstr "Suche"
@ -2166,7 +2171,7 @@ msgstr "Aufgenommen"
msgid "Teal"
msgstr "Blaugrün"
#: src/dialog/photo/details.vue:26 src/pages/people/faces.vue:49
#: src/dialog/photo/details.vue:26 src/pages/people/faces.vue:50
msgid "Text too long"
msgstr "Text ist zu lang"
@ -2446,12 +2451,13 @@ msgstr "Gelb"
msgid "Yellowstone"
msgstr "Yellowstone"
#: src/dialog/photo/archive.vue:18 src/dialog/photo/files.vue:103
#: src/dialog/photo/files.vue:111 src/dialog/photo/files.vue:157
#: src/dialog/photo/files.vue:100 src/dialog/photo/files.vue:108
#: src/dialog/photo/files.vue:154 src/dialog/photo/info.vue:284
#: src/dialog/photo/info.vue:305 src/dialog/photo/info.vue:325
#: src/dialog/photo/info.vue:345 src/dialog/photo/info.vue:365
#: src/dialog/people/merge.vue:18 src/dialog/photo/archive.vue:18
#: src/dialog/photo/files.vue:103 src/dialog/photo/files.vue:111
#: src/dialog/photo/files.vue:157 src/dialog/photo/files.vue:100
#: src/dialog/photo/files.vue:108 src/dialog/photo/files.vue:154
#: src/dialog/photo/info.vue:284 src/dialog/photo/info.vue:305
#: src/dialog/photo/info.vue:325 src/dialog/photo/info.vue:345
#: src/dialog/photo/info.vue:365
msgid "Yes"
msgstr "Ja"

File diff suppressed because one or more lines are too long

View file

@ -36,8 +36,8 @@ msgstr ""
msgid "%{n} labels found"
msgstr ""
#: src/pages/people/faces.vue:357
#: src/pages/people/subjects.vue:348
#: src/pages/people/faces.vue:364
#: src/pages/people/subjects.vue:389
msgid "%{n} people found"
msgstr ""
@ -198,8 +198,8 @@ msgstr ""
msgid "All %{n} labels loaded"
msgstr ""
#: src/pages/people/faces.vue:264
#: src/pages/people/subjects.vue:255
#: src/pages/people/faces.vue:271
#: src/pages/people/subjects.vue:296
msgid "All %{n} people loaded"
msgstr ""
@ -346,7 +346,7 @@ msgstr ""
msgid "Automatically creates albums of special moments, trips, and places."
msgstr ""
#: src/pages/people/subjects.vue:351
#: src/pages/people/subjects.vue:352
msgid "Bio"
msgstr ""
@ -420,10 +420,10 @@ msgstr ""
#: src/pages/labels.vue:198
#: src/pages/library/files.vue:193
#: src/pages/library/files.vue:209
#: src/pages/people/faces.vue:200
#: src/pages/people/faces.vue:216
#: src/pages/people/subjects.vue:191
#: src/pages/people/subjects.vue:207
#: src/pages/people/faces.vue:207
#: src/pages/people/faces.vue:223
#: src/pages/people/subjects.vue:232
#: src/pages/people/subjects.vue:248
#: src/share/albums.vue:345
#: src/share/albums.vue:361
msgid "Can't select more items"
@ -1402,6 +1402,10 @@ msgstr ""
msgid "Medium"
msgstr ""
#: src/dialog/people/merge.vue:25
msgid "Merge %{a} with %{b}?"
msgstr ""
#: src/pages/about/feedback.vue:27
msgid "Message sent"
msgstr ""
@ -1441,7 +1445,7 @@ msgstr ""
msgid "More than 20 albums found"
msgstr ""
#: src/pages/people/faces.vue:360
#: src/pages/people/faces.vue:367
msgid "More than 20 faces found"
msgstr ""
@ -1449,7 +1453,7 @@ msgstr ""
msgid "More than 20 labels found"
msgstr ""
#: src/pages/people/subjects.vue:351
#: src/pages/people/subjects.vue:392
msgid "More than 20 people found"
msgstr ""
@ -1487,14 +1491,14 @@ msgstr ""
#: src/dialog/photo/files.vue:30
#: src/dialog/photo/info.vue:31
#: src/dialog/photo/labels.vue:48
#: src/dialog/photo/people.vue:18
#: src/dialog/photo/people.vue:228
#: src/dialog/photo/people.vue:19
#: src/dialog/photo/people.vue:229
#: src/pages/about/feedback.vue:144
#: src/pages/labels.vue:337
#: src/pages/login.vue:73
#: src/pages/people/faces.vue:46
#: src/pages/people/faces.vue:312
#: src/pages/people/subjects.vue:314
#: src/pages/people/faces.vue:47
#: src/pages/people/faces.vue:310
#: src/pages/people/subjects.vue:315
#: src/share/photo/cards.vue:30
#: src/share/photo/list.vue:34
#: src/share/photo/list.vue:216
@ -1504,11 +1508,11 @@ msgstr ""
#: src/component/album/toolbar.vue:52
#: src/dialog/album/edit.vue:24
#: src/dialog/photo/labels.vue:22
#: src/dialog/photo/people.vue:21
#: src/dialog/photo/people.vue:22
#: src/pages/labels.vue:38
#: src/pages/library/files.vue:40
#: src/pages/people/faces.vue:40
#: src/pages/people/subjects.vue:39
#: src/pages/people/faces.vue:41
#: src/pages/people/subjects.vue:40
msgid "Name too long"
msgstr ""
@ -1532,6 +1536,7 @@ msgstr ""
msgid "Newest first"
msgstr ""
#: src/dialog/people/merge.vue:15
#: src/dialog/photo/archive.vue:15
#: src/dialog/photo/info.vue:284
#: src/dialog/photo/info.vue:305
@ -1561,9 +1566,9 @@ msgstr ""
#: src/dialog/photo/people.vue:5
#: src/pages/people/faces.vue:23
#: src/pages/people/faces.vue:353
#: src/pages/people/faces.vue:360
#: src/pages/people/subjects.vue:26
#: src/pages/people/subjects.vue:344
#: src/pages/people/subjects.vue:385
msgid "No people found"
msgstr ""
@ -1675,8 +1680,8 @@ msgstr ""
msgid "One label found"
msgstr ""
#: src/pages/people/faces.vue:355
#: src/pages/people/subjects.vue:346
#: src/pages/people/faces.vue:362
#: src/pages/people/subjects.vue:387
msgid "One person found"
msgstr ""
@ -1980,7 +1985,7 @@ msgstr ""
#: src/pages/library/errors.vue:69
#: src/pages/library/files.vue:100
#: src/pages/people/faces.vue:67
#: src/pages/people/subjects.vue:97
#: src/pages/people/subjects.vue:98
msgid "Reload"
msgstr ""
@ -2067,7 +2072,7 @@ msgstr ""
#: src/pages/albums.vue:109
#: src/pages/labels.vue:81
#: src/pages/library/errors.vue:60
#: src/pages/people/subjects.vue:80
#: src/pages/people/subjects.vue:81
#: src/pages/places.vue:30
#: src/routes.js:107
msgid "Search"
@ -2340,7 +2345,7 @@ msgid "Teal"
msgstr ""
#: src/dialog/photo/details.vue:26
#: src/pages/people/faces.vue:49
#: src/pages/people/faces.vue:50
msgid "Text too long"
msgstr ""
@ -2643,6 +2648,7 @@ msgstr ""
msgid "Yellowstone"
msgstr ""
#: src/dialog/people/merge.vue:18
#: src/dialog/photo/archive.vue:18
#: src/dialog/photo/files.vue:103
#: src/dialog/photo/files.vue:111

View file

@ -104,7 +104,7 @@ export class Face extends RestModel {
}
static batchSize() {
return 120;
return 24;
}
static getCollectionResource() {

View file

@ -131,7 +131,7 @@ export class Marker extends RestModel {
}
static batchSize() {
return 60;
return 48;
}
static getCollectionResource() {

View file

@ -96,6 +96,16 @@ export class Model {
return result;
}
originalValue(key) {
if (this.__originalValues.hasOwnProperty(key) && key !== "__originalValues") {
return this.__originalValues[key];
} else if (this.hasOwnProperty(key) && key !== "__originalValues") {
return this[key];
}
return null;
}
wasChanged() {
const changed = this.getValues(true);

View file

@ -124,7 +124,7 @@ export class Subject extends RestModel {
}
static batchSize() {
return 480;
return 60;
}
static getCollectionResource() {

View file

@ -74,14 +74,12 @@
v-model="model.Marker.Name"
:rules="[textRule]"
:disabled="busy"
:readonly="false"
browser-autocomplete="off"
class="input-name pa-0 ma-0"
hide-details
single-line
solo-inverted
clearable
clear-icon="eject"
@click:clear="onClearSubject(model.Marker)"
@change="onRename(model.Marker)"
@keyup.enter.native="onRename(model.Marker)"
></v-text-field>
@ -522,11 +520,19 @@ export default {
},
onClearSubject(marker) {
this.busy = true;
marker.clearSubject(marker).finally(() => this.busy = false);
this.$notify.blockUI();
marker.clearSubject(marker).finally(() => {
this.$notify.unblockUI();
this.busy = false;
});
},
onRename(marker) {
this.busy = true;
marker.rename().finally(() => this.busy = false);
this.$notify.blockUI();
marker.rename().finally(() => {
this.$notify.unblockUI();
this.busy = false;
});
},
onUpdate(ev, data) {
if (!this.listen) return;

View file

@ -145,6 +145,8 @@
</v-layout>
</v-container>
</v-container>
<p-people-merge-dialog lazy :show="merge.show" :subj1="merge.subj1" :subj2="merge.subj2" @cancel="onCancelMerge"
@confirm="onMerge"></p-people-merge-dialog>
</div>
</template>
@ -191,6 +193,11 @@ export default {
titleRule: v => v.length <= this.$config.get("clip") || this.$gettext("Name too long"),
input: new Input(),
lastId: "",
merge: {
subj1: null,
subj2: null,
show: false,
}
};
},
watch: {
@ -229,6 +236,38 @@ export default {
}
},
methods: {
onSave(m) {
const existing = this.$config.getPerson(m.Name);
if(!existing) {
m.update();
return;
}
if (existing.UID === m.UID) {
// Name didn't change.
return;
}
this.merge.subj1 = m;
this.merge.subj2 = existing;
this.merge.show = true;
},
onCancelMerge() {
this.merge.show = false;
this.merge.subj1 = null;
this.merge.subj2 = null;
},
onMerge() {
this.merge.show = false;
this.$notify.blockUI();
this.merge.subj1.update().finally(() => {
this.merge.subj1 = null;
this.merge.subj2 = null;
this.$notify.unblockUI();
this.refresh();
});
},
searchCount() {
const offset = parseInt(window.localStorage.getItem("subjects_offset"));
@ -326,9 +365,6 @@ export default {
}
}
},
onSave(m) {
m.update();
},
showAll() {
this.filter.all = "true";
this.updateQuery();