refactor: Unify substream actions into substream_{on,off} (#2497)
## Summary
- Collapse `live_substream_{on,off,select}` into a unified
`substream_{on,off}` pair, symmetric with `call_{start,end}`.
- Rename the `camera` field on the former `live_substream_select` to
`stream` (it always was a stream ID).
- Add optional `camera` field to both new actions for targeting a
non-selected base camera.
- YAML configs are migrated automatically; URL bookmarks must be updated
by hand.
## Migration
### Cycling between camera and substream (toggle button)
Before:
```yaml
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: live_substream_on
```
After:
```yaml
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: substream_on
```
### Selecting a specific substream
Before:
```yaml
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: live_substream_select
camera: camera.front_door_hd
```
After:
```yaml
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: substream_on
stream: camera.front_door_hd
```
### Turning the substream off
Before:
```yaml
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: live_substream_off
```
After:
```yaml
tap_action:
action: custom:advanced-camera-card-action
advanced_camera_card_action: substream_off
```
### URL querystrings (manual update required)
| Before | After |
| --- | --- |
|
`?advanced-camera-card-action.live_substream_select=camera.front_door_hd`
| `?advanced-camera-card-action.substream_on=camera.front_door_hd` |
This commit is contained in:
committed by
dermotduffy
parent
15e335a647
commit
f18e4cd4b8
@@ -1,21 +1,58 @@
|
||||
import { expect, it } from 'vitest';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { SubstreamOffAction } from '../../../../src/card-controller/actions/actions/substream-off';
|
||||
import { SubstreamViewModifier } from '../../../../src/card-controller/view/modifiers/substream';
|
||||
import { createCardAPI } from '../../../test-utils';
|
||||
import { applyViewModifiers } from '../../../../src/card-controller/view/modifiers';
|
||||
import { createSubstreamOffAction } from '../../../../src/utils/action';
|
||||
import { View } from '../../../../src/view/view';
|
||||
import { createCardAPI, createView } from '../../../test-utils';
|
||||
|
||||
it('should handle live_substream_off action', async () => {
|
||||
// Runs the off-action for `view` and applies the modifier it produces.
|
||||
const applySubstreamOff = async (
|
||||
view: View,
|
||||
options?: { camera?: string },
|
||||
): Promise<void> => {
|
||||
const api = createCardAPI();
|
||||
const action = new SubstreamOffAction(
|
||||
{},
|
||||
{
|
||||
action: 'fire-dom-event',
|
||||
advanced_camera_card_action: 'live_substream_off',
|
||||
},
|
||||
);
|
||||
vi.mocked(api.getViewManager().getView).mockReturnValue(view);
|
||||
|
||||
await action.execute(api);
|
||||
await new SubstreamOffAction({}, createSubstreamOffAction(options)).execute(api);
|
||||
|
||||
expect(api.getViewManager().setViewByParameters).toBeCalledWith({
|
||||
modifiers: [expect.any(SubstreamViewModifier)],
|
||||
const params = vi.mocked(api.getViewManager().setViewByParameters).mock.calls[0]?.[0];
|
||||
applyViewModifiers(view, params?.modifiers);
|
||||
};
|
||||
|
||||
describe('SubstreamOffAction', () => {
|
||||
it('should clear the selected camera override', async () => {
|
||||
const view = createView({
|
||||
view: 'live',
|
||||
camera: 'camera.office',
|
||||
context: {
|
||||
live: { overrides: new Map([['camera.office', 'camera.kitchen']]) },
|
||||
},
|
||||
});
|
||||
|
||||
await applySubstreamOff(view);
|
||||
|
||||
expect(view.context?.live?.overrides?.get('camera.office')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should clear an explicit camera override', async () => {
|
||||
const view = createView({
|
||||
view: 'live',
|
||||
camera: 'camera.driveway',
|
||||
context: {
|
||||
live: {
|
||||
overrides: new Map([
|
||||
['camera.office', 'camera.kitchen'],
|
||||
['camera.driveway', 'camera.driveway_hd'],
|
||||
]),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await applySubstreamOff(view, { camera: 'camera.office' });
|
||||
|
||||
expect(view.context?.live?.overrides?.get('camera.office')).toBeUndefined();
|
||||
expect(view.context?.live?.overrides?.get('camera.driveway')).toBe(
|
||||
'camera.driveway_hd',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user