Add default video length setting and inherit duration when extending.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-03 19:44:28 -05:00
co-authored by Cursor
parent a6756c1f1a
commit 86e23499a9
5 changed files with 116 additions and 25 deletions
+29 -2
View File
@@ -68,6 +68,19 @@
<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">
<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."
@update:model-value="onDefaultVideoDuration"
/>
</div>
</section>
<section v-if="activePanel === 'storage'" class="glass rounded-3xl p-5 sm:p-6">
<h2 class="font-display text-xl font-bold">Storage</h2>
<div class="mt-4 rounded-2xl border border-white/10 bg-zinc-950/50 px-4 py-3">
@@ -379,6 +392,13 @@ import {
type KeepPromptKind,
type KeepPromptLists
} from '~/utils/keepPrompts'
import {
VIDEO_DURATION_DEFAULT,
clampVideoDuration,
defaultVideoDurationPref,
setDefaultVideoDurationPref
} from '~/utils/videoDuration'
import { generationNotifyPref, setGenerationNotifyPref, generationNotifySupported, ensureGenerationNotifyPermission } from '~/utils/generationNotify'
export interface SettingsFolder {
id: string
@@ -389,7 +409,7 @@ export interface SettingsFolder {
unlocked: boolean
}
type SettingsPanel = 'gpu' | 'storage' | 'login' | 'folders' | 'loras' | 'keeps' | 'prompts'
type SettingsPanel = 'gpu' | 'studio' | 'storage' | 'login' | 'folders' | 'loras' | 'keeps' | 'prompts'
type LoraKindFilter = 'all' | 'image' | 'video'
const route = useRoute()
@@ -402,7 +422,7 @@ const notice = ref('')
const noticeError = ref(false)
let noticeTimer: ReturnType<typeof setTimeout> | null = null
const panelIds: SettingsPanel[] = ['gpu', 'storage', 'login', 'folders', 'loras', 'keeps', 'prompts']
const panelIds: SettingsPanel[] = ['gpu', 'studio', 'storage', 'login', 'folders', 'loras', 'keeps', 'prompts']
function parsePanel(raw: unknown): SettingsPanel {
const value = String(raw || '')
@@ -424,6 +444,7 @@ const activePanel = computed({
const navItems = computed(() => {
const items: Array<{ id: SettingsPanel; label: string }> = [
{ id: 'gpu', label: 'GPU' },
{ id: 'studio', label: 'Studio' },
{ id: 'storage', label: 'Storage' }
]
if (authMode.value === 'password') items.push({ id: 'login', label: 'Site login' })
@@ -480,6 +501,7 @@ const gpuError = ref(false)
const gpuMessage = ref('')
const notifyComplete = ref(true)
const notifyMessage = ref('')
const defaultVideoDuration = ref(VIDEO_DURATION_DEFAULT)
const storage = ref<{
libraryBytes: number
breakdown: { clips: number; stills: number; tmp: number; other: number }
@@ -554,6 +576,7 @@ async function loadAccount() {
onMounted(() => {
notifyComplete.value = generationNotifyPref()
defaultVideoDuration.value = defaultVideoDurationPref()
void loadAccount()
void loadPresets()
void loadStorage()
@@ -660,6 +683,10 @@ async function onNotifyCompleteChange() {
}
}
function onDefaultVideoDuration(value: number) {
defaultVideoDuration.value = setDefaultVideoDurationPref(value)
}
async function sleepGpu() {
if (gpuSleeping.value || gpuWaking.value) return
gpuSleeping.value = true