-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
Copy pathalbum-card-group.svelte
89 lines (81 loc) · 2.92 KB
/
album-card-group.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<script lang="ts">
import { flip } from 'svelte/animate';
import { slide } from 'svelte/transition';
import { AppRoute } from '$lib/constants';
import type { AlbumResponseDto } from '@immich/sdk';
import { albumViewSettings } from '$lib/stores/preferences.store';
import type { ContextMenuPosition } from '$lib/utils/context-menu';
import { type AlbumGroup, isAlbumGroupCollapsed, toggleAlbumGroupCollapsing } from '$lib/utils/album-utils';
import { mdiChevronRight } from '@mdi/js';
import AlbumCard from '$lib/components/album-page/album-card.svelte';
import Icon from '$lib/components/elements/icon.svelte';
import { t } from 'svelte-i18n';
interface Props {
albums: AlbumResponseDto[];
group?: AlbumGroup | undefined;
showOwner?: boolean;
showDateRange?: boolean;
showItemCount?: boolean;
onShowContextMenu?: ((position: ContextMenuPosition, album: AlbumResponseDto) => unknown) | undefined;
}
let {
albums,
group = undefined,
showOwner = false,
showDateRange = false,
showItemCount = false,
onShowContextMenu = undefined,
}: Props = $props();
let isCollapsed = $derived(!!group && isAlbumGroupCollapsed($albumViewSettings, group.id));
const showContextMenu = (position: ContextMenuPosition, album: AlbumResponseDto) => {
onShowContextMenu?.(position, album);
};
let iconRotation = $derived(isCollapsed ? 'rotate-0' : 'rotate-90');
const oncontextmenu = (event: MouseEvent, album: AlbumResponseDto) => {
event.preventDefault();
showContextMenu({ x: event.x, y: event.y }, album);
};
</script>
{#if group}
<div class="grid">
<button
type="button"
onclick={() => toggleAlbumGroupCollapsing(group.id)}
class="w-fit mt-2 pt-2 pr-2 mb-2 dark:text-immich-dark-fg"
aria-expanded={!isCollapsed}
>
<Icon
path={mdiChevronRight}
size="24"
class="inline-block -mt-2.5 transition-all duration-[250ms] {iconRotation}"
/>
<span class="font-bold text-3xl text-black dark:text-white">{group.name}</span>
<span class="ml-1.5">({$t('albums_count', { values: { count: albums.length } })})</span>
</button>
<hr class="dark:border-immich-dark-gray" />
</div>
{/if}
<div class="mt-4">
{#if !isCollapsed}
<div class="flex flex-wrap" transition:slide={{ duration: 300 }}>
{#each albums as album, index (album.id)}
<a
class="w-[250px]"
data-sveltekit-preload-data="hover"
href="{AppRoute.ALBUMS}/{album.id}"
animate:flip={{ duration: 400 }}
oncontextmenu={(event) => oncontextmenu(event, album)}
>
<AlbumCard
{album}
{showOwner}
{showDateRange}
{showItemCount}
preload={index < 20}
onShowContextMenu={onShowContextMenu ? (position) => showContextMenu(position, album) : undefined}
/>
</a>
{/each}
</div>
{/if}
</div>