Put default video length on the main Settings panel and let Studio save it.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<Thumbwheel
|
||||
v-model="model"
|
||||
:label="label || 'Duration'"
|
||||
lock-key="duration"
|
||||
:lock-key="lockKey || 'duration'"
|
||||
:min="MIN"
|
||||
:max="MAX"
|
||||
:step="0.1"
|
||||
@@ -24,9 +24,11 @@ const MAX = 120
|
||||
withDefaults(defineProps<{
|
||||
label?: string
|
||||
hint?: string
|
||||
lockKey?: string
|
||||
}>(), {
|
||||
label: '',
|
||||
hint: ''
|
||||
hint: '',
|
||||
lockKey: 'duration'
|
||||
})
|
||||
|
||||
const model = defineModel<number>({ required: true })
|
||||
|
||||
+12
-12
@@ -21,7 +21,7 @@
|
||||
>{{ notice }}</p>
|
||||
|
||||
<section v-if="activePanel === 'gpu'" class="glass rounded-3xl p-5 sm:p-6">
|
||||
<h2 class="font-display text-xl font-bold">GPU</h2>
|
||||
<h2 class="font-display text-xl font-bold">GPU & defaults</h2>
|
||||
<div class="mt-4 space-y-3 rounded-2xl border border-white/10 bg-zinc-950/50 px-4 py-3">
|
||||
<p class="text-sm text-zinc-400">
|
||||
Stops Comfy on the desktop GPU so it drops out of VRAM. The PC stays on. Generate or Wake GPU will start it again.
|
||||
@@ -66,19 +66,20 @@
|
||||
</span>
|
||||
</label>
|
||||
<p v-if="notifyMessage" class="mt-2 text-xs text-zinc-500">{{ notifyMessage }}</p>
|
||||
</section>
|
||||
|
||||
<section v-if="activePanel === 'studio'" class="glass rounded-3xl p-5 sm:p-6">
|
||||
<h2 class="font-display text-xl font-bold">Studio</h2>
|
||||
<p class="mt-1 text-sm text-zinc-400">Defaults for new video jobs. Extend still copies the length of the clip you are extending.</p>
|
||||
<div class="mt-4 max-w-xs rounded-2xl border border-white/10 bg-zinc-950/50 px-4 py-3">
|
||||
<div class="mt-6 border-t border-white/10 pt-5">
|
||||
<h3 class="text-sm font-semibold text-zinc-200">Default video length</h3>
|
||||
<p class="mt-1 text-xs text-zinc-500">New Studio jobs and new shot cards start at this length. Extend still copies the clip you are extending.</p>
|
||||
<div class="mt-3 max-w-xs">
|
||||
<DurationField
|
||||
v-model="defaultVideoDuration"
|
||||
label="Default video length"
|
||||
hint="Used when you open Studio or add a new shot. Extend uses the source clip’s length."
|
||||
label="Seconds"
|
||||
lock-key="default-video-duration"
|
||||
@update:model-value="onDefaultVideoDuration"
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-zinc-500">Saved as {{ defaultVideoDuration }}s for this browser.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section v-if="activePanel === 'storage'" class="glass rounded-3xl p-5 sm:p-6">
|
||||
@@ -409,7 +410,7 @@ export interface SettingsFolder {
|
||||
unlocked: boolean
|
||||
}
|
||||
|
||||
type SettingsPanel = 'gpu' | 'studio' | 'storage' | 'login' | 'folders' | 'loras' | 'keeps' | 'prompts'
|
||||
type SettingsPanel = 'gpu' | 'storage' | 'login' | 'folders' | 'loras' | 'keeps' | 'prompts'
|
||||
type LoraKindFilter = 'all' | 'image' | 'video'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -422,7 +423,7 @@ const notice = ref('')
|
||||
const noticeError = ref(false)
|
||||
let noticeTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const panelIds: SettingsPanel[] = ['gpu', 'studio', 'storage', 'login', 'folders', 'loras', 'keeps', 'prompts']
|
||||
const panelIds: SettingsPanel[] = ['gpu', 'storage', 'login', 'folders', 'loras', 'keeps', 'prompts']
|
||||
|
||||
function parsePanel(raw: unknown): SettingsPanel {
|
||||
const value = String(raw || '')
|
||||
@@ -443,8 +444,7 @@ const activePanel = computed({
|
||||
|
||||
const navItems = computed(() => {
|
||||
const items: Array<{ id: SettingsPanel; label: string }> = [
|
||||
{ id: 'gpu', label: 'GPU' },
|
||||
{ id: 'studio', label: 'Studio' },
|
||||
{ id: 'gpu', label: 'GPU & defaults' },
|
||||
{ id: 'storage', label: 'Storage' }
|
||||
]
|
||||
if (authMode.value === 'password') items.push({ id: 'login', label: 'Site login' })
|
||||
|
||||
+20
-1
@@ -1012,10 +1012,20 @@
|
||||
|
||||
<div v-if="studioMode === 'video'" class="space-y-4">
|
||||
<div class="grid grid-cols-1 items-start gap-3 sm:grid-cols-2">
|
||||
<div>
|
||||
<DurationField
|
||||
v-model="duration"
|
||||
label="Duration"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="mt-2 text-[11px] text-amber-200/90 hover:text-amber-100"
|
||||
title="Save this length as the default for new video jobs"
|
||||
@click="saveDurationAsDefault"
|
||||
>
|
||||
Save {{ duration }}s as default
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<Thumbwheel
|
||||
v-model="cfg"
|
||||
@@ -2302,7 +2312,8 @@ import {
|
||||
VIDEO_DURATION_DEFAULT,
|
||||
clampVideoDuration,
|
||||
clipPartDuration,
|
||||
defaultVideoDurationPref
|
||||
defaultVideoDurationPref,
|
||||
setDefaultVideoDurationPref
|
||||
} from '~/utils/videoDuration'
|
||||
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
@@ -2579,6 +2590,8 @@ function selectStudioKind(kind: 'video' | 'image') {
|
||||
studioMode.value = 'editv2'
|
||||
outputFocus.value = 'edit'
|
||||
}
|
||||
outputFocus.value = 'edit'
|
||||
}
|
||||
|
||||
function applyStudioQueryFromRoute() {
|
||||
const studio = String(route.query.studio || '').toLowerCase()
|
||||
@@ -4109,6 +4122,12 @@ function clampDuration(value: number) {
|
||||
return clampVideoDuration(value, defaultVideoDurationPref())
|
||||
}
|
||||
|
||||
function saveDurationAsDefault() {
|
||||
const next = setDefaultVideoDurationPref(duration.value)
|
||||
duration.value = next
|
||||
toast(`Default video length set to ${next}s`)
|
||||
}
|
||||
|
||||
function clampCfg(value: number) {
|
||||
return clampVideoCfg(value, turbo.value ? CFG_TURBO : CFG_QUALITY)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user