`index.ts` caches primary views and hides them with a class so
scrollTop survives navigation. Nothing else was told: `disconnectedCallback`
never fires for one, so everything written to clean up there never
cleans up. The worst case was not a leak — pressing `s` on Settings
skipped two albums out of the Autotag queue, and `a` on that same live
handler rewrites tags on disk.
- `utils/view-lifecycle.ts` is the missing half: `viewActivated` /
`viewDeactivated`, with `listenWhileActive`, `intervalWhileActive`
and `whileActive` torn down on the way out, and an off-screen view
that does not render. `registerViewAware` gives a shared reactive
controller the same treatment, because a controller cannot know
whether its host is a cached view — `ContextMenuController` bound
three document listeners in `hostConnected`, which for a cached host
is "forever".
- `services/shortcut-scope.ts` publishes the ambient scope. Resolving
scope from focus alone was not enough: this app is driven with the
mouse, focus sits on `<body>`, and a focus-only rule would have made
the panel keys work only after a click landed inside the panel.
- Global bindings yield to a focused control that owns the key —
button, select, slider, checkbox, menu, grid row, or anything inside
an open dialog — so the unmodified single-key bindings stop stealing
Space and the arrows.
- `utils/roving-grid.ts` gives a card grid one tab stop moved with the
arrows, since a card per tab stop makes a library-length tab
sequence.
- Add selectAll() method to SelectionController that selects all items via host interface
- Change app.selectAll dispatch from document.execCommand('selectAll') to CustomEvent('shortcut:select-all')
- Create keyboard-shortcut-service.ts singleton with keydown listener
- Shadow DOM active element resolution for scope detection
- Text input suppression (only Escape passes through)
- Scope resolution: text-input > panel-specific > global
- Action dispatch to player/queue stores and Wails bindings
- Create shortcuts-store.ts with Wails persistence and event sync
- Create shortcuts-controller.ts for Lit component integration
- Export store and controller from store/index.ts
- Replace hardcoded Ctrl+F handler in index.ts with service
- Initialize service via import in frontend/index.ts