First crack at the app. Still lots of bugs to squash.

This commit is contained in:
2026-05-17 23:30:08 -05:00
parent cfd936e5fa
commit 435481549c
35 changed files with 4029 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
<script lang="ts">
import {apiGetPhotoBlob} from '../api/index'
let { photoId, version = 'MEDIUM', alt = 'Photo', class: cls = '' }: {
photoId: string
version?: 'ORIGINAL' | 'LARGE' | 'MEDIUM' | 'SMALL'
alt?: string
class?: string
} = $props()
let src = $state<string | null>(null)
let error = $state(false)
$effect(() => {
let objectUrl: string | null = null
let cancelled = false
error = false
src = null
async function load(attempt = 0) {
try {
const blob = await apiGetPhotoBlob(photoId, version)
if (cancelled) return
if (objectUrl) URL.revokeObjectURL(objectUrl)
objectUrl = URL.createObjectURL(blob)
src = objectUrl
} catch {
if (cancelled) return
if (attempt < 3) {
await new Promise(r => setTimeout(r, 1500 * (attempt + 1)))
if (!cancelled) load(attempt + 1)
} else {
error = true
}
}
}
load()
return () => {
cancelled = true
if (objectUrl) URL.revokeObjectURL(objectUrl)
}
})
</script>
{#if error}
<div class="bg-base-300 flex items-center justify-center {cls}">
<span class="text-base-content/40 text-sm">No image</span>
</div>
{:else if src}
<img {src} {alt} class={cls} />
{:else}
<div class="bg-base-300 animate-pulse {cls}"></div>
{/if}