Move engine pickers into the Video / Image / Music cards.
Flux/Krea, MiniMax/LTX, and ACE/YuE sit on the top kind cards so you choose the engine before the prompt form.
This commit is contained in:
+149
-39
@@ -1,54 +1,164 @@
|
||||
<template>
|
||||
<div class="mb-4 grid grid-cols-3 gap-3">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-3xl border px-4 py-4 text-left transition"
|
||||
:class="current === 'video' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400 hover:border-white/20 hover:text-zinc-200'"
|
||||
@click="emit('select', 'video')"
|
||||
<div
|
||||
class="overflow-hidden rounded-3xl border transition"
|
||||
:class="current === 'video' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400'"
|
||||
>
|
||||
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
|
||||
<rect x="4" y="10" width="24" height="20" rx="3" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M28 16 36 12v16l-8-4V16Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
|
||||
<circle cx="12" cy="20" r="2" fill="currentColor" />
|
||||
</svg>
|
||||
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Video</span>
|
||||
<span class="mt-0.5 block text-xs text-zinc-500">MiniMax H3 · LTX</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-3xl border px-4 py-4 text-left transition"
|
||||
:class="current === 'image' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400 hover:border-white/20 hover:text-zinc-200'"
|
||||
@click="emit('select', 'image')"
|
||||
<button
|
||||
type="button"
|
||||
class="w-full px-4 pb-3 pt-4 text-left transition"
|
||||
:class="current === 'video' ? '' : 'hover:text-zinc-200'"
|
||||
@click="emit('select', 'video')"
|
||||
>
|
||||
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
|
||||
<rect x="4" y="10" width="24" height="20" rx="3" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M28 16 36 12v16l-8-4V16Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
|
||||
<circle cx="12" cy="20" r="2" fill="currentColor" />
|
||||
</svg>
|
||||
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Video</span>
|
||||
</button>
|
||||
<div v-if="ltxEnabled" class="grid grid-cols-2 border-t border-white/10">
|
||||
<button
|
||||
type="button"
|
||||
class="border-r border-white/10 px-3 py-2.5 text-left text-sm transition"
|
||||
:class="engineBtnClass(current === 'video' && videoEngine === 'minimax')"
|
||||
@click="pickVideo('minimax')"
|
||||
>
|
||||
<span class="block font-semibold">MiniMax</span>
|
||||
<span class="text-xs opacity-80">H3</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="px-3 py-2.5 text-left text-sm transition"
|
||||
:class="engineBtnClass(current === 'video' && videoEngine === 'ltx')"
|
||||
@click="pickVideo('ltx')"
|
||||
>
|
||||
<span class="block font-semibold">LTX</span>
|
||||
<span class="text-xs opacity-80">2.3</span>
|
||||
</button>
|
||||
</div>
|
||||
<p v-else class="border-t border-white/10 px-4 py-2 text-xs text-zinc-500">MiniMax H3</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="overflow-hidden rounded-3xl border transition"
|
||||
:class="current === 'image' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400'"
|
||||
>
|
||||
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
|
||||
<rect x="6" y="8" width="28" height="24" rx="3" stroke="currentColor" stroke-width="2" />
|
||||
<path d="m10 26 7-8 6 7 3-3 4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<circle cx="15" cy="15" r="2.5" fill="currentColor" />
|
||||
</svg>
|
||||
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Image</span>
|
||||
<span class="mt-0.5 block text-xs text-zinc-500">Flux · Krea</span>
|
||||
</button>
|
||||
<NuxtLink
|
||||
to="/music"
|
||||
class="rounded-3xl border px-4 py-4 text-left transition"
|
||||
:class="current === 'music' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400 hover:border-white/20 hover:text-zinc-200'"
|
||||
<button
|
||||
type="button"
|
||||
class="w-full px-4 pb-3 pt-4 text-left transition"
|
||||
:class="current === 'image' ? '' : 'hover:text-zinc-200'"
|
||||
@click="emit('select', 'image')"
|
||||
>
|
||||
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
|
||||
<rect x="6" y="8" width="28" height="24" rx="3" stroke="currentColor" stroke-width="2" />
|
||||
<path d="m10 26 7-8 6 7 3-3 4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<circle cx="15" cy="15" r="2.5" fill="currentColor" />
|
||||
</svg>
|
||||
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Image</span>
|
||||
</button>
|
||||
<div class="grid grid-cols-2 border-t border-white/10">
|
||||
<button
|
||||
type="button"
|
||||
class="border-r border-white/10 px-3 py-2.5 text-left text-sm transition"
|
||||
:class="engineBtnClass(current === 'image' && imageEngine === 'flux')"
|
||||
@click="pickImage('flux')"
|
||||
>
|
||||
<span class="block font-semibold">Flux</span>
|
||||
<span class="text-xs opacity-80">Klein 9B</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="px-3 py-2.5 text-left text-sm transition"
|
||||
:class="engineBtnClass(current === 'image' && imageEngine === 'krea')"
|
||||
@click="pickImage('krea')"
|
||||
>
|
||||
<span class="block font-semibold">Krea</span>
|
||||
<span class="text-xs opacity-80">2 Turbo</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="overflow-hidden rounded-3xl border transition"
|
||||
:class="current === 'music' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400'"
|
||||
>
|
||||
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
|
||||
<circle cx="20" cy="20" r="12" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M18 14v12l10-4V12l-10 2Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
|
||||
</svg>
|
||||
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Music</span>
|
||||
<span class="mt-0.5 block text-xs text-zinc-500">ACE-Step · YuE</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/music"
|
||||
class="block w-full px-4 pb-3 pt-4 text-left transition"
|
||||
:class="current === 'music' ? '' : 'hover:text-zinc-200'"
|
||||
>
|
||||
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
|
||||
<circle cx="20" cy="20" r="12" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M18 14v12l10-4V12l-10 2Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
|
||||
</svg>
|
||||
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Music</span>
|
||||
</NuxtLink>
|
||||
<div class="grid grid-cols-2 border-t border-white/10">
|
||||
<button
|
||||
type="button"
|
||||
class="border-r border-white/10 px-3 py-2.5 text-left text-sm transition"
|
||||
:class="engineBtnClass(current === 'music' && musicEngine === 'ace')"
|
||||
@click="pickMusic('ace')"
|
||||
>
|
||||
<span class="block font-semibold">ACE</span>
|
||||
<span class="text-xs opacity-80">Step</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="px-3 py-2.5 text-left text-sm transition"
|
||||
:class="engineBtnClass(current === 'music' && musicEngine === 'yue')"
|
||||
@click="pickMusic('yue')"
|
||||
>
|
||||
<span class="block font-semibold">YuE</span>
|
||||
<span class="text-xs opacity-80">Lyrics</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
current: 'video' | 'image' | 'music'
|
||||
}>()
|
||||
ltxEnabled?: boolean
|
||||
videoEngine?: 'minimax' | 'ltx'
|
||||
imageEngine?: 'flux' | 'krea'
|
||||
musicEngine?: 'ace' | 'yue'
|
||||
}>(), {
|
||||
ltxEnabled: false,
|
||||
videoEngine: 'minimax',
|
||||
imageEngine: 'flux',
|
||||
musicEngine: 'ace'
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
select: [kind: 'video' | 'image']
|
||||
'video-engine': [engine: 'minimax' | 'ltx']
|
||||
'image-engine': [engine: 'flux' | 'krea']
|
||||
'music-engine': [engine: 'ace' | 'yue']
|
||||
}>()
|
||||
|
||||
function engineBtnClass(active: boolean) {
|
||||
if (active) return 'bg-amber-400/15 text-amber-100'
|
||||
return 'text-zinc-400 hover:bg-white/5 hover:text-zinc-200'
|
||||
}
|
||||
|
||||
function pickVideo(engine: 'minimax' | 'ltx') {
|
||||
emit('video-engine', engine)
|
||||
if (props.current !== 'video') emit('select', 'video')
|
||||
}
|
||||
|
||||
function pickImage(engine: 'flux' | 'krea') {
|
||||
emit('image-engine', engine)
|
||||
if (props.current !== 'image') emit('select', 'image')
|
||||
}
|
||||
|
||||
function pickMusic(engine: 'ace' | 'yue') {
|
||||
if (props.current === 'music') {
|
||||
emit('music-engine', engine)
|
||||
return
|
||||
}
|
||||
void navigateTo({ path: '/music', query: { engine } })
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user