1 parent
dacde91f3a
commit
c9c7e93e19
3 files changed
+108
-10
No files matched your search
@@ -96,6 +96,7 @@ export class QueryStringManager {
|
|||||||
protected _getActions(): AdvancedCameraCardCustomActionConfig[] {
|
protected _getActions(): AdvancedCameraCardCustomActionConfig[] {
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const actions: AdvancedCameraCardCustomActionConfig[] = [];
|
const actions: AdvancedCameraCardCustomActionConfig[] = [];
|
||||||
|
const configuredCardID = this._api.getConfigManager().getConfig()?.card_id;
|
||||||
const actionRE = new RegExp(
|
const actionRE = new RegExp(
|
||||||
/^(advanced-camera-card|frigate-card)-action([.:](?<cardID>\w+))?[.:](?<action>\w+)/,
|
/^(advanced-camera-card|frigate-card)-action([.:](?<cardID>\w+))?[.:](?<action>\w+)/,
|
||||||
);
|
);
|
||||||
@@ -107,14 +108,17 @@ export class QueryStringManager {
|
|||||||
const cardID: string | undefined = match.groups['cardID'];
|
const cardID: string | undefined = match.groups['cardID'];
|
||||||
const actionName = match.groups['action'];
|
const actionName = match.groups['action'];
|
||||||
|
|
||||||
|
// Skip actions targeted at other cards.
|
||||||
|
if (cardID && cardID !== configuredCardID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let action: AdvancedCameraCardCustomActionConfig | null = null;
|
let action: AdvancedCameraCardCustomActionConfig | null = null;
|
||||||
switch (actionName) {
|
switch (actionName) {
|
||||||
case 'camera_select':
|
case 'camera_select':
|
||||||
case 'live_substream_select':
|
case 'live_substream_select':
|
||||||
if (value) {
|
if (value) {
|
||||||
action = createCameraAction(actionName, value, {
|
action = createCameraAction(actionName, value, { cardID });
|
||||||
cardID: cardID,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'camera_ui':
|
case 'camera_ui':
|
||||||
@@ -122,9 +126,7 @@ export class QueryStringManager {
|
|||||||
case 'download':
|
case 'download':
|
||||||
case 'expand':
|
case 'expand':
|
||||||
case 'menu_toggle':
|
case 'menu_toggle':
|
||||||
action = createGeneralAction(actionName, {
|
action = createGeneralAction(actionName, { cardID });
|
||||||
cardID: cardID,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case 'clip':
|
case 'clip':
|
||||||
case 'clips':
|
case 'clips':
|
||||||
@@ -136,9 +138,7 @@ export class QueryStringManager {
|
|||||||
case 'snapshot':
|
case 'snapshot':
|
||||||
case 'snapshots':
|
case 'snapshots':
|
||||||
case 'timeline':
|
case 'timeline':
|
||||||
action = createViewAction(actionName, {
|
action = createViewAction(actionName, { cardID });
|
||||||
cardID: cardID,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn(
|
console.warn(
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ export interface CardMicrophoneAPI {
|
|||||||
export interface CardQueryStringAPI {
|
export interface CardQueryStringAPI {
|
||||||
getActionsManager(): ActionsManager;
|
getActionsManager(): ActionsManager;
|
||||||
getCardElementManager(): CardElementManager;
|
getCardElementManager(): CardElementManager;
|
||||||
|
getConfigManager(): ConfigManager;
|
||||||
getViewManager(): ViewManager;
|
getViewManager(): ViewManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { mock } from 'vitest-mock-extended';
|
import { mock } from 'vitest-mock-extended';
|
||||||
|
import { CardController } from '../../src/card-controller/controller';
|
||||||
import { QueryStringManager } from '../../src/card-controller/query-string-manager';
|
import { QueryStringManager } from '../../src/card-controller/query-string-manager';
|
||||||
import { SubstreamSelectViewModifier } from '../../src/card-controller/view/modifiers/substream-select';
|
import { SubstreamSelectViewModifier } from '../../src/card-controller/view/modifiers/substream-select';
|
||||||
import { createCardAPI } from '../test-utils';
|
import { createCardAPI, createConfig } from '../test-utils';
|
||||||
|
|
||||||
const setQueryString = (qs: string): void => {
|
const setQueryString = (qs: string): void => {
|
||||||
const location: Location = mock<Location>();
|
const location: Location = mock<Location>();
|
||||||
@@ -11,6 +12,14 @@ const setQueryString = (qs: string): void => {
|
|||||||
vi.spyOn(window, 'location', 'get').mockReturnValue(location);
|
vi.spyOn(window, 'location', 'get').mockReturnValue(location);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setCardID = (api: CardController, cardID: string): void => {
|
||||||
|
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(
|
||||||
|
createConfig({
|
||||||
|
card_id: cardID,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// @vitest-environment jsdom
|
// @vitest-environment jsdom
|
||||||
describe('QueryStringManager', () => {
|
describe('QueryStringManager', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -45,6 +54,7 @@ describe('QueryStringManager', () => {
|
|||||||
])('%s', async (viewName: string) => {
|
])('%s', async (viewName: string) => {
|
||||||
setQueryString(`?advanced-camera-card-action.id.${viewName}=`);
|
setQueryString(`?advanced-camera-card-action.id.${viewName}=`);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
|
|
||||||
// View actions do not need the card to have been updated.
|
// View actions do not need the card to have been updated.
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
||||||
@@ -71,6 +81,7 @@ describe('QueryStringManager', () => {
|
|||||||
])('%s', async (action: string) => {
|
])('%s', async (action: string) => {
|
||||||
setQueryString(`?advanced-camera-card-action.id.${action}=`);
|
setQueryString(`?advanced-camera-card-action.id.${action}=`);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -92,6 +103,7 @@ describe('QueryStringManager', () => {
|
|||||||
it('should execute view default action', async () => {
|
it('should execute view default action', async () => {
|
||||||
setQueryString('?advanced-camera-card-action.id.default=');
|
setQueryString('?advanced-camera-card-action.id.default=');
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
// View actions do not need the card to have been updated.
|
// View actions do not need the card to have been updated.
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
||||||
|
|
||||||
@@ -109,6 +121,7 @@ describe('QueryStringManager', () => {
|
|||||||
it('should execute camera_select action', async () => {
|
it('should execute camera_select action', async () => {
|
||||||
setQueryString('?advanced-camera-card-action.id.camera_select=camera.office');
|
setQueryString('?advanced-camera-card-action.id.camera_select=camera.office');
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -130,6 +143,7 @@ describe('QueryStringManager', () => {
|
|||||||
'?advanced-camera-card-action.id.live_substream_select=camera.office_hd',
|
'?advanced-camera-card-action.id.live_substream_select=camera.office_hd',
|
||||||
);
|
);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -152,6 +166,7 @@ describe('QueryStringManager', () => {
|
|||||||
async (action: string) => {
|
async (action: string) => {
|
||||||
setQueryString(`?advanced-camera-card-action.id.${action}=`);
|
setQueryString(`?advanced-camera-card-action.id.${action}=`);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -170,6 +185,7 @@ describe('QueryStringManager', () => {
|
|||||||
|
|
||||||
setQueryString('?advanced-camera-card-action.id.not_an_action=value');
|
setQueryString('?advanced-camera-card-action.id.not_an_action=value');
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -197,6 +213,7 @@ describe('QueryStringManager', () => {
|
|||||||
])('%s', async (viewName: string) => {
|
])('%s', async (viewName: string) => {
|
||||||
setQueryString(`?advanced-camera-card-action.id.${viewName}=`);
|
setQueryString(`?advanced-camera-card-action.id.${viewName}=`);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -221,6 +238,7 @@ describe('QueryStringManager', () => {
|
|||||||
'&advanced-camera-card-action.id.camera_select=camera.kitchen',
|
'&advanced-camera-card-action.id.camera_select=camera.kitchen',
|
||||||
);
|
);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -241,6 +259,7 @@ describe('QueryStringManager', () => {
|
|||||||
'&advanced-camera-card-action.id.camera_select=camera.office',
|
'&advanced-camera-card-action.id.camera_select=camera.office',
|
||||||
);
|
);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -259,6 +278,7 @@ describe('QueryStringManager', () => {
|
|||||||
'?advanced-camera-card-action.id.live_substream_select=camera.office_hd',
|
'?advanced-camera-card-action.id.live_substream_select=camera.office_hd',
|
||||||
);
|
);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
const manager = new QueryStringManager(api);
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
@@ -282,6 +302,7 @@ describe('QueryStringManager', () => {
|
|||||||
it('should execute actions with old frigate-card-action key', async () => {
|
it('should execute actions with old frigate-card-action key', async () => {
|
||||||
setQueryString(`?frigate-card-action.id.clips=`);
|
setQueryString(`?frigate-card-action.id.clips=`);
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'id');
|
||||||
|
|
||||||
// View actions do not need the card to have been updated.
|
// View actions do not need the card to have been updated.
|
||||||
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
||||||
@@ -297,4 +318,80 @@ describe('QueryStringManager', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('should filter by card_id', () => {
|
||||||
|
it('should execute view action when card_id matches', async () => {
|
||||||
|
setQueryString('?advanced-camera-card-action.my_card.clips=');
|
||||||
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'my_card');
|
||||||
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
||||||
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
|
expect(manager.hasViewRelatedActionsToRun()).toBeTruthy();
|
||||||
|
await manager.executeIfNecessary();
|
||||||
|
|
||||||
|
expect(api.getViewManager().setViewByParametersWithNewQuery).toBeCalledWith({
|
||||||
|
params: {
|
||||||
|
view: 'clips',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT execute view action when card_id does not match', async () => {
|
||||||
|
setQueryString('?advanced-camera-card-action.other_card.clips=');
|
||||||
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'my_card');
|
||||||
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
||||||
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
|
expect(manager.hasViewRelatedActionsToRun()).toBeFalsy();
|
||||||
|
await manager.executeIfNecessary();
|
||||||
|
|
||||||
|
expect(api.getViewManager().setViewByParametersWithNewQuery).not.toBeCalled();
|
||||||
|
expect(api.getActionsManager().executeActions).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute action without card_id on any card', async () => {
|
||||||
|
setQueryString('?advanced-camera-card-action.clips=');
|
||||||
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'my_card');
|
||||||
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
||||||
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
|
expect(manager.hasViewRelatedActionsToRun()).toBeTruthy();
|
||||||
|
await manager.executeIfNecessary();
|
||||||
|
|
||||||
|
expect(api.getViewManager().setViewByParametersWithNewQuery).toBeCalledWith({
|
||||||
|
params: {
|
||||||
|
view: 'clips',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT execute non-view action when card_id does not match', async () => {
|
||||||
|
setQueryString('?advanced-camera-card-action.other_card.menu_toggle=');
|
||||||
|
const api = createCardAPI();
|
||||||
|
setCardID(api, 'my_card');
|
||||||
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(true);
|
||||||
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
|
expect(manager.hasViewRelatedActionsToRun()).toBeFalsy();
|
||||||
|
await manager.executeIfNecessary();
|
||||||
|
|
||||||
|
expect(api.getActionsManager().executeActions).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute action when card has no card_id and URL has card_id', async () => {
|
||||||
|
setQueryString('?advanced-camera-card-action.some_card.clips=');
|
||||||
|
const api = createCardAPI();
|
||||||
|
vi.mocked(api.getCardElementManager().hasUpdated).mockReturnValue(false);
|
||||||
|
const manager = new QueryStringManager(api);
|
||||||
|
|
||||||
|
// Should NOT execute since URL targets 'some_card' but this card has no card_id
|
||||||
|
expect(manager.hasViewRelatedActionsToRun()).toBeFalsy();
|
||||||
|
await manager.executeIfNecessary();
|
||||||
|
|
||||||
|
expect(api.getViewManager().setViewByParametersWithNewQuery).not.toBeCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user