Add ACE-Step 1.5 and YuE on Music, and put Video/Image/Music cards back.
Recover finished Comfy audio when queueing hangs so a completed track is not stuck on Queueing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div
|
||||
ref="root"
|
||||
class="relative inline-flex shrink-0"
|
||||
@mouseenter="open"
|
||||
@mouseleave="scheduleClose"
|
||||
@focusin="open"
|
||||
@focusout="onFocusOut"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="flex h-6 w-6 items-center justify-center rounded-full border border-white/15 text-zinc-400 hover:border-amber-300/50 hover:text-amber-200"
|
||||
:aria-label="ariaLabel"
|
||||
:aria-expanded="show"
|
||||
@click.prevent.stop="show = !show"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-3.5 w-3.5" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<path d="M12 16v-4M12 8h.01" stroke-linecap="round" />
|
||||
</svg>
|
||||
</button>
|
||||
<Teleport to="body">
|
||||
<div
|
||||
v-if="show"
|
||||
ref="panel"
|
||||
class="fixed z-[80] max-h-[min(20rem,50vh)] w-[min(28rem,calc(100vw-1.5rem))] overflow-y-auto overscroll-contain whitespace-pre-wrap break-words rounded-xl border border-white/10 bg-zinc-950 p-3 text-xs leading-relaxed text-zinc-300 shadow-2xl"
|
||||
:style="panelStyle"
|
||||
@mouseenter="open"
|
||||
@mouseleave="scheduleClose"
|
||||
@click.stop
|
||||
>
|
||||
{{ text }}
|
||||
</div>
|
||||
</Teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
text: string
|
||||
ariaLabel: string
|
||||
}>()
|
||||
|
||||
const root = ref<HTMLElement | null>(null)
|
||||
const panel = ref<HTMLElement | null>(null)
|
||||
const show = ref(false)
|
||||
const panelStyle = ref<Record<string, string>>({})
|
||||
let closeTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
function place() {
|
||||
const el = root.value
|
||||
if (!el) return
|
||||
const rect = el.getBoundingClientRect()
|
||||
const width = Math.min(448, window.innerWidth - 24)
|
||||
const maxHeight = Math.min(320, window.innerHeight * 0.5)
|
||||
let left = rect.right - width
|
||||
left = Math.min(Math.max(12, left), window.innerWidth - width - 12)
|
||||
const below = rect.bottom + 8
|
||||
const above = rect.top - 8 - maxHeight
|
||||
const top = below + maxHeight <= window.innerHeight - 12 ? below : Math.max(12, above)
|
||||
panelStyle.value = {
|
||||
top: `${Math.round(top)}px`,
|
||||
left: `${Math.round(left)}px`,
|
||||
width: `${Math.round(width)}px`
|
||||
}
|
||||
}
|
||||
|
||||
function open() {
|
||||
if (closeTimer) {
|
||||
clearTimeout(closeTimer)
|
||||
closeTimer = null
|
||||
}
|
||||
show.value = true
|
||||
nextTick(place)
|
||||
}
|
||||
|
||||
function close() {
|
||||
show.value = false
|
||||
}
|
||||
|
||||
function scheduleClose() {
|
||||
if (closeTimer) clearTimeout(closeTimer)
|
||||
closeTimer = setTimeout(close, 160)
|
||||
}
|
||||
|
||||
function onFocusOut(event: FocusEvent) {
|
||||
const next = event.relatedTarget as Node | null
|
||||
if (root.value?.contains(next) || panel.value?.contains(next)) return
|
||||
scheduleClose()
|
||||
}
|
||||
|
||||
watch(show, (value) => {
|
||||
if (typeof window === 'undefined') return
|
||||
if (value) {
|
||||
window.addEventListener('resize', place)
|
||||
window.addEventListener('scroll', place, true)
|
||||
return
|
||||
}
|
||||
window.removeEventListener('resize', place)
|
||||
window.removeEventListener('scroll', place, true)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (closeTimer) clearTimeout(closeTimer)
|
||||
if (typeof window === 'undefined') return
|
||||
window.removeEventListener('resize', place)
|
||||
window.removeEventListener('scroll', place, true)
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div class="mb-4 grid grid-cols-3 gap-3">
|
||||
<NuxtLink
|
||||
to="/?studio=video"
|
||||
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'"
|
||||
>
|
||||
<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>
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/?studio=image"
|
||||
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'"
|
||||
>
|
||||
<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>
|
||||
</NuxtLink>
|
||||
<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'"
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
current: 'video' | 'image' | 'music'
|
||||
}>()
|
||||
</script>
|
||||
Reference in New Issue
Block a user