Rename library actions and always store promptRaw on ingest.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-29 08:14:13 -05:00
co-authored by Cursor
parent 930bbf7c7b
commit 5f6a7aa9bc
3 changed files with 44 additions and 40 deletions
+11 -5
View File
@@ -97,9 +97,12 @@
<aside v-if="detailAsset" class="lib-modal-detail"> <aside v-if="detailAsset" class="lib-modal-detail">
<p class="lib-modal-detail-name">{{ detailLabel }}</p> <p class="lib-modal-detail-name">{{ detailLabel }}</p>
<div v-if="detailAsset.kind !== 'track'" class="lib-modal-actions"> <div v-if="detailAsset.kind !== 'track'" class="lib-modal-actions">
<button type="button" @click="$emit('use-as-photo', detailAsset)">Use as photo</button> <button type="button" @click="$emit('use-image', detailAsset)">Use image</button>
<button type="button" @click="$emit('use-prompt', detailAsset)">Use prompt</button>
<button type="button" @click="$emit('copy-prompt', detailAsset)">Copy prompt</button> <button type="button" @click="$emit('copy-prompt', detailAsset)">Copy prompt</button>
<button type="button" @click="$emit('load', detailAsset)">Load</button> <button type="button" @click="$emit('copy-raw-prompt', detailAsset)">Copy raw prompt</button>
<button type="button" @click="$emit('load-input', detailAsset)">Load input</button>
<button type="button" @click="$emit('load-input-raw', detailAsset)">Load input raw</button>
<button type="button" @click="$emit('toggle-preview')">{{ previewHidden ? 'Show output' : 'Hide output' }}</button> <button type="button" @click="$emit('toggle-preview')">{{ previewHidden ? 'Show output' : 'Hide output' }}</button>
<button type="button" class="danger" @click="onDeleteClick">Delete</button> <button type="button" class="danger" @click="onDeleteClick">Delete</button>
<button type="button" class="primary" @click="useAndClose">Use and close</button> <button type="button" class="primary" @click="useAndClose">Use and close</button>
@@ -139,9 +142,12 @@ const props = defineProps<{
const emit = defineEmits<{ const emit = defineEmits<{
close: [] close: []
select: [asset: any] select: [asset: any]
'use-as-photo': [asset: any] 'use-image': [asset: any]
'use-prompt': [asset: any]
'copy-prompt': [asset: any] 'copy-prompt': [asset: any]
load: [asset: any] 'copy-raw-prompt': [asset: any]
'load-input': [asset: any]
'load-input-raw': [asset: any]
delete: [asset: any] delete: [asset: any]
'toggle-preview': [] 'toggle-preview': []
}>() }>()
@@ -234,7 +240,7 @@ function pickEntry(entry: LibraryEntry) {
function close() { emit('close') } function close() { emit('close') }
function useAndClose() { function useAndClose() {
if (detailAsset.value) emit('select', detailAsset.value) if (detailAsset.value) emit('use-image', detailAsset.value)
close() close()
} }
+17 -21
View File
@@ -129,9 +129,12 @@
:preview-hidden="!ctx.eyeOpen" :preview-hidden="!ctx.eyeOpen"
@close="ctx.closeLibrary()" @close="ctx.closeLibrary()"
@select="ctx.selectOutput" @select="ctx.selectOutput"
@use-as-photo="ctx.onLibraryUseAsPhoto" @use-image="ctx.onLibraryUseImage"
@use-prompt="ctx.onLibraryUsePrompt"
@copy-prompt="ctx.onLibraryCopyPrompt" @copy-prompt="ctx.onLibraryCopyPrompt"
@load="ctx.onLibraryLoad" @copy-raw-prompt="ctx.onLibraryCopyRawPrompt"
@load-input="ctx.onLibraryLoadInput"
@load-input-raw="ctx.onLibraryLoadInputRaw"
@delete="ctx.onLibraryDelete" @delete="ctx.onLibraryDelete"
@toggle-preview="ctx.toggleReveal()" @toggle-preview="ctx.toggleReveal()"
/> />
@@ -150,9 +153,12 @@
<button type="button" class="m-handle" aria-label="Close" @click="sheet=''" /> <button type="button" class="m-handle" aria-label="Close" @click="sheet=''" />
<div class="m-sheet-head"><strong>Actions</strong><button type="button" @click="sheet=''">Done</button></div> <div class="m-sheet-head"><strong>Actions</strong><button type="button" @click="sheet=''">Done</button></div>
<div class="m-sheet-body m-actions-list"> <div class="m-sheet-body m-actions-list">
<button type="button" @click="runAction('use')">Use as photo</button> <button type="button" @click="runAction('use-image')">Use image</button>
<button type="button" @click="runAction('use-prompt')">Use prompt</button>
<button type="button" @click="runAction('copy')">Copy prompt</button> <button type="button" @click="runAction('copy')">Copy prompt</button>
<button type="button" @click="runAction('load')">Load</button> <button type="button" @click="runAction('copy-raw')">Copy raw prompt</button>
<button type="button" @click="runAction('load-input')">Load input</button>
<button type="button" @click="runAction('load-input-raw')">Load input raw</button>
<button type="button" class="m-danger" @click="runAction('delete')">Delete</button> <button type="button" class="m-danger" @click="runAction('delete')">Delete</button>
</div> </div>
</aside> </aside>
@@ -172,24 +178,12 @@
{{ ctx.hideInputs ? 'Show inputs' : 'Hide inputs' }} {{ ctx.hideInputs ? 'Show inputs' : 'Hide inputs' }}
</button> </button>
</div> </div>
<template v-if="ctx.hideInputs">
<p class="m-muted">
{{ ctx.photoFilledCount || 0 }} photo{{ (ctx.photoFilledCount||0)===1 ? '' : 's' }}
<button
v-if="(ctx.form.photos?.length||0) < ctx.photosPlanState.max"
type="button"
class="m-amber"
@click="ctx.showInputsAndAddPhoto()"
>+ Add photo</button>
</p>
</template>
<template v-else>
<p v-if="!ctx.form.photos?.length && ctx.photosPlanState.emptyHint" class="m-muted">{{ ctx.photosPlanState.emptyHint }}</p> <p v-if="!ctx.form.photos?.length && ctx.photosPlanState.emptyHint" class="m-muted">{{ ctx.photosPlanState.emptyHint }}</p>
<Studio2AssetSlot <Studio2AssetSlot
v-for="(card, index) in ctx.form.photos" v-for="(card, index) in ctx.form.photos"
:key="'m-photo-'+index+'-'+card.stillId" :key="'m-photo-'+index+'-'+card.stillId"
:asset="ctx.stillById(card.stillId)" :asset="ctx.stillById(card.stillId)"
:hidden="false" :hidden="!!ctx.hideInputs"
:role="card.role" :role="card.role"
:role-options="ctx.photoRoleOptions" :role-options="ctx.photoRoleOptions"
@pick="ctx.setPicker('photo:'+index)" @pick="ctx.setPicker('photo:'+index)"
@@ -199,7 +193,6 @@
/> />
<button v-if="(ctx.form.photos?.length||0) < ctx.photosPlanState.max" type="button" class="m-amber" @click="ctx.addPhoto">+ Add photo</button> <button v-if="(ctx.form.photos?.length||0) < ctx.photosPlanState.max" type="button" class="m-amber" @click="ctx.addPhoto">+ Add photo</button>
<p v-if="ctx.photoRoleWarning" class="m-hint">{{ ctx.photoRoleWarning }}</p> <p v-if="ctx.photoRoleWarning" class="m-hint">{{ ctx.photoRoleWarning }}</p>
</template>
<template v-if="ctx.showIdentityLocks"> <template v-if="ctx.showIdentityLocks">
<label class="m-check"><input v-model="ctx.form.lockFace" type="checkbox"> Lock face</label> <label class="m-check"><input v-model="ctx.form.lockFace" type="checkbox"> Lock face</label>
<label class="m-check"><input v-model="ctx.form.lockOutfit" type="checkbox"> Lock outfit</label> <label class="m-check"><input v-model="ctx.form.lockOutfit" type="checkbox"> Lock outfit</label>
@@ -360,11 +353,14 @@ function toggleSheet(id: string) {
function closeMenus() { function closeMenus() {
sheet.value = '' sheet.value = ''
} }
function runAction(kind: 'use' | 'copy' | 'load' | 'delete') { function runAction(kind: 'use-image' | 'use-prompt' | 'copy' | 'copy-raw' | 'load-input' | 'load-input-raw' | 'delete') {
sheet.value = '' sheet.value = ''
if (kind === 'use') props.ctx.applyUseAsSource?.() if (kind === 'use-image') props.ctx.applyUseImage?.()
else if (kind === 'use-prompt') props.ctx.applyUsePrompt?.()
else if (kind === 'copy') props.ctx.copySelectedPrompt?.() else if (kind === 'copy') props.ctx.copySelectedPrompt?.()
else if (kind === 'load') props.ctx.loadSelectedJob?.() else if (kind === 'copy-raw') props.ctx.copySelectedRawPrompt?.()
else if (kind === 'load-input') props.ctx.loadInputUsed?.()
else if (kind === 'load-input-raw') props.ctx.loadInputRaw?.()
else if (kind === 'delete') props.ctx.deleteOutput?.() else if (kind === 'delete') props.ctx.deleteOutput?.()
} }
function onStageTouchStart(e: TouchEvent) { function onStageTouchStart(e: TouchEvent) {
+2
View File
@@ -452,6 +452,8 @@ async function run(r: any, job: Job) {
r.progress = null; r.progress = null;
r.request.promptSections = prompts[r.index]; r.request.promptSections = prompts[r.index];
r.request.compiledPrompt = compilePrompt(prompts[r.index], ['video', 'extend'].includes(r.request.mode), r.request); r.request.compiledPrompt = compilePrompt(prompts[r.index], ['video', 'extend'].includes(r.request.mode), r.request);
// Typed brief before PE / TextEncode — Copy raw / Load input raw need this even when Enhance is off.
r.request.promptRaw = String(r.request.compiledPrompt || '');
update(r, 'waking'); update(r, 'waking');
await ensureComfyReady(message => emitJob(job, { type: 'status', message })); await ensureComfyReady(message => emitJob(job, { type: 'status', message }));
if (job.status === 'cancelled') if (job.status === 'cancelled')