Only import screenfull in a single place.
This commit is contained in:
+2
-1
@@ -195,8 +195,9 @@ class FrigateCard extends LitElement {
|
|||||||
this._config,
|
this._config,
|
||||||
this._controller.getCameraManager(),
|
this._controller.getCameraManager(),
|
||||||
view,
|
view,
|
||||||
this._controller.getExpandManager().isExpanded(),
|
|
||||||
{
|
{
|
||||||
|
inExpandedMode: this._controller.getExpandManager().isExpanded(),
|
||||||
|
inFullscreenMode: this._controller.getFullscreenManager().isInFullscreen(),
|
||||||
currentMediaLoadedInfo: this._controller.getMediaLoadedInfoManager().get(),
|
currentMediaLoadedInfo: this._controller.getMediaLoadedInfoManager().get(),
|
||||||
showCameraUIButton: this._controller.getCameraURLManager().hasCameraURL(),
|
showCameraUIButton: this._controller.getCameraURLManager().hasCameraURL(),
|
||||||
mediaPlayerController: this._controller.getMediaPlayerManager(),
|
mediaPlayerController: this._controller.getMediaPlayerManager(),
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// TODO: Test HA state connection/disconnect logic in real life.
|
|
||||||
// TODO: Should not need to import screenfull anywhere except the fullscreen manager.
|
|
||||||
// TODO: executeMediaQueryForView should not need a HTMLElement host parameter see the view-manager.ts call in particular.
|
// TODO: executeMediaQueryForView should not need a HTMLElement host parameter see the view-manager.ts call in particular.
|
||||||
// TODO: Split out zod schema and add tests for config parsing (e.g. view.scan.show_status argument was missing)
|
// TODO: Split out zod schema and add tests for config parsing (e.g. view.scan.show_status argument was missing)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { HomeAssistant } from 'custom-card-helpers';
|
import { HomeAssistant } from 'custom-card-helpers';
|
||||||
import { StyleInfo } from 'lit/directives/style-map';
|
import { StyleInfo } from 'lit/directives/style-map';
|
||||||
import screenfull from 'screenfull';
|
|
||||||
import { CameraManager } from '../camera-manager/manager';
|
import { CameraManager } from '../camera-manager/manager';
|
||||||
import { FRIGATE_BUTTON_MENU_ICON } from '../const';
|
import { FRIGATE_BUTTON_MENU_ICON } from '../const';
|
||||||
import { localize } from '../localize/localize.js';
|
import { localize } from '../localize/localize.js';
|
||||||
@@ -19,6 +18,15 @@ import { MediaPlayerManager } from './card-controller/media-player-manager';
|
|||||||
import { MicrophoneManager } from './card-controller/microphone-manager';
|
import { MicrophoneManager } from './card-controller/microphone-manager';
|
||||||
import { hasSubstream } from './substream';
|
import { hasSubstream } from './substream';
|
||||||
|
|
||||||
|
export interface MenuButtonControllerOptions {
|
||||||
|
currentMediaLoadedInfo?: MediaLoadedInfo | null;
|
||||||
|
showCameraUIButton?: boolean;
|
||||||
|
inFullscreenMode?: boolean;
|
||||||
|
inExpandedMode?: boolean;
|
||||||
|
microphoneManager?: MicrophoneManager | null;
|
||||||
|
mediaPlayerController?: MediaPlayerManager | null;
|
||||||
|
}
|
||||||
|
|
||||||
export class MenuButtonController {
|
export class MenuButtonController {
|
||||||
// Array of dynamic menu buttons to be added to menu.
|
// Array of dynamic menu buttons to be added to menu.
|
||||||
protected _dynamicMenuButtons: MenuButton[] = [];
|
protected _dynamicMenuButtons: MenuButton[] = [];
|
||||||
@@ -44,13 +52,7 @@ export class MenuButtonController {
|
|||||||
config: FrigateCardConfig,
|
config: FrigateCardConfig,
|
||||||
cameraManager: CameraManager,
|
cameraManager: CameraManager,
|
||||||
view: View,
|
view: View,
|
||||||
expanded: boolean,
|
options?: MenuButtonControllerOptions,
|
||||||
options?: {
|
|
||||||
currentMediaLoadedInfo?: MediaLoadedInfo | null;
|
|
||||||
showCameraUIButton?: boolean,
|
|
||||||
microphoneManager?: MicrophoneManager | null;
|
|
||||||
mediaPlayerController?: MediaPlayerManager | null;
|
|
||||||
},
|
|
||||||
): MenuButton[] {
|
): MenuButton[] {
|
||||||
const visibleCameras = cameraManager.getStore().getVisibleCameras();
|
const visibleCameras = cameraManager.getStore().getVisibleCameras();
|
||||||
const selectedCameraID = view.camera;
|
const selectedCameraID = view.camera;
|
||||||
@@ -294,26 +296,26 @@ export class MenuButtonController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screenfull.isEnabled && !this._isBeingCasted()) {
|
if (!this._isBeingCasted()) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
icon: screenfull.isFullscreen ? 'mdi:fullscreen-exit' : 'mdi:fullscreen',
|
icon: options?.inFullscreenMode ? 'mdi:fullscreen-exit' : 'mdi:fullscreen',
|
||||||
...config.menu.buttons.fullscreen,
|
...config.menu.buttons.fullscreen,
|
||||||
type: 'custom:frigate-card-menu-icon',
|
type: 'custom:frigate-card-menu-icon',
|
||||||
title: localize('config.menu.buttons.fullscreen'),
|
title: localize('config.menu.buttons.fullscreen'),
|
||||||
tap_action: createFrigateCardCustomAction(
|
tap_action: createFrigateCardCustomAction(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
) as FrigateCardCustomAction,
|
) as FrigateCardCustomAction,
|
||||||
style: screenfull.isFullscreen ? this._getEmphasizedStyle() : {},
|
style: options?.inFullscreenMode ? this._getEmphasizedStyle() : {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
buttons.push({
|
buttons.push({
|
||||||
icon: expanded ? 'mdi:arrow-collapse-all' : 'mdi:arrow-expand-all',
|
icon: options?.inExpandedMode ? 'mdi:arrow-collapse-all' : 'mdi:arrow-expand-all',
|
||||||
...config.menu.buttons.expand,
|
...config.menu.buttons.expand,
|
||||||
type: 'custom:frigate-card-menu-icon',
|
type: 'custom:frigate-card-menu-icon',
|
||||||
title: localize('config.menu.buttons.expand'),
|
title: localize('config.menu.buttons.expand'),
|
||||||
tap_action: createFrigateCardCustomAction('expand') as FrigateCardCustomAction,
|
tap_action: createFrigateCardCustomAction('expand') as FrigateCardCustomAction,
|
||||||
style: expanded ? this._getEmphasizedStyle() : {},
|
style: options?.inExpandedMode ? this._getEmphasizedStyle() : {},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -417,7 +419,7 @@ export class MenuButtonController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const styledDynamicButtons = this._dynamicMenuButtons.map((button) => ({
|
const styledDynamicButtons = this._dynamicMenuButtons.map((button) => ({
|
||||||
style: this._getStyleFromActions(config, view, button),
|
style: this._getStyleFromActions(config, view, button, options),
|
||||||
...button,
|
...button,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -450,6 +452,7 @@ export class MenuButtonController {
|
|||||||
config: FrigateCardConfig,
|
config: FrigateCardConfig,
|
||||||
view: View,
|
view: View,
|
||||||
button: MenuButton,
|
button: MenuButton,
|
||||||
|
options?: MenuButtonControllerOptions,
|
||||||
): StyleInfo {
|
): StyleInfo {
|
||||||
for (const actionSet of [
|
for (const actionSet of [
|
||||||
button.tap_action,
|
button.tap_action,
|
||||||
@@ -479,8 +482,7 @@ export class MenuButtonController {
|
|||||||
(frigateCardAction.frigate_card_action === 'default' &&
|
(frigateCardAction.frigate_card_action === 'default' &&
|
||||||
view.is(config.view.default)) ||
|
view.is(config.view.default)) ||
|
||||||
(frigateCardAction.frigate_card_action === 'fullscreen' &&
|
(frigateCardAction.frigate_card_action === 'fullscreen' &&
|
||||||
screenfull.isEnabled &&
|
!!options?.inFullscreenMode) ||
|
||||||
screenfull.isFullscreen) ||
|
|
||||||
(frigateCardAction.frigate_card_action === 'camera_select' &&
|
(frigateCardAction.frigate_card_action === 'camera_select' &&
|
||||||
view.camera === frigateCardAction.camera)
|
view.camera === frigateCardAction.camera)
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { HomeAssistant } from 'custom-card-helpers';
|
import { HomeAssistant } from 'custom-card-helpers';
|
||||||
import isEqual from 'lodash-es/isEqual';
|
import isEqual from 'lodash-es/isEqual';
|
||||||
import screenfull from 'screenfull';
|
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { mock } from 'vitest-mock-extended';
|
import { mock } from 'vitest-mock-extended';
|
||||||
import { CameraManager } from '../../src/camera-manager/manager';
|
import { CameraManager } from '../../src/camera-manager/manager';
|
||||||
@@ -8,14 +7,13 @@ import { CameraManagerCameraMetadata } from '../../src/camera-manager/types';
|
|||||||
import {
|
import {
|
||||||
FrigateCardConfig,
|
FrigateCardConfig,
|
||||||
FrigateCardMediaPlayer,
|
FrigateCardMediaPlayer,
|
||||||
MediaLoadedInfo,
|
|
||||||
MenuButton,
|
MenuButton,
|
||||||
ViewDisplayMode,
|
ViewDisplayMode,
|
||||||
} from '../../src/types';
|
} from '../../src/types';
|
||||||
import { createFrigateCardCustomAction } from '../../src/utils/action';
|
import { createFrigateCardCustomAction } from '../../src/utils/action';
|
||||||
import { MediaPlayerManager } from '../../src/utils/card-controller/media-player-manager';
|
import { MediaPlayerManager } from '../../src/utils/card-controller/media-player-manager';
|
||||||
import { MicrophoneManager } from '../../src/utils/card-controller/microphone-manager';
|
import { MicrophoneManager } from '../../src/utils/card-controller/microphone-manager';
|
||||||
import { MenuButtonController } from '../../src/utils/menu-controller';
|
import { MenuButtonController, MenuButtonControllerOptions } from '../../src/utils/menu-controller';
|
||||||
import { ViewMedia } from '../../src/view/media';
|
import { ViewMedia } from '../../src/view/media';
|
||||||
import { MediaQueriesResults } from '../../src/view/media-queries-results';
|
import { MediaQueriesResults } from '../../src/view/media-queries-results';
|
||||||
import { View } from '../../src/view/view';
|
import { View } from '../../src/view/view';
|
||||||
@@ -35,20 +33,14 @@ import {
|
|||||||
vi.mock('../../src/camera-manager/manager.js');
|
vi.mock('../../src/camera-manager/manager.js');
|
||||||
vi.mock('../../src/utils/media-player-controller.js');
|
vi.mock('../../src/utils/media-player-controller.js');
|
||||||
vi.mock('../../src/utils/card-controller/microphone-manager.js');
|
vi.mock('../../src/utils/card-controller/microphone-manager.js');
|
||||||
vi.mock('screenfull');
|
|
||||||
|
|
||||||
const calculateButtons = (
|
const calculateButtons = (
|
||||||
controller: MenuButtonController,
|
controller: MenuButtonController,
|
||||||
options?: {
|
options?: MenuButtonControllerOptions & {
|
||||||
hass?: HomeAssistant;
|
hass?: HomeAssistant;
|
||||||
config?: FrigateCardConfig;
|
config?: FrigateCardConfig;
|
||||||
cameraManager?: CameraManager;
|
cameraManager?: CameraManager;
|
||||||
view?: View;
|
view?: View;
|
||||||
expanded?: boolean;
|
|
||||||
currentMediaLoadedInfo?: MediaLoadedInfo | null;
|
|
||||||
mediaPlayerController?: MediaPlayerManager;
|
|
||||||
showCameraUIButton?: boolean;
|
|
||||||
microphoneManager?: MicrophoneManager;
|
|
||||||
},
|
},
|
||||||
): MenuButton[] => {
|
): MenuButton[] => {
|
||||||
return controller.calculateButtons(
|
return controller.calculateButtons(
|
||||||
@@ -62,13 +54,7 @@ const calculateButtons = (
|
|||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
options?.view ?? createView({ camera: 'camera-1' }),
|
options?.view ?? createView({ camera: 'camera-1' }),
|
||||||
options?.expanded ?? false,
|
options,
|
||||||
{
|
|
||||||
currentMediaLoadedInfo: options?.currentMediaLoadedInfo,
|
|
||||||
mediaPlayerController: options?.mediaPlayerController,
|
|
||||||
showCameraUIButton: options?.showCameraUIButton,
|
|
||||||
microphoneManager: options?.microphoneManager,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -863,9 +849,8 @@ describe('MenuButtonController', () => {
|
|||||||
|
|
||||||
it('should have fullscreen button', () => {
|
it('should have fullscreen button', () => {
|
||||||
// Need to write a readonly property.
|
// Need to write a readonly property.
|
||||||
Object.defineProperty(screenfull, 'isEnabled', { value: true });
|
|
||||||
vi.stubGlobal('navigator', { userAgent: 'foo' });
|
vi.stubGlobal('navigator', { userAgent: 'foo' });
|
||||||
const buttons = calculateButtons(controller);
|
const buttons = calculateButtons(controller, { inFullscreenMode: false });
|
||||||
|
|
||||||
expect(buttons).toContainEqual({
|
expect(buttons).toContainEqual({
|
||||||
icon: 'mdi:fullscreen',
|
icon: 'mdi:fullscreen',
|
||||||
@@ -879,11 +864,8 @@ describe('MenuButtonController', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have unfullscreen', () => {
|
it('should have unfullscreen', () => {
|
||||||
// Need to write a readonly property.
|
|
||||||
Object.defineProperty(screenfull, 'isEnabled', { value: true });
|
|
||||||
Object.defineProperty(screenfull, 'isFullscreen', { value: true });
|
|
||||||
vi.stubGlobal('navigator', { userAgent: 'foo' });
|
vi.stubGlobal('navigator', { userAgent: 'foo' });
|
||||||
const buttons = calculateButtons(controller);
|
const buttons = calculateButtons(controller, { inFullscreenMode: true });
|
||||||
|
|
||||||
expect(buttons).toContainEqual({
|
expect(buttons).toContainEqual({
|
||||||
icon: 'mdi:fullscreen-exit',
|
icon: 'mdi:fullscreen-exit',
|
||||||
@@ -897,7 +879,7 @@ describe('MenuButtonController', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have expand button', () => {
|
it('should have expand button', () => {
|
||||||
const buttons = calculateButtons(controller);
|
const buttons = calculateButtons(controller, { inExpandedMode: false });
|
||||||
|
|
||||||
expect(buttons).toContainEqual({
|
expect(buttons).toContainEqual({
|
||||||
icon: 'mdi:arrow-expand-all',
|
icon: 'mdi:arrow-expand-all',
|
||||||
@@ -911,7 +893,7 @@ describe('MenuButtonController', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have unexpand button', () => {
|
it('should have unexpand button', () => {
|
||||||
const buttons = calculateButtons(controller, { expanded: true });
|
const buttons = calculateButtons(controller, { inExpandedMode: true });
|
||||||
|
|
||||||
expect(buttons).toContainEqual({
|
expect(buttons).toContainEqual({
|
||||||
icon: 'mdi:arrow-collapse-all',
|
icon: 'mdi:arrow-collapse-all',
|
||||||
@@ -1224,17 +1206,13 @@ describe('MenuButtonController', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should set style for dynamic button with fullscreen action', () => {
|
it('should set style for dynamic button with fullscreen action', () => {
|
||||||
// Need to write a readonly property.
|
|
||||||
Object.defineProperty(screenfull, 'isEnabled', { value: true });
|
|
||||||
Object.defineProperty(screenfull, 'isFullscreen', { value: true });
|
|
||||||
|
|
||||||
const button: MenuButton = {
|
const button: MenuButton = {
|
||||||
...dynamicButton,
|
...dynamicButton,
|
||||||
tap_action: { action: 'fire-dom-event', frigate_card_action: 'fullscreen' },
|
tap_action: { action: 'fire-dom-event', frigate_card_action: 'fullscreen' },
|
||||||
};
|
};
|
||||||
|
|
||||||
controller.addDynamicMenuButton(button);
|
controller.addDynamicMenuButton(button);
|
||||||
expect(calculateButtons(controller)).toContainEqual({
|
expect(calculateButtons(controller, { inFullscreenMode: true })).toContainEqual({
|
||||||
...button,
|
...button,
|
||||||
style: { color: 'var(--primary-color, white)' },
|
style: { color: 'var(--primary-color, white)' },
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user