Bind the selected output when restoring complete input settings

This commit is contained in:
Towsty
2026-09-11 19:06:17 -05:00
parent ad135ae19c
commit ec0b6f10ab
3 changed files with 8 additions and 5 deletions
+1 -1
View File
@@ -88,7 +88,7 @@ function chooseTask(task:string){if(task==='extend'){Object.assign(form,extendSe
function chooseClip(id:string){if(!id){form.startClipId='';return}const clip=clips.value.find((c:any)=>c.id===id);if(clip)Object.assign(form,bindClip(form,clip,useRuntimeConfig().public.studio==='xaigen'))}
function selectOutput(item:any){selected.value=item}
function sourceChanged(){Object.assign(form,changeSource(form))}
function restore(item:any){Object.assign(form,restoreAll(form,item));form.guides=form.guides||[];batchText.value=''}
function restore(item:any){Object.assign(form,restoreAll(form,item,xaigen));form.guides=form.guides||[];batchText.value=''}
function focusJob(job:any){selectOutput(job.outputs?.at(-1)||null)}
async function loadLoras(fresh=false){try{loraNames.value=await $fetch('/api/studio-2/loras'+(fresh?'?fresh=1':''))}catch{error.value='Could not refresh LoRAs. The last loaded list is still available.'}}
function pickAsset(asset:any){const key=picker.value;if(key.startsWith('guide:'))form.guides[Number(key.split(':')[1])].stillId=asset?.id||'';else if(key==='startClipId')chooseClip(asset?.id||'');else form[key]=asset?.id||'';picker.value=''}
+5 -2
View File
@@ -49,8 +49,11 @@ export function changeSource(form) {
export function useAsHero(form, item) { return {...form,identityStillId:item.id} }
export function useAsSource(form, item) { return {...form,imageAId:item.id} }
export function restoreAll(form,item) {
export function restoreAll(form,item,xaigen=false) {
const restored=restoreInput(item),next={...form,...restored,settings:{...form.settings,...restored.settings,seedMode:'random'}}
next.mode=restored.mode==='iterate'?'edit':restored.mode || (item.kind==='clip'?'video':'edit')
if(item.kind==='clip') return {...bindClip(next,item,xaigen),mode:'extend'}
next.mode=restored.mode==='iterate'?'edit':restored.mode || 'edit'
next.imageAId=item.id
next.startClipId=''
return next
}
+2 -2
View File
@@ -27,7 +27,7 @@ test('hidden xAIGen canvas and family render no image or video elements',async()
const src=readFileSync(new URL('../components/studio2/Bench.vue',import.meta.url),'utf8')
const stage=src.slice(src.indexOf(' <div class="flex min-h-80'),src.indexOf(' <div v-if="selected"'))
const strip=src.split('\n').find(line=>line.includes('aria-label="Current family outputs"'))
const render=new Function('Vue',compile('<section>'+stage+strip+'</section>',{mode:'function'}).code)(Vue)
const render=new Function('Vue',compile('<section>'+stage+strip+'</section>',{mode:'function',prefixIdentifiers:true}).code)(Vue)
const state={selected:{id:'a',kind:'still'},hideOutput:true,xaigen:true,family:[{id:'a',kind:'still'}],form:{hideInput:true},previewHidden,stillUrl:id=>'/image/'+id,selectOutput(){}}
const hidden=await renderToString(Vue.createSSRApp({render,data:()=>state}));assert.doesNotMatch(hidden,/<img|<video/);assert.match(hidden,/preview hidden/)
const visible=await renderToString(Vue.createSSRApp({render,data:()=>({...state,xaigen:false})}));assert.match(visible,/<img/)
@@ -42,7 +42,7 @@ test('source/hero actions are independent and full input restores structured set
const form={identityStillId:'hero',imageAId:'source',promptSections:{action:'old'},settings:{}}
assert.equal(useAsHero(form,{id:'new'}).imageAId,'source');assert.equal(useAsSource(form,{id:'new'}).identityStillId,'hero')
const saved={mode:'edit',identityStillId:'h',imageAId:'s',imageStyles:{positive:['Comic'],negative:['Skin pores']},promptSections:{action:'New',cameraBeats:[{moves:['hold']}]},settings:{steps:24,loraStack:[{name:'a',strengthModel:.4,strengthClip:.6}]}}
const restored=restoreAll(form,{id:'result',studio2:saved});assert.equal(restored.imageAId,'s');assert.equal(restored.identityStillId,'h');assert.deepEqual(restored.settings.loraStack,saved.settings.loraStack);assert.deepEqual(restored.imageStyles,saved.imageStyles);assert.equal(restored.promptSections.action,'New')
const restored=restoreAll(form,{id:'result',studio2:saved});assert.equal(restored.imageAId,'result');assert.equal(restored.identityStillId,'h');assert.deepEqual(restored.settings.loraStack,saved.settings.loraStack);assert.deepEqual(restored.imageStyles,saved.imageStyles);assert.equal(restored.promptSections.action,'New');const clip=restoreAll(form,{id:'clip',kind:'clip',studio2:{...saved,mode:'video',engine:'minimax'}});assert.equal(clip.startClipId,'clip');assert.equal(clip.mode,'extend');assert.equal(clip.promptSections.action,'New')
})
test('image chips compile positive and negative independently; video chips do not leak',()=>{
let styles=toggleStyle({},'Comic');styles=toggleStyle(styles,'Skin pores',true);styles=toggleStyle(styles,'Comic',true);assert.equal(stylePrompt(styles),'');assert.match(stylePrompt(styles,true),/Comic/)