feat(09-02): add frontend keyboard shortcut service, store, and controller
- 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
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
||||
import type { ShortcutsState } from '../shortcuts-store';
|
||||
import { shortcutsStore } from '../shortcuts-store';
|
||||
|
||||
/**
|
||||
* ShortcutsController connects a Lit component to the ShortcutsStore.
|
||||
*
|
||||
* Use this controller in components that need to read or change
|
||||
* shortcut bindings (e.g. the shortcut settings UI in config-page).
|
||||
*/
|
||||
export class ShortcutsController implements ReactiveController {
|
||||
private host: ReactiveControllerHost;
|
||||
private unsubscribe?: () => void;
|
||||
|
||||
constructor(host: ReactiveControllerHost) {
|
||||
this.host = host;
|
||||
host.addController(this);
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// LIFECYCLE HOOKS
|
||||
// ===================================================================
|
||||
|
||||
hostConnected(): void {
|
||||
this.unsubscribe = shortcutsStore.subscribe(() => {
|
||||
this.host.requestUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
hostDisconnected(): void {
|
||||
this.unsubscribe?.();
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// STATE ACCESSORS
|
||||
// ===================================================================
|
||||
|
||||
get state(): Readonly<ShortcutsState> {
|
||||
return shortcutsStore.getState();
|
||||
}
|
||||
|
||||
get bindings(): Map<string, string> {
|
||||
return shortcutsStore.getBindings();
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// ACTIONS
|
||||
// ===================================================================
|
||||
|
||||
async updateBinding(
|
||||
action: string,
|
||||
key: string,
|
||||
): Promise<void> {
|
||||
await shortcutsStore.updateBinding(action, key);
|
||||
}
|
||||
|
||||
async resetAll(): Promise<void> {
|
||||
await shortcutsStore.resetAll();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user