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