First crack at the app. Still lots of bugs to squash.
This commit is contained in:
55
src/lib/components/AuthImage.svelte
Normal file
55
src/lib/components/AuthImage.svelte
Normal 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}
|
||||
Reference in New Issue
Block a user