fix: Stop PTZ movement and browser key handling from fighting (#2674)

- Closes: #2623
This commit is contained in:
Dermot Duffy
2026-08-10 14:49:50 -07:00
committed by GitHub
parent a8aa9ec7c2
commit 3808a1b030
20 changed files with 822 additions and 148 deletions
@@ -538,7 +538,7 @@ describe('ConfigManager', () => {
view: {
keyboard_shortcuts: {
enabled: true,
ptz_home: { key: 'h' },
ptz_home: { key: 'q' },
},
},
overrides: [
@@ -552,39 +552,28 @@ describe('ConfigManager', () => {
manager.setConfig(config);
await flushPromises();
// Verify keyboard shortcuts automations were added initially with ptz_home
expect(addAutomationsSpy).toHaveBeenCalledWith(
expect.arrayContaining([
expect.objectContaining({
triggers: expect.arrayContaining([
expect.objectContaining({ trigger: 'key', key: 'h' }),
]),
actions: expect.arrayContaining([
expect.objectContaining({
advanced_camera_card_action: 'ptz_multi',
}),
]),
}),
]),
);
const hasKeyTrigger = (key: string): boolean =>
addAutomationsSpy.mock.calls.some((call) =>
call[0].some((automation: Automation) =>
automation.triggers.some(
(trig: Trigger) => trig.trigger === 'key' && trig.key === key,
),
),
);
// The configured binding, rather than the default one.
expect(hasKeyTrigger('q')).toBe(true);
addAutomationsSpy.mockClear();
// Trigger the override - keyboard_shortcuts should be deleted
// Trigger the override, which deletes the shortcut configuration.
stateManager.setState({ fullscreen: true });
await flushPromises();
// Verify newly added automations don't contain keyboard shortcuts (key: 'h')
// This confirms the override removed them (directly verified through add calls)
const addCalls = addAutomationsSpy.mock.calls;
const hasKeyboardShortcut = addCalls.some((call) =>
call[0].some((automation: Automation) =>
automation.triggers.some(
(trig: Trigger) => trig.trigger === 'key' && trig.key === 'h',
),
),
);
expect(hasKeyboardShortcut).toBe(false);
// Deleting the configuration restores the defaults rather than removing
// the shortcuts, so the loader re-runs and binds the default key.
expect(hasKeyTrigger('q')).toBe(false);
expect(hasKeyTrigger('h')).toBe(true);
});
it('should re-run folders loader when overrides change', async () => {
@@ -114,6 +114,55 @@ describe('setKeyboardShortcutsFromConfig', () => {
]);
});
it('should give the start and stop of a shortcut the same modifiers', () => {
const api = createCardAPI();
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
createConfig({
view: {
keyboard_shortcuts: {
enabled: true,
ptz_home: null,
ptz_right: null,
ptz_up: null,
ptz_down: null,
ptz_zoom_in: null,
ptz_zoom_out: null,
ptz_left: { key: 'z', ctrl: false, alt: false, meta: false },
},
},
}),
);
setKeyboardShortcutsFromConfig(api);
const automations = vi.mocked(api.getAutomationsManager().addAutomations).mock
.calls[0][0];
expect(automations.map((automation) => automation.triggers)).toEqual([
[
{
trigger: 'key',
key: 'z',
state: 'down',
ctrl: false,
alt: false,
meta: false,
shift: undefined,
},
],
[
{
trigger: 'key',
key: 'z',
state: 'up',
ctrl: false,
alt: false,
meta: false,
shift: undefined,
},
],
]);
});
it('ptz_home', () => {
const api = createCardAPI();
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(createConfig());
@@ -134,11 +183,11 @@ describe('setKeyboardShortcutsFromConfig', () => {
],
triggers: [
{
alt: undefined,
alt: false,
trigger: 'key',
ctrl: undefined,
ctrl: false,
key: 'h',
meta: undefined,
meta: false,
shift: undefined,
state: 'down',
},