feat(web): add open in new tab and explicit merge buttons to people thumbnails in merge and reassign pages
parent
287f6d5c94
commit
ea0a7ba881
|
|
@ -33,6 +33,7 @@
|
|||
"add_to_albums": "Add to albums",
|
||||
"add_to_albums_count": "Add to albums ({count})",
|
||||
"add_to_bottom_bar": "Add to",
|
||||
"add_to_merge": "Add to merge",
|
||||
"add_to_shared_album": "Add to shared album",
|
||||
"add_upload_to_stack": "Add upload to stack",
|
||||
"add_url": "Add URL",
|
||||
|
|
@ -1512,6 +1513,7 @@
|
|||
"only_favorites": "Only favorites",
|
||||
"open": "Open",
|
||||
"open_in_map_view": "Open in map view",
|
||||
"open_in_new_tab": "Open in new tab",
|
||||
"open_in_openstreetmap": "Open in OpenStreetMap",
|
||||
"open_the_search_filters": "Open the search filters",
|
||||
"options": "Options",
|
||||
|
|
@ -1709,6 +1711,7 @@
|
|||
"remove_from_lock_folder_action_prompt": "{count} removed from the locked folder",
|
||||
"remove_from_locked_folder": "Remove from locked folder",
|
||||
"remove_from_locked_folder_confirmation": "Are you sure you want to move these photos and videos out of the locked folder? They will be visible in your library.",
|
||||
"remove_from_merge": "Remove from merge",
|
||||
"remove_from_shared_link": "Remove from shared link",
|
||||
"remove_memory": "Remove memory",
|
||||
"remove_photo_from_memory": "Remove photo from this memory",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { getPeopleThumbnailUrl } from '$lib/utils';
|
||||
import { type PersonResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiMinus, mdiOpenInNew, mdiPlus } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
||||
|
||||
interface Props {
|
||||
|
|
@ -22,47 +25,57 @@
|
|||
border = false,
|
||||
onClick = () => {},
|
||||
}: Props = $props();
|
||||
|
||||
const handleAddToMerge = () => {
|
||||
onClick(person);
|
||||
};
|
||||
</script>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="relative rounded-lg transition-all"
|
||||
onclick={() => onClick(person)}
|
||||
disabled={!selectable}
|
||||
style:width={thumbnailSize ? thumbnailSize + 'px' : '100%'}
|
||||
style:height={thumbnailSize ? thumbnailSize + 'px' : '100%'}
|
||||
>
|
||||
<div class="group relative" tabindex={selectable ? 0 : -1} role={selectable ? 'group' : undefined}>
|
||||
<div
|
||||
class="h-full w-full border-2 brightness-90 filter"
|
||||
class:rounded-full={circle}
|
||||
class:rounded-lg={!circle}
|
||||
class:border-transparent={!border}
|
||||
class:dark:border-immich-dark-primary={border}
|
||||
class:border-immich-primary={border}
|
||||
class="relative rounded-lg transition-all"
|
||||
style:width={thumbnailSize ? thumbnailSize + 'px' : '100%'}
|
||||
style:height={thumbnailSize ? thumbnailSize + 'px' : '100%'}
|
||||
>
|
||||
<ImageThumbnail {circle} url={getPeopleThumbnailUrl(person)} altText={person.name} widthStyle="100%" shadow />
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute start-0 top-0 h-full w-full bg-immich-primary/30 opacity-0"
|
||||
class:hover:opacity-100={selectable}
|
||||
class:rounded-full={circle}
|
||||
class:rounded-lg={!circle}
|
||||
></div>
|
||||
|
||||
{#if selected}
|
||||
<div
|
||||
class="absolute start-0 top-0 h-full w-full bg-blue-500/80"
|
||||
class="h-full w-full border-2 brightness-90 filter"
|
||||
class:rounded-full={circle}
|
||||
class:rounded-lg={!circle}
|
||||
></div>
|
||||
{/if}
|
||||
|
||||
{#if person.name}
|
||||
<span
|
||||
class="w-100 text-white-shadow absolute bottom-2 start-0 w-full text-ellipsis px-1 text-center font-medium text-white hover:cursor-pointer"
|
||||
class:border-transparent={!border}
|
||||
class:dark:border-immich-dark-primary={border}
|
||||
class:border-immich-primary={border}
|
||||
>
|
||||
{person.name}
|
||||
</span>
|
||||
<ImageThumbnail {circle} url={getPeopleThumbnailUrl(person)} altText={person.name} widthStyle="100%" shadow />
|
||||
</div>
|
||||
|
||||
{#if person.name}
|
||||
<span
|
||||
class="w-100 text-white-shadow absolute bottom-2 start-0 w-full text-ellipsis px-1 text-center font-medium text-white"
|
||||
>
|
||||
{person.name}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if selectable}
|
||||
<div
|
||||
class="absolute left-1/2 -bottom-6 hidden -translate-x-1/2 gap-2 group-hover:flex group-focus-within:flex [@media(hover:none)]:flex"
|
||||
>
|
||||
<IconButton
|
||||
icon={mdiOpenInNew}
|
||||
href="/people/{person.id}"
|
||||
target="_blank"
|
||||
aria-label={$t('open_in_new_tab')}
|
||||
size="small"
|
||||
color="primary"
|
||||
/>
|
||||
<IconButton
|
||||
icon={selected ? mdiMinus : mdiPlus}
|
||||
onclick={handleAddToMerge}
|
||||
aria-label={selected ? $t('remove_from_merge') : $t('add_to_merge')}
|
||||
size="small"
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -111,7 +111,15 @@
|
|||
<div class="grid grid-flow-col-dense place-content-center place-items-center gap-4">
|
||||
{#each selectedPeople as person (person.id)}
|
||||
<div animate:flip={{ duration: 250, easing: quintOut }}>
|
||||
<FaceThumbnail border circle {person} selectable thumbnailSize={120} onClick={() => onSelect(person)} />
|
||||
<FaceThumbnail
|
||||
border
|
||||
circle
|
||||
{person}
|
||||
selectable
|
||||
selected
|
||||
thumbnailSize={120}
|
||||
onClick={() => onSelect(person)}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@
|
|||
border
|
||||
circle
|
||||
selectable
|
||||
selected
|
||||
thumbnailSize={180}
|
||||
onClick={handleRemoveSelectedPerson}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue