fix: Don't hide PTZ control menu button unnecessarily (#1823)
- Closes: #1819
This commit is contained in:
@@ -74,7 +74,7 @@ live:
|
|||||||
| `hide_home` | `false` | When `true` the Home button of the control is hidden |
|
| `hide_home` | `false` | When `true` the Home button of the control is hidden |
|
||||||
| `hide_pan_tilt` | `false` | When `true` the Pan & Tilt buttons of the control is hidden |
|
| `hide_pan_tilt` | `false` | When `true` the Pan & Tilt buttons of the control is hidden |
|
||||||
| `hide_zoom` | `false` | When `true` the Zoom button of the control is hidden |
|
| `hide_zoom` | `false` | When `true` the Zoom button of the control is hidden |
|
||||||
| `mode` | `auto` | If `on` or `off` will always or never show PTZ controls respectively, if `auto` will show PTZ controls only if the camera supports real PTZ. |
|
| `mode` | `auto` | If `on` or `off`, by default will always or never show PTZ controls respectively, if `auto` will show PTZ controls only if the camera supports real PTZ. |
|
||||||
| `orientation` | `horizontal` | Whether to show a `vertical` or `horizontal` PTZ control. |
|
| `orientation` | `horizontal` | Whether to show a `vertical` or `horizontal` PTZ control. |
|
||||||
| `position` | `bottom-right` | Whether to position the control on the `top-left`, `top-right`, `bottom-left` or `bottom-right`. This may be overridden by using the `style` parameter to precisely control placement. |
|
| `position` | `bottom-right` | Whether to position the control on the `top-left`, `top-right`, `bottom-left` or `bottom-right`. This may be overridden by using the `style` parameter to precisely control placement. |
|
||||||
| `style` | | Optionally position and style the element using CSS. Similar to [Picture Element styling](https://www.home-assistant.io/dashboards/picture-elements/#how-to-use-the-style-object), except without any default, e.g. `left: 42%` |
|
| `style` | | Optionally position and style the element using CSS. Similar to [Picture Element styling](https://www.home-assistant.io/dashboards/picture-elements/#how-to-use-the-style-object), except without any default, e.g. `left: 42%` |
|
||||||
|
|||||||
@@ -582,20 +582,20 @@ export class MenuButtonController {
|
|||||||
? config.media_viewer.controls.ptz
|
? config.media_viewer.controls.ptz
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
if (!view || !ptzConfig || ptzConfig.mode === 'off') {
|
if (!view || !ptzConfig) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ptzTarget = getPTZTarget(view, {
|
const ptzTarget = getPTZTarget(view, {
|
||||||
cameraManager: cameraManager,
|
cameraManager: cameraManager,
|
||||||
...(ptzConfig.mode === 'auto' && { type: 'ptz' }),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ptzTarget) {
|
if (ptzTarget) {
|
||||||
const isOn =
|
const isOn =
|
||||||
view.context?.ptzControls?.enabled !== false &&
|
view.context?.ptzControls?.enabled !== undefined
|
||||||
(ptzConfig.mode === 'on' ||
|
? view.context.ptzControls.enabled
|
||||||
(ptzConfig.mode === 'auto' && ptzTarget.type === 'ptz'));
|
: ptzConfig.mode === 'on' ||
|
||||||
|
(ptzConfig.mode === 'auto' && ptzTarget.type === 'ptz');
|
||||||
return {
|
return {
|
||||||
icon: 'mdi:pan',
|
icon: 'mdi:pan',
|
||||||
...config.menu.buttons.ptz_controls,
|
...config.menu.buttons.ptz_controls,
|
||||||
|
|||||||
@@ -1428,26 +1428,7 @@ describe('MenuButtonController', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('should have show ptz button', () => {
|
describe('should have show ptz button', () => {
|
||||||
it('when the selected camera is not PTZ enabled', () => {
|
it('should not show when not in live view', () => {
|
||||||
const store = createStore([
|
|
||||||
{
|
|
||||||
cameraID: 'camera-1',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const buttons = calculateButtons(controller, {
|
|
||||||
cameraManager: createCameraManager(store),
|
|
||||||
view: createView({ view: 'live' }),
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(buttons).not.toContainEqual(
|
|
||||||
expect.objectContaining({
|
|
||||||
title: 'Show PTZ controls',
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('when not in live view', () => {
|
|
||||||
const store = createStore([
|
const store = createStore([
|
||||||
{
|
{
|
||||||
cameraID: 'camera-1',
|
cameraID: 'camera-1',
|
||||||
@@ -1467,7 +1448,7 @@ describe('MenuButtonController', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('when the selected camera is PTZ enabled', () => {
|
it('should show when in live view', () => {
|
||||||
const store = createStore([
|
const store = createStore([
|
||||||
{
|
{
|
||||||
cameraID: 'camera-1',
|
cameraID: 'camera-1',
|
||||||
@@ -1477,6 +1458,31 @@ describe('MenuButtonController', () => {
|
|||||||
|
|
||||||
const buttons = calculateButtons(controller, {
|
const buttons = calculateButtons(controller, {
|
||||||
cameraManager: createCameraManager(store),
|
cameraManager: createCameraManager(store),
|
||||||
|
view: createView({ view: 'live' }),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(buttons).toContainEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
title: 'Show PTZ controls',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show when the context has PTZ enabled', () => {
|
||||||
|
const store = createStore([
|
||||||
|
{
|
||||||
|
cameraID: 'camera-1',
|
||||||
|
capabilities: new Capabilities({ ptz: { left: ['relative'] } }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const view = createView({
|
||||||
|
camera: 'camera-1',
|
||||||
|
context: { ptzControls: { enabled: true } },
|
||||||
|
});
|
||||||
|
const buttons = calculateButtons(controller, {
|
||||||
|
cameraManager: createCameraManager(store),
|
||||||
|
view: view,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(buttons).toContainEqual({
|
expect(buttons).toContainEqual({
|
||||||
@@ -1496,7 +1502,7 @@ describe('MenuButtonController', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('when the context has PTZ disabled', () => {
|
it('should show when the context has PTZ disabled', () => {
|
||||||
const store = createStore([
|
const store = createStore([
|
||||||
{
|
{
|
||||||
cameraID: 'camera-1',
|
cameraID: 'camera-1',
|
||||||
@@ -1528,7 +1534,41 @@ describe('MenuButtonController', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('when a substream is PTZ enabled', () => {
|
it('should detect current status without context in auto mode', () => {
|
||||||
|
const store = createStore([
|
||||||
|
{
|
||||||
|
cameraID: 'camera-1',
|
||||||
|
capabilities: new Capabilities({ ptz: { left: ['relative'] } }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const view = createView({
|
||||||
|
camera: 'camera-1',
|
||||||
|
});
|
||||||
|
const buttons = calculateButtons(controller, {
|
||||||
|
cameraManager: createCameraManager(store),
|
||||||
|
config: createConfig({ live: { controls: { ptz: { mode: 'auto' } } } }),
|
||||||
|
view: view,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(buttons).toContainEqual({
|
||||||
|
enabled: false,
|
||||||
|
icon: 'mdi:pan',
|
||||||
|
priority: 50,
|
||||||
|
style: {
|
||||||
|
color: 'var(--frigate-card-menu-button-active-color)',
|
||||||
|
},
|
||||||
|
tap_action: {
|
||||||
|
action: 'fire-dom-event',
|
||||||
|
frigate_card_action: 'ptz_controls',
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
title: 'Show PTZ controls',
|
||||||
|
type: 'custom:frigate-card-menu-icon',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show when a substream is PTZ enabled', () => {
|
||||||
const store = createStore([
|
const store = createStore([
|
||||||
{
|
{
|
||||||
cameraID: 'camera-1',
|
cameraID: 'camera-1',
|
||||||
|
|||||||
Reference in New Issue
Block a user