your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import type { Item } from '$lib/types';
3 import { onMount } from 'svelte';
4 import { getAdditionalUserData, getIsMobile } from '$lib/website/context';
5 import { getCDNImageBlobUrl, parseUri } from '$lib/atproto';
6 import { loadGrainGalleryData } from './helpers';
7
8 import { ImageMasonry } from '@foxui/visual';
9 import { openImageViewer } from '$lib/components/image-viewer/imageViewer.svelte';
10
11 interface PhotoItem {
12 uri: string;
13 value: {
14 photo: { $type: 'blob'; ref: { $link: string } };
15 aspectRatio: { width: number; height: number };
16 position?: number;
17 };
18 }
19
20 let { item }: { item: Item } = $props();
21
22 const data = getAdditionalUserData();
23 // svelte-ignore state_referenced_locally
24 let feed = $state(
25 (data[item.cardType] as Record<string, PhotoItem[]> | undefined)?.[item.cardData.galleryUri]
26 );
27
28 onMount(async () => {
29 if (!feed) {
30 feed = ((await loadGrainGalleryData([item])) as Record<string, PhotoItem[]> | undefined)?.[
31 item.cardData.galleryUri
32 ];
33
34 data[item.cardType] = feed;
35 }
36 });
37
38 let images = $derived(
39 (feed
40 ?.toSorted((a: PhotoItem, b: PhotoItem) => {
41 return (a.value.position ?? 0) - (b.value.position ?? 0);
42 })
43 .map((i: PhotoItem) => {
44 const item = parseUri(i.uri);
45 const src = getCDNImageBlobUrl({ did: item?.repo, blob: i.value.photo });
46 return {
47 src,
48 name: '',
49 width: i.value.aspectRatio.width,
50 height: i.value.aspectRatio.height,
51 position: i.value.position ?? 0,
52 onclick: src ? () => openImageViewer(src) : undefined
53 };
54 })
55 .filter((i) => i.src !== undefined) || []) as {
56 src: string;
57 name: string;
58 width: number;
59 height: number;
60 position: number;
61 onclick?: () => void;
62 }[]
63 );
64
65 let isMobile = getIsMobile();
66</script>
67
68<div class="z-10 flex h-full w-full flex-col gap-4 overflow-y-scroll p-4">
69 <ImageMasonry
70 images={images ?? []}
71 showNames={false}
72 maxColumns={!isMobile() && item.w > 4 ? 3 : 2}
73 />
74</div>