Remount stage media on selectedId and show thumb before the archive still.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-29 19:45:51 -05:00
co-authored by Cursor
parent aa0aa871e4
commit ffdaa7ce42
2 changed files with 32 additions and 4 deletions
+31 -3
View File
@@ -286,7 +286,7 @@
</template>
<template v-else-if="selected?.kind==='track'">
<div class="w-full max-w-xl px-6 py-4">
<AudioPlayer :src="`/api/library/tracks/${selected.id}/audio`" :download-name="`${selected.name || 'track'}.${selected.ext || 'wav'}`" :label="selected.name || 'Track'" />
<AudioPlayer :key="selected.id" :src="`/api/library/tracks/${selected.id}/audio`" :download-name="`${selected.name || 'track'}.${selected.ext || 'wav'}`" :label="selected.name || 'Track'" />
</div>
</template>
<template v-else-if="selected?.kind==='clip'">
@@ -300,7 +300,13 @@
/>
</template>
<template v-else-if="selected">
<img :src="stillUrl(selected.id)" alt="Selected still">
<img
:key="selected.id"
:src="stageStillSrc"
alt="Selected still"
decoding="async"
@load="onStageStillLoad"
>
</template>
<template v-else>
<p class="placeholder-still">Open Library to pick a still or clip</p>
@@ -431,7 +437,7 @@
<div class="grid grid-cols-2 gap-3 sm:grid-cols-4 lg:grid-cols-5">
<button v-for="a in pickerAssets" :key="a.id" type="button" class="rounded-[var(--radius)] border border-[var(--line)] p-2 text-left" @click="pickAsset(a)">
<span v-if="pickerThumbHidden(a)" class="flex h-24 items-center text-xs text-[var(--muted)]">Still loaded · preview hidden</span>
<img v-else :src="a.kind==='clip'?'/api/library/clips/'+a.id+'/thumb':stillUrl(a.id)" class="h-24 w-full object-contain" alt="">
<img v-else :src="a.kind==='clip'?'/api/library/clips/'+a.id+'/thumb':stillThumbUrl(a.id)" class="h-24 w-full object-contain" alt="">
<span class="mt-2 block truncate text-xs">{{ assetLabel(a) }}</span>
</button>
</div>
@@ -677,6 +683,25 @@ watch(()=>form.identityStillId,id=>{if(import.meta.client&&form.folderId&&form.e
const stills=computed(()=>library.value.stills.filter((s:any)=>s.folderId===form.folderId))
const clips=computed(()=>library.value.clips.filter((s:any)=>s.folderId===form.folderId))
const stillUrl=(id:string)=>`/api/library/stills/${id}`
const stillThumbUrl=(id:string)=>`/api/library/stills/${id}/thumb`
/** Stage shows thumb first, then swaps to original after decode — never leave the previous still painted. */
const stageStillHiRes=ref(false)
const stageStillSrc=computed(()=>{
const id=selected.value?.id
if(!id || selected.value?.kind==='clip' || selected.value?.kind==='track') return ''
if(isHidden(selected.value)) return ''
return stageStillHiRes.value ? stillUrl(id) : stillThumbUrl(id)
})
function onStageStillLoad(e:Event){
const id=selected.value?.id
if(!id || stageStillHiRes.value) return
const img=e.target as HTMLImageElement
const bump=()=>{ if(selected.value?.id===id) stageStillHiRes.value=true }
if(typeof img.decode==='function') void img.decode().then(bump).catch(bump)
else bump()
}
watch(()=>selected.value?.id,()=>{ stageStillHiRes.value=false })
watch(eyeOpen,()=>{ if(eyeOpen.value) stageStillHiRes.value=false })
const folderJobs=computed(()=>jobs.value.filter(j=>j.request.folderId===form.folderId))
const benchJobs=computed(()=>queueJobs(folderJobs.value))
const musicJobs=computed(()=>studioQueue.value
@@ -1423,6 +1448,9 @@ const mobileCtx=computed(()=>({
loraTriggers:{...loraNames.value.triggers,...library.value.loraTriggers},
aspectOptions,
stillUrl,
stillThumbUrl,
stageStillSrc:stageStillSrc.value,
onStageStillLoad,
isHidden,
slotHidden,
stillById,