your personal website on atproto - mirror blento.app
at fix-cached-posts 89 lines 2.3 kB view raw
1<script lang="ts"> 2 import type { Item } from '$lib/types'; 3 import { onMount } from 'svelte'; 4 import { getAdditionalUserData } 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</script> 65 66<div class="photo-gallery-card z-10 flex h-full w-full flex-col gap-4 overflow-y-scroll p-4"> 67 <div class="gallery-compact"> 68 <ImageMasonry images={images ?? []} showNames={false} maxColumns={2} /> 69 </div> 70 <div class="gallery-wide"> 71 <ImageMasonry images={images ?? []} showNames={false} maxColumns={3} /> 72 </div> 73</div> 74 75<style> 76 .gallery-wide { 77 display: none; 78 } 79 80 @container card (width >= 28rem) { 81 .gallery-compact { 82 display: none; 83 } 84 85 .gallery-wide { 86 display: block; 87 } 88 } 89</style>