Set the selected still on Use image instead of an empty Photos card.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-29 15:40:35 -05:00
co-authored by Cursor
parent ba83520923
commit 845ee5bbf6
+54 -18
View File
@@ -232,8 +232,8 @@
class="stage-actions" class="stage-actions"
aria-label="Selected still actions" aria-label="Selected still actions"
> >
<button type="button" @click="applyUseImage">Use image</button> <button type="button" @click="applyUseImage()">Use image</button>
<button type="button" @click="applyUsePrompt">Use prompt</button> <button type="button" @click="applyUsePrompt()">Use prompt</button>
<div class="stage-split"> <div class="stage-split">
<button <button
type="button" type="button"
@@ -895,6 +895,11 @@ function sourceStillIdsOf(item:any){
if(meta.imageBId) push(meta.imageBId) if(meta.imageBId) push(meta.imageBId)
return ids.filter(id=>stillById(id)) return ids.filter(id=>stillById(id))
} }
function resolveActionAsset(item?:any){
// Stage @click handlers pass a MouseEvent as the first arg — never treat events as library assets.
if(item && typeof item.id==='string' && item.id) return item
return selected.value
}
function useImageRole(){ function useImageRole(){
const plan=photosPlanState.value const plan=photosPlanState.value
const filled=(form.photos||[]).filter((p:any)=>p?.stillId) const filled=(form.photos||[]).filter((p:any)=>p?.stillId)
@@ -904,36 +909,61 @@ function useImageRole(){
return plan.defaultRole || 'change' return plan.defaultRole || 'change'
} }
function applyUseImage(item?:any){ function applyUseImage(item?:any){
const asset=item || selected.value const asset=resolveActionAsset(item)
if(!asset||asset.kind==='track')return if(!asset?.id){
uploadMessage.value='Select a still first.'
return
}
if(asset.kind==='track' || asset.kind==='clip'){
uploadMessage.value='Use image needs a still.'
return
}
const stillId=String(asset.id)
if(!stillById(stillId)){
uploadMessage.value='Select a still first.'
return
}
const plan=photosPlanState.value const plan=photosPlanState.value
const role=useImageRole() const role=useImageRole()
if(!plan.show){ // Prefer filling an empty draft card left by + Add photo; never open the picker.
form.photos=[{stillId:asset.id,role}] const emptyIdx=(form.photos||[]).findIndex((p:any)=>!p?.stillId)
if(emptyIdx>=0){
form.photos[emptyIdx]={stillId,role}
syncPhotosBindings() syncPhotosBindings()
uploadMessage.value=`Added ${assetLabel(asset)} to Photos.` uploadMessage.value=`Added ${assetLabel(asset)} to Photos.`
saveBenchDraft(true) saveBenchDraft(true)
return return
} }
if(form.photos.length>=plan.max){ if(plan.show && !plan.handoffReadonly && (form.photos||[]).length>=plan.max){
form.photos[form.photos.length-1]={stillId:asset.id,role} const changeIdx=(form.photos||[]).findIndex((p:any)=>p?.role==='change')
}else{ if(changeIdx>=0){
form.photos.push({stillId:asset.id,role}) form.photos[changeIdx]={stillId,role:'change'}
syncPhotosBindings()
uploadMessage.value=`Replaced Photos card with ${assetLabel(asset)}.`
saveBenchDraft(true)
return
}
uploadMessage.value='Photos full.'
return
} }
form.photos.push({stillId,role})
syncPhotosBindings() syncPhotosBindings()
uploadMessage.value=`Added ${assetLabel(asset)} to Photos.` uploadMessage.value=`Added ${assetLabel(asset)} to Photos.`
saveBenchDraft(true) saveBenchDraft(true)
} }
function applyUsePrompt(item?:any){ function applyUsePrompt(item?:any){
const asset=item || selected.value const asset=resolveActionAsset(item)
if(!asset)return if(!asset){
uploadMessage.value='Select a still first.'
return
}
const text=usedPromptOf(asset) const text=usedPromptOf(asset)
form.promptSections.action=text form.promptSections.action=text
uploadMessage.value=text?'Prompt set from this item.':'No Used prompt on this item.' uploadMessage.value=text?'Prompt set from this item.':'No Used prompt on this item.'
saveBenchDraft(true) saveBenchDraft(true)
} }
async function copySelectedPrompt(item?:any){ async function copySelectedPrompt(item?:any){
const asset=item || selected.value const asset=resolveActionAsset(item)
const text=usedPromptOf(asset) const text=usedPromptOf(asset)
try{ try{
if(import.meta.client && navigator.clipboard)await navigator.clipboard.writeText(String(text||'')) if(import.meta.client && navigator.clipboard)await navigator.clipboard.writeText(String(text||''))
@@ -941,7 +971,7 @@ async function copySelectedPrompt(item?:any){
}catch{error.value='Could not copy prompt.'} }catch{error.value='Could not copy prompt.'}
} }
async function copySelectedRawPrompt(item?:any){ async function copySelectedRawPrompt(item?:any){
const asset=item || selected.value const asset=resolveActionAsset(item)
const raw=rawPromptOf(asset) const raw=rawPromptOf(asset)
const used=usedPromptOf(asset) const used=usedPromptOf(asset)
const text=raw || used const text=raw || used
@@ -961,8 +991,11 @@ function loadInputPhotos(ids:string[]){
syncPhotosBindings() syncPhotosBindings()
} }
function loadInputUsed(item?:any){ function loadInputUsed(item?:any){
const asset=item || selected.value const asset=resolveActionAsset(item)
if(!asset)return if(!asset){
uploadMessage.value='Select a still first.'
return
}
const ids=sourceStillIdsOf(asset) const ids=sourceStillIdsOf(asset)
const text=usedPromptOf(asset) const text=usedPromptOf(asset)
if(ids.length) loadInputPhotos(ids) if(ids.length) loadInputPhotos(ids)
@@ -973,8 +1006,11 @@ function loadInputUsed(item?:any){
saveBenchDraft(true) saveBenchDraft(true)
} }
function loadInputRaw(item?:any){ function loadInputRaw(item?:any){
const asset=item || selected.value const asset=resolveActionAsset(item)
if(!asset)return if(!asset){
uploadMessage.value='Select a still first.'
return
}
const ids=sourceStillIdsOf(asset) const ids=sourceStillIdsOf(asset)
const raw=rawPromptOf(asset) const raw=rawPromptOf(asset)
const used=usedPromptOf(asset) const used=usedPromptOf(asset)