Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions src/renderer/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,10 @@ export function sessionSnapshot(state: AppState, genResults: string[]): unknown
}
return {
version: SESSION_VERSION,
category: state.category,
operation: state.operation,
lastOperation: state.lastOperation,
// The category and its operation are deliberately NOT persisted as such:
// the app always launches into the first category, and each category's
// sub-page rides in lastOperation (kept current by setOperation).
lastOperation: { ...state.lastOperation, [state.category]: state.operation },
options: state.options,
queues,
genResults: genResults.slice(0, MAX_GEN)
Expand All @@ -231,8 +232,6 @@ function isValidItem(i: unknown): i is QueueItem {
}

interface PersistedSession {
category: CategoryId
operation: string
lastOperation: Partial<Record<CategoryId, string>>
options: Record<WorkspaceKey, JobOptions>
queues: AppState['queues']
Expand All @@ -254,12 +253,14 @@ export function parseSession(raw: unknown): { state: AppState; genResults: strin
return false
}
}
// Two independent checks: a renamed OPERATION must not also discard the
// persisted category.
const category = validCat(p.category) ? p.category : FIRST_CATEGORY
const operation = findOperation(category, p.operation)
? p.operation
: defaultOperation(category)
// Always launch into the FIRST category (owner decision: coming back to
// the remembered one felt wrong). What IS remembered is each category's
// last sub-page: Images still opens on Generate if that is where it was,
// and switching to Video lands on its own remembered operation.
const category = FIRST_CATEGORY
const remembered = (p.lastOperation ?? {})[category]
const operation =
remembered && findOperation(category, remembered) ? remembered : defaultOperation(category)
// Drop queues for categories no longer in the catalog (a removed/renamed tool).
const queues: AppState['queues'] = {}
for (const [cat, q] of Object.entries(p.queues ?? {})) {
Expand Down
29 changes: 26 additions & 3 deletions test/session-persist.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,33 @@ describe('session persistence round-trip', () => {
expect(pruned.state.queues.images!.selected).toEqual([])
})

it('falls back to a valid category/operation when the persisted one is invalid', () => {
const snap = sessionSnapshot(initialState, []) as Record<string, unknown>
const parsed = parseSession({ ...snap, category: 'nonsense', operation: 'nope' })
it('always launches into the first category, whatever was open at close', () => {
// The category itself is not restored - only each category's sub-page is.
const state: AppState = { ...initialState, category: 'video', operation: 'compress' }
const parsed = parseSession(sessionSnapshot(state, []))
expect(parsed).not.toBeNull()
expect(parsed!.state.category).toBe('images')
})

it("remembers each category's last sub-page, including the one open at close", () => {
const state: AppState = {
...initialState,
category: 'video',
operation: 'compress',
lastOperation: { images: 'generate', video: 'compress' }
}
const parsed = parseSession(sessionSnapshot(state, []))
// Launches into Images ON its remembered sub-page...
expect(parsed!.state.category).toBe('images')
expect(parsed!.state.operation).toBe('generate')
// ...and Video's sub-page survives for when the user switches to it.
expect(parsed!.state.lastOperation.video).toBe('compress')
})

it('falls back to the default operation when the remembered one is gone', () => {
const state: AppState = { ...initialState, lastOperation: { images: 'renamed-away' } }
const parsed = parseSession(sessionSnapshot(state, []))
expect(parsed!.state.category).toBe('images')
expect(parsed!.state.operation).toBe('convert')
})
})
Loading