Remount stage media on selectedId and show thumb before the archive still.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -286,7 +286,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-else-if="selected?.kind==='track'">
|
<template v-else-if="selected?.kind==='track'">
|
||||||
<div class="w-full max-w-xl px-6 py-4">
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="selected?.kind==='clip'">
|
<template v-else-if="selected?.kind==='clip'">
|
||||||
@@ -300,7 +300,13 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="selected">
|
<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>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<p class="placeholder-still">Open Library to pick a still or clip</p>
|
<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">
|
<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)">
|
<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>
|
<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>
|
<span class="mt-2 block truncate text-xs">{{ assetLabel(a) }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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 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 clips=computed(()=>library.value.clips.filter((s:any)=>s.folderId===form.folderId))
|
||||||
const stillUrl=(id:string)=>`/api/library/stills/${id}`
|
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 folderJobs=computed(()=>jobs.value.filter(j=>j.request.folderId===form.folderId))
|
||||||
const benchJobs=computed(()=>queueJobs(folderJobs.value))
|
const benchJobs=computed(()=>queueJobs(folderJobs.value))
|
||||||
const musicJobs=computed(()=>studioQueue.value
|
const musicJobs=computed(()=>studioQueue.value
|
||||||
@@ -1423,6 +1448,9 @@ const mobileCtx=computed(()=>({
|
|||||||
loraTriggers:{...loraNames.value.triggers,...library.value.loraTriggers},
|
loraTriggers:{...loraNames.value.triggers,...library.value.loraTriggers},
|
||||||
aspectOptions,
|
aspectOptions,
|
||||||
stillUrl,
|
stillUrl,
|
||||||
|
stillThumbUrl,
|
||||||
|
stageStillSrc:stageStillSrc.value,
|
||||||
|
onStageStillLoad,
|
||||||
isHidden,
|
isHidden,
|
||||||
slotHidden,
|
slotHidden,
|
||||||
stillById,
|
stillById,
|
||||||
|
|||||||
@@ -117,7 +117,7 @@
|
|||||||
controls
|
controls
|
||||||
playsinline
|
playsinline
|
||||||
/>
|
/>
|
||||||
<img v-else-if="ctx.selected" :src="ctx.stillUrl(ctx.selected.id)" alt="Selected still">
|
<img v-else-if="ctx.selected" :key="ctx.selected.id" :src="ctx.stageStillSrc || ctx.stillUrl(ctx.selected.id)" alt="Selected still" decoding="async" @load="ctx.onStageStillLoad">
|
||||||
<p v-else class="m-muted">Open Library to pick a still or clip</p>
|
<p v-else class="m-muted">Open Library to pick a still or clip</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user