mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
fix: hide faces (#3352)
* fix: hide faces * remove unused variable * fix: work even if one fails * better style for hidden people * add hide face in the menu dropdown * add buttons to toggle visibility for all faces * add server test * close modal with escape key * fix: explore page * improve show & hide faces modal * keep name on people card * simplify layout * sticky app bar in show-hide page * fix format --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
c40aa4399b
commit
ed64c91da6
25 changed files with 1097 additions and 72 deletions
|
|
@ -15,12 +15,15 @@
|
|||
export let circle = false;
|
||||
export let hidden = false;
|
||||
let complete = false;
|
||||
|
||||
export let eyeColor = 'white';
|
||||
</script>
|
||||
|
||||
<img
|
||||
style:width={widthStyle}
|
||||
style:height={heightStyle}
|
||||
style:filter={hidden ? 'grayscale(75%)' : 'none'}
|
||||
style:filter={hidden ? 'grayscale(50%)' : 'none'}
|
||||
style:opacity={hidden ? '0.5' : '1'}
|
||||
src={url}
|
||||
alt={altText}
|
||||
class="object-cover transition duration-300"
|
||||
|
|
@ -32,9 +35,10 @@
|
|||
use:imageLoad
|
||||
on:image-load|once={() => (complete = true)}
|
||||
/>
|
||||
|
||||
{#if hidden}
|
||||
<div class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform">
|
||||
<EyeOffOutline size="2em" />
|
||||
<EyeOffOutline size="2em" color={eyeColor} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
$: unselectedPeople = people.filter((source) => !selectedPeople.includes(source) && source.id !== person.id);
|
||||
|
||||
onMount(async () => {
|
||||
const { data } = await api.personApi.getAllPeople({ withHidden: true });
|
||||
const { data } = await api.personApi.getAllPeople({ withHidden: false });
|
||||
people = data.people;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -20,17 +20,19 @@
|
|||
const onMergeFacesClicked = () => {
|
||||
dispatch('merge-faces', person);
|
||||
};
|
||||
|
||||
const onHideFaceClicked = () => {
|
||||
dispatch('hide-face', person);
|
||||
};
|
||||
</script>
|
||||
|
||||
<div id="people-card" class="relative">
|
||||
<a href="/people/{person.id}" draggable="false">
|
||||
<div class="w-48 rounded-xl brightness-95 filter">
|
||||
<div class="h-48 w-48 rounded-xl brightness-95 filter">
|
||||
<ImageThumbnail shadow url={api.getPeopleThumbnailUrl(person.id)} altText={person.name} widthStyle="100%" />
|
||||
</div>
|
||||
{#if person.name}
|
||||
<span
|
||||
class="w-100 absolute bottom-2 w-full text-ellipsis px-1 text-center font-medium text-white backdrop-blur-[1px] hover:cursor-pointer"
|
||||
>
|
||||
<span class="absolute bottom-2 left-0 w-full select-text px-1 text-center font-medium text-white">
|
||||
{person.name}
|
||||
</span>
|
||||
{/if}
|
||||
|
|
@ -50,6 +52,7 @@
|
|||
|
||||
{#if showContextMenu}
|
||||
<ContextMenu on:outclick={() => (showContextMenu = false)}>
|
||||
<MenuOption on:click={() => onHideFaceClicked()} text="Hide face" />
|
||||
<MenuOption on:click={() => onChangeNameClicked()} text="Change name" />
|
||||
<MenuOption on:click={() => onMergeFacesClicked()} text="Merge faces" />
|
||||
</ContextMenu>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,19 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { fly } from 'svelte/transition';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import IconButton from '../elements/buttons/icon-button.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import Restart from 'svelte-material-icons/Restart.svelte';
|
||||
import Eye from 'svelte-material-icons/Eye.svelte';
|
||||
import EyeOff from 'svelte-material-icons/EyeOff.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let showLoadingSpinner: boolean;
|
||||
export let toggleVisibility: boolean;
|
||||
</script>
|
||||
|
||||
<section
|
||||
|
|
@ -14,17 +21,30 @@
|
|||
class="absolute left-0 top-0 z-[9999] h-full w-full bg-immich-bg dark:bg-immich-dark-bg"
|
||||
>
|
||||
<div
|
||||
class="absolute flex h-16 w-full place-items-center justify-between border-b dark:border-immich-dark-gray dark:text-immich-dark-fg"
|
||||
class="sticky top-0 z-10 flex h-16 w-full items-center justify-between border-b bg-white p-1 dark:border-immich-dark-gray dark:bg-black dark:text-immich-dark-fg md:p-8"
|
||||
>
|
||||
<div class="flex w-full items-center justify-between p-8">
|
||||
<div class="flex items-center">
|
||||
<CircleIconButton logo={Close} on:click={() => dispatch('closeClick')} />
|
||||
<p class="ml-4">Show & hide faces</p>
|
||||
</div>
|
||||
<IconButton on:click={() => dispatch('doneClick')}>Done</IconButton>
|
||||
<div class="flex items-center">
|
||||
<CircleIconButton logo={Close} on:click={() => dispatch('closeClick')} />
|
||||
<p class="ml-4 hidden sm:block">Show & hide faces</p>
|
||||
</div>
|
||||
<div class="immich-scrollbar absolute top-16 h-[calc(100%-theme(spacing.16))] w-full p-4 pb-8">
|
||||
<slot />
|
||||
<div class="flex items-center justify-end">
|
||||
<div class="flex items-center md:mr-8">
|
||||
<CircleIconButton title="Reset faces visibility" logo={Restart} on:click={() => dispatch('reset-visibility')} />
|
||||
<CircleIconButton
|
||||
title="Toggle visibility"
|
||||
logo={toggleVisibility ? Eye : EyeOff}
|
||||
on:click={() => dispatch('toggle-visibility')}
|
||||
/>
|
||||
</div>
|
||||
{#if !showLoadingSpinner}
|
||||
<IconButton on:click={() => dispatch('doneClick')}>Done</IconButton>
|
||||
{:else}
|
||||
<LoadingSpinner />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex w-full flex-wrap gap-1 bg-immich-bg p-2 pb-8 dark:bg-immich-dark-bg md:px-8 md:pt-4">
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue