From e263bcae43a6a922cb9e3b50d164fea10cc31826 Mon Sep 17 00:00:00 2001 From: oezgueremir Date: Tue, 18 Jun 2024 23:47:14 +0200 Subject: [PATCH 1/4] When watching photos and the info tab (detail-panel) is open, all the faces in the photo are marked. tasks: - [x] the "mark all faces" function can be de-/activated on the info tab. - [x] CircleIconButton mark_all_faces with mdiLabelMultiple icon as controller. - [x] Each person/face has a different, static border color given. This is provided with a little quick'n'dirty solution. A better solution could/would require changes in the DB model... - [x] The mouseover event will override that functionallity and mark only the faces of this single person. More over, it will change the visualization of the marking rectangle to border=white, filling=person/face color, opacity=0.6 - [x] If mark_all_faces is active, the CircleIconButton show_hidden_people will always be available. So you are able to see even hidden and unassigned faces. Hidden and unassigned faces will be visualized, as if the mouseover event is triggered for them. It can be further evaluated, if these two states have to be controlled individually and presented with unique designs. --- .../asset-viewer/detail-panel.svelte | 44 ++++++++++++++++--- .../asset-viewer/photo-viewer.svelte | 4 +- .../faces-page/person-side-panel.svelte | 11 +++-- web/src/lib/i18n/en.json | 1 + web/src/lib/stores/people.store.ts | 24 +++++++++- web/src/lib/utils/people-utils.ts | 13 ++++-- 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index 5414871adbce7..5e13c02961a6d 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -3,7 +3,7 @@ import Icon from '$lib/components/elements/icon.svelte'; import ChangeDate from '$lib/components/shared-components/change-date.svelte'; import { AppRoute, QueryParameter, timeToLoadTheMap } from '$lib/constants'; - import { boundingBoxesArray } from '$lib/stores/people.store'; + import { boundingBoxesArray, createBoundingBoxType, getBorderColor } from '$lib/stores/people.store'; import { locale } from '$lib/stores/preferences.store'; import { featureFlags } from '$lib/stores/server-config.store'; import { user } from '$lib/stores/user.store'; @@ -28,9 +28,11 @@ mdiInformationOutline, mdiPencil, mdiAccountOff, + mdiLabelMultiple, + mdiLabelOff, } from '@mdi/js'; import { DateTime } from 'luxon'; - import { createEventDispatcher, onMount } from 'svelte'; + import { createEventDispatcher, onDestroy, onMount } from 'svelte'; import { slide } from 'svelte/transition'; import { getByteUnitString } from '$lib/utils/byte-units'; import { handleError } from '$lib/utils/handle-error'; @@ -93,7 +95,22 @@ })(); $: people = asset.people || []; + + $: allFaces = markingAllFaces + ? people + .filter((person) => showingHiddenPeople || !person.isHidden) + .flatMap((person) => + person.faces.map((face) => createBoundingBoxType(face, person.id, showingHiddenPeople && person.isHidden)), + ) + .concat(showingHiddenPeople ? unassignedFaces.map((face) => createBoundingBoxType(face, face.id, true)) : []) + : []; + + $: { + $boundingBoxesArray = allFaces || []; + } + $: showingHiddenPeople = false; + $: markingAllFaces = false; $: unassignedFaces = asset.unassignedFaces || []; @@ -105,6 +122,10 @@ }); }); + onDestroy(() => { + $boundingBoxesArray = []; + }); + const dispatch = createEventDispatcher<{ close: void; }>(); @@ -125,6 +146,7 @@ unassignedFaces = data?.unassignedFaces || []; }); showEditFaces = false; + $boundingBoxesArray = allFaces || []; }; const toggleAssetPath = () => (showAssetPath = !showAssetPath); @@ -177,7 +199,7 @@ size="24" /> {/if} - {#if people.some((person) => person.isHidden)} + {#if markingAllFaces || people.some((person) => person.isHidden)} (showingHiddenPeople = !showingHiddenPeople)} /> {/if} + (markingAllFaces = !markingAllFaces)} + /> ($boundingBoxesArray = people[index].faces)} + on:focus={() => + ($boundingBoxesArray = people[index].faces.map((face) => createBoundingBoxType(face, person.id, true)))} on:blur={() => ($boundingBoxesArray = [])} - on:mouseover={() => ($boundingBoxesArray = people[index].faces)} - on:mouseleave={() => ($boundingBoxesArray = [])} + on:mouseover={() => + ($boundingBoxesArray = people[index].faces.map((face) => createBoundingBoxType(face, person.id, true)))} + on:mouseleave={() => ($boundingBoxesArray = allFaces)} >
{#each getBoundingBox($boundingBoxesArray, $photoZoomState, $photoViewer) as boundingbox}
{/each}
diff --git a/web/src/lib/components/faces-page/person-side-panel.svelte b/web/src/lib/components/faces-page/person-side-panel.svelte index a25e30310350e..0e353b86ee0ff 100644 --- a/web/src/lib/components/faces-page/person-side-panel.svelte +++ b/web/src/lib/components/faces-page/person-side-panel.svelte @@ -1,7 +1,7 @@