diff --git a/pages/index.vue b/pages/index.vue index 36c271f..dc0644b 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -2227,7 +2227,7 @@ import { VIDEO_CFG_STEP, type GenerationPreset } from '~/utils/generationPresets' -import { LOAD_QUEUED_JOB_KEY } from '~/utils/queuedJob' +import { LOAD_GENERATION_PAYLOAD_KEY, LOAD_QUEUED_JOB_KEY } from '~/utils/queuedJob' import { clipSettingsRows, inferStillPipeline, @@ -4400,6 +4400,19 @@ function applyIncomingDirectorScript() { } async function applyIncomingQueuedJob() { + try { + const raw = sessionStorage.getItem(LOAD_GENERATION_PAYLOAD_KEY) + if (raw) { + sessionStorage.removeItem(LOAD_GENERATION_PAYLOAD_KEY) + const loaded = JSON.parse(raw) as { kind?: string; payload?: Record } + if (loaded?.payload) { + await restoreStudioPayload(loaded.kind || 'video', loaded.payload) + toast('Saved generation loaded into Input.') + return + } + } + } catch { /* fall through to queue id */ } + let id = '' try { id = sessionStorage.getItem(LOAD_QUEUED_JOB_KEY) || '' @@ -5376,7 +5389,16 @@ async function restoreStudioEditJob(payload: { async function restoreStudioJob(id: string) { const job = await $fetch<{ - payload?: { + payload?: Parameters[1] + kind?: string + imagePipeline?: string + }>(`/api/studio-queue/${id}`) + const payload = job.payload + if (!payload) throw new Error('That job has no saved inputs') + await restoreStudioPayload(job.kind || (payload.imagePipeline === 'v2' ? 'edit' : 'video'), payload) +} + +async function restoreStudioPayload(kind: string, payload: { prompt?: string name?: string folderId?: string @@ -5423,13 +5445,8 @@ async function restoreStudioJob(id: string) { scaleMegapixels?: number steps?: number referenceStillId?: string - } - kind?: string - imagePipeline?: string - }>(`/api/studio-queue/${id}`) - const payload = job.payload - if (!payload) throw new Error('That job has no saved inputs') - if (job.kind === 'edit' || payload.imagePipeline === 'v2') { + }) { + if (kind === 'edit' || payload.imagePipeline === 'v2') { await restoreStudioEditJob(payload) return } diff --git a/pages/music.vue b/pages/music.vue index 9b0533b..eb943a6 100644 --- a/pages/music.vue +++ b/pages/music.vue @@ -244,7 +244,7 @@ import { } from '~/utils/music' import { ensureGenerationNotifyPermission, notifyGenerationComplete } from '~/utils/generationNotify' import type { LibraryFolder } from '~/utils/libraryBrowse' -import { LOAD_MUSIC_JOB_KEY } from '~/utils/queuedJob' +import { LOAD_GENERATION_PAYLOAD_KEY, LOAD_MUSIC_JOB_KEY } from '~/utils/queuedJob' import type { GenerationPreset, MusicPresetSettings } from '~/utils/generationPresets' const tagsPlaceholder = DEFAULT_MUSIC_TAGS @@ -566,6 +566,28 @@ watch(instrumental, (on) => { }) function applyIncomingMusic() { + try { + const genRaw = sessionStorage.getItem(LOAD_GENERATION_PAYLOAD_KEY) + if (genRaw) { + const loaded = JSON.parse(genRaw) as { kind?: string; payload?: Record } + if (loaded?.kind === 'music' && loaded.payload) { + sessionStorage.removeItem(LOAD_GENERATION_PAYLOAD_KEY) + const payload = loaded.payload + if (typeof payload.prompt === 'string') tags.value = payload.prompt + if (typeof payload.lyrics === 'string') lyrics.value = payload.lyrics + instrumental.value = payload.instrumental === true + if (typeof payload.duration === 'number') duration.value = payload.duration + if (typeof payload.steps === 'number') steps.value = payload.steps + if (payload.seed != null) seed.value = String(payload.seed) + if (typeof payload.name === 'string') name.value = payload.name + if (payload.folderId && folders.value.some(folder => folder.id === payload.folderId)) folderId.value = payload.folderId + if (payload.musicEngine || payload.engine) applyEngine(parseMusicEngine(payload.musicEngine || payload.engine)) + status.value = 'Loaded from generation log' + return + } + } + } catch { /* fall through */ } + try { const raw = sessionStorage.getItem(LOAD_MUSIC_JOB_KEY) if (!raw) return diff --git a/pages/queue.vue b/pages/queue.vue index 567e6b2..0a1dfb2 100644 --- a/pages/queue.vue +++ b/pages/queue.vue @@ -374,6 +374,58 @@ + +
+
+

Recent generations

+

+ Kept even after the queue clears or a zombie job is wiped. Re-queue to run again, or load the prompt into Studio. +

+
+
    +
  • +
    +

    + {{ logKindLabel(entry) }} · {{ logStatusLabel(entry.status) }} + · {{ formatLogWhen(entry.updatedAt || entry.createdAt) }} +

    +

    {{ entry.name || 'Untitled' }}

    +

    {{ promptSnippet(entry.prompt) }}

    +

    {{ entry.lastError }}

    +
    +
    + + + +
    +
  • +
+
@@ -420,6 +472,7 @@