Simplify generation controls with task navigation and settings drawer
This commit is contained in:
+44
-5
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="min-h-dvh min-w-0">
|
||||
<AppHeader
|
||||
:subtitle="ltxEnabled ? 'MiniMax H3 · LTX-2.3 · Flux.2 Klein' : 'MiniMax H3 · Flux.2 Klein'"
|
||||
:subtitle="advanced ? (ltxEnabled ? 'MiniMax H3 · LTX-2.3 · Flux.2 Klein' : 'MiniMax H3 · Flux.2 Klein') : 'Create images, video, and music'"
|
||||
current="studio"
|
||||
:queue-count="queueBadgeCount"
|
||||
@gpu="pollComfyHealth"
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<main class="mx-auto min-w-0 max-w-7xl space-y-6 px-4 py-6 sm:px-6">
|
||||
<StudioKindCards
|
||||
:advanced="advanced"
|
||||
:current="imageStudio ? 'image' : 'video'"
|
||||
:ltx-enabled="ltxEnabled"
|
||||
:video-engine="videoEngine"
|
||||
@@ -18,6 +19,12 @@
|
||||
@video-engine="selectVideoEngine"
|
||||
@image-engine="setV2Engine"
|
||||
/>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<div v-if="!advanced" class="flex flex-wrap gap-2" role="group" aria-label="Generation task">
|
||||
<button v-for="task in ['From text', 'From image', 'Edit', 'Extend']" :key="task" type="button" class="rounded-full border px-4 py-2 text-sm" :class="simpleTask === task ? 'border-amber-300 bg-amber-400/10 text-amber-100' : 'border-white/15 text-zinc-300'" :aria-pressed="simpleTask === task" @click="chooseSimpleTask(task)">{{ task }}</button>
|
||||
</div>
|
||||
<label class="ml-auto flex items-center gap-2 text-sm text-zinc-300"><input v-model="advanced" type="checkbox" class="accent-amber-400">Advanced mode</label>
|
||||
</div>
|
||||
<div class="grid min-w-0 gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] lg:items-stretch">
|
||||
<section id="studio-input" class="glass min-w-0 max-w-full space-y-5 rounded-3xl p-5 sm:p-6">
|
||||
<div>
|
||||
@@ -127,7 +134,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="studioMode === 'editv2'" class="flex flex-wrap gap-2">
|
||||
<div v-if="studioMode === 'editv2' && (advanced || simpleTask === 'Edit')" class="flex flex-wrap gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-full border px-3 py-1 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-40"
|
||||
@@ -266,7 +273,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<DirectorScriptBar
|
||||
v-if="studioMode === 'video'"
|
||||
v-if="advanced && studioMode === 'video'"
|
||||
class="mb-2"
|
||||
:scripts="directorScripts"
|
||||
v-model:selected-id="directorScriptId"
|
||||
@@ -288,6 +295,7 @@
|
||||
>
|
||||
<div class="min-w-0">
|
||||
<PromptPartsEditor
|
||||
:simple="!advanced"
|
||||
v-model:pre="promptPre"
|
||||
v-model:prompt="prompt"
|
||||
v-model:post="promptPost"
|
||||
@@ -660,6 +668,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!advanced" class="space-y-4">
|
||||
<AspectRatioPick v-if="imageStudio" :model-value="aspect" heading="Image size" :options="imageAspects" @update:model-value="setImageAspect" />
|
||||
<template v-else><DurationField v-model="duration" label="Duration" /><AspectRatioPick v-model="aspect" heading="Video size" :options="videoAspects" /></template>
|
||||
</div>
|
||||
<GenerationSettings :advanced="advanced">
|
||||
<div v-if="studioMode === 'video'" class="space-y-3">
|
||||
<p class="text-xs text-zinc-500">{{ videoModelHint }}</p>
|
||||
<div v-if="showLegacyMinimaxV1 && videoEngine === 'minimax' && videoStart === 'still'">
|
||||
@@ -737,6 +750,11 @@
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<label class="block space-y-2 text-sm">
|
||||
<span>Model</span>
|
||||
<select v-if="imageStudio" :value="v2Engine" class="w-full rounded-xl border border-white/15 bg-zinc-900 p-3" @change="setV2Engine(($event.target as HTMLSelectElement).value as ImageV2Engine)"><option value="flux">Flux Klein 9B</option><option value="krea">Krea 2 Turbo</option></select>
|
||||
<select v-else :value="videoEngine" class="w-full rounded-xl border border-white/15 bg-zinc-900 p-3" @change="selectVideoEngine(($event.target as HTMLSelectElement).value as VideoEngineId)"><option value="minimax">MiniMax H3</option><option v-if="ltxEnabled" value="ltx">LTX 2.3</option></select>
|
||||
</label>
|
||||
<div v-if="studioMode === 'video'" class="max-w-md space-y-2">
|
||||
<LoraSelect
|
||||
v-model="videoLoraStack"
|
||||
@@ -1126,14 +1144,15 @@
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
</GenerationSettings>
|
||||
<div class="sticky bottom-3 z-10 flex flex-wrap gap-3 rounded-2xl bg-zinc-950/95 p-2 shadow-lg">
|
||||
<button
|
||||
type="button"
|
||||
class="flex-1 rounded-2xl bg-amber-400 px-5 py-3 font-semibold text-zinc-950 transition hover:bg-amber-300 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
:disabled="studioMode === 'editv2' ? editV2Blocked : (studioMode === 'edit' ? editBlocked : videoGenerateDisabled)"
|
||||
@click="studioMode === 'editv2' ? editImageV2() : (studioMode === 'edit' ? editImage() : generate())"
|
||||
>
|
||||
{{ studioMode === 'editv2' ? editV2SubmitLabel : (studioMode === 'edit' ? editSubmitLabel : generateLabel) }}
|
||||
{{ !advanced ? 'Queue' : studioMode === 'editv2' ? editV2SubmitLabel : (studioMode === 'edit' ? editSubmitLabel : generateLabel) }}
|
||||
</button>
|
||||
<button
|
||||
v-if="showWakeGpu"
|
||||
@@ -2393,6 +2412,26 @@ import {
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { advanced } = useStudioLayout()
|
||||
const editingTask = ref(false)
|
||||
const simpleTask = computed(() => extendOpen.value ? 'Extend' : editingTask.value || (imageStudio.value && ['compose', 'refine'].includes(v2Mode.value)) ? 'Edit' : file.value ? 'From image' : 'From text')
|
||||
function chooseSimpleTask(task: string) {
|
||||
if (task === 'Extend') {
|
||||
selectStudioKind('video')
|
||||
void openExtend()
|
||||
return
|
||||
}
|
||||
closeExtend()
|
||||
editingTask.value = task === 'Edit'
|
||||
if (task === 'Edit') selectStudioKind('image')
|
||||
if (task === 'From text') {
|
||||
resetImage()
|
||||
if (imageStudio.value) v2Mode.value = editPassQueue.value.length ? 'iterate' : 'generate'
|
||||
} else {
|
||||
if (imageStudio.value && !editPassQueue.value.length) v2Mode.value = 'edit'
|
||||
if (!file.value) openPicker('main')
|
||||
}
|
||||
}
|
||||
|
||||
type AspectId = 'auto' | '16:9' | '9:16' | '1:1'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user