Split blank-line paragraphs in the desktop prompt into ordered image batch jobs.
This commit is contained in:
@@ -124,11 +124,12 @@
|
|||||||
ref="promptArea"
|
ref="promptArea"
|
||||||
v-model="form.promptSections.action"
|
v-model="form.promptSections.action"
|
||||||
class="field-area"
|
class="field-area"
|
||||||
placeholder="Describe the image or the shot."
|
placeholder="Describe the image or the shot. Blank line between prompts for a batch."
|
||||||
@select="capturePromptCaret"
|
@select="capturePromptCaret"
|
||||||
@click="capturePromptCaret"
|
@click="capturePromptCaret"
|
||||||
@keyup="capturePromptCaret"
|
@keyup="capturePromptCaret"
|
||||||
/>
|
/>
|
||||||
|
<p v-if="imagePromptCount > 1" class="mt-1 text-[var(--type-sm)] text-[var(--muted)]">{{ imagePromptCount }} prompts · queued in order</p>
|
||||||
</label>
|
</label>
|
||||||
<label v-if="form.engine==='qwen21' && (form.mode==='generate' || form.mode==='edit')" class="inline-flex items-center gap-2 text-[var(--type-sm)] text-[var(--muted)]">
|
<label v-if="form.engine==='qwen21' && (form.mode==='generate' || form.mode==='edit')" class="inline-flex items-center gap-2 text-[var(--type-sm)] text-[var(--muted)]">
|
||||||
<input v-model="form.enhancePrompt" type="checkbox" class="accent-[var(--amber)]">Enhance prompt
|
<input v-model="form.enhancePrompt" type="checkbox" class="accent-[var(--amber)]">Enhance prompt
|
||||||
@@ -406,7 +407,7 @@
|
|||||||
<div class="queue-foot">
|
<div class="queue-foot">
|
||||||
<button type="button" class="generate-cta" :disabled="submitting" @click="queue">
|
<button type="button" class="generate-cta" :disabled="submitting" @click="queue">
|
||||||
<span aria-hidden="true">▶</span>
|
<span aria-hidden="true">▶</span>
|
||||||
{{ submitting ? 'Queuing…' : 'Generate' }}
|
{{ submitting ? 'Queuing…' : (imagePromptCount > 1 ? `Generate · ${imagePromptCount} prompts` : 'Generate') }}
|
||||||
</button>
|
</button>
|
||||||
<p v-if="error" class="queue-foot-error">{{ error }}</p>
|
<p v-if="error" class="queue-foot-error">{{ error }}</p>
|
||||||
<p class="tiny">
|
<p class="tiny">
|
||||||
@@ -744,6 +745,12 @@ function onStagePreviewError(){
|
|||||||
watch(()=>selected.value?.id,()=>{stagePreviewNonce.value=0;stagePreviewRetries.value=0})
|
watch(()=>selected.value?.id,()=>{stagePreviewNonce.value=0;stagePreviewRetries.value=0})
|
||||||
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))
|
||||||
|
/** Desktop image generate: blank-line paragraphs in the prompt box (same parseBatch as mobile batchText). */
|
||||||
|
const imagePromptParts=computed(()=>{
|
||||||
|
if(video.value || form.mode!=='generate') return [] as string[]
|
||||||
|
return parseBatch(form.promptSections?.action)
|
||||||
|
})
|
||||||
|
const imagePromptCount=computed(()=>imagePromptParts.value.length)
|
||||||
const musicJobs=computed(()=>studioQueue.value
|
const musicJobs=computed(()=>studioQueue.value
|
||||||
.filter((j:any)=>j.kind==='music' && j.folderId===form.folderId && !['complete','done'].includes(j.status))
|
.filter((j:any)=>j.kind==='music' && j.folderId===form.folderId && !['complete','done'].includes(j.status))
|
||||||
.map((j:any)=>({...j,live:j.liveJobId?liveMusic.value[j.liveJobId]:null})))
|
.map((j:any)=>({...j,live:j.liveJobId?liveMusic.value[j.liveJobId]:null})))
|
||||||
@@ -1521,6 +1528,10 @@ async function queue(){
|
|||||||
.filter((p:any)=>p?.stillId)
|
.filter((p:any)=>p?.stillId)
|
||||||
.map((p:any)=>({stillId:String(p.stillId),role:String(p.role||'change')}))
|
.map((p:any)=>({stillId:String(p.stillId),role:String(p.role||'change')}))
|
||||||
const promptAction=String(form.promptSections?.action||'')
|
const promptAction=String(form.promptSections?.action||'')
|
||||||
|
// Image generate: split the prompt box on blank lines (parseBatch). Video/edit keep batchText.
|
||||||
|
const imageParts=(!video.value && form.mode==='generate') ? parseBatch(promptAction) : null
|
||||||
|
const firstAction=imageParts?.length ? imageParts[0] : promptAction
|
||||||
|
const imageBatch=imageParts?.length ? imageParts.slice(1) : []
|
||||||
const promptSections=video.value
|
const promptSections=video.value
|
||||||
?{
|
?{
|
||||||
action:promptAction,
|
action:promptAction,
|
||||||
@@ -1534,7 +1545,7 @@ async function queue(){
|
|||||||
musicChip:form.promptSections?.musicChip||'N/A',
|
musicChip:form.promptSections?.musicChip||'N/A',
|
||||||
dialogue:form.promptSections?.dialogue?JSON.parse(JSON.stringify(form.promptSections.dialogue)):{mode:'none',line:''}
|
dialogue:form.promptSections?.dialogue?JSON.parse(JSON.stringify(form.promptSections.dialogue)):{mode:'none',line:''}
|
||||||
}
|
}
|
||||||
:{action:promptAction}
|
:{action:firstAction}
|
||||||
const settings={
|
const settings={
|
||||||
aspect:String(form.settings?.aspect||'auto'),
|
aspect:String(form.settings?.aspect||'auto'),
|
||||||
fps:Number(form.settings?.fps)||24,
|
fps:Number(form.settings?.fps)||24,
|
||||||
@@ -1607,7 +1618,7 @@ async function queue(){
|
|||||||
promptSections,
|
promptSections,
|
||||||
imageStyles:optimisticRequest.imageStyles,
|
imageStyles:optimisticRequest.imageStyles,
|
||||||
settings:{...settings,seed:form.settings.seed},
|
settings:{...settings,seed:form.settings.seed},
|
||||||
batch:video.value || form.mode==='edit'?parseBatch(batchText.value):[],
|
batch:video.value || form.mode==='edit' ? parseBatch(batchText.value) : imageBatch,
|
||||||
guides:[],
|
guides:[],
|
||||||
maskId:'',
|
maskId:'',
|
||||||
endStillId:''
|
endStillId:''
|
||||||
|
|||||||
Reference in New Issue
Block a user