feat: Rename the card to advanced-camera-card (#1873)
Whilst the Frigate support in this card is the best among camera engines, the name incorrectly suggests that Frigate is a requirement. Instead, to broaden the appeal, change to more camera agnostic name. This does not suggest any change in priority, role or support for Frigate. This change is likely to be bug prone, due to the size of the rename -- the code contains 1500+ references to "Frigate" most of which make sense to rename, some which do not, all of which needed human assessment. - Closes #1298 BREAKING CHANGE: References to `frigate-card` in all kinds of configuration need to be updated to `advanced-camera-card`. An automated config upgrade should take care of the majority of usecases (click `Edit -> Upgrade -> Save`), though may not be perfect.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { fireEvent } from '@dermotduffy/custom-card-helpers';
|
||||
import type {
|
||||
ActionHandlerDetail,
|
||||
ActionHandlerOptions,
|
||||
} from '@dermotduffy/custom-card-helpers';
|
||||
import { fireEvent } from '@dermotduffy/custom-card-helpers';
|
||||
import { noChange } from 'lit';
|
||||
import {
|
||||
AttributePart,
|
||||
@@ -18,10 +18,10 @@ interface ActionHandlerInterface extends HTMLElement {
|
||||
bind(element: Element, options): void;
|
||||
}
|
||||
interface ActionHandlerElement extends HTMLElement {
|
||||
actionHandlerOptions?: FrigateCardActionHandlerOptions;
|
||||
actionHandlerOptions?: AdvancedCameraCardActionHandlerOptions;
|
||||
}
|
||||
|
||||
interface FrigateCardActionHandlerOptions extends ActionHandlerOptions {
|
||||
interface AdvancedCameraCardActionHandlerOptions extends ActionHandlerOptions {
|
||||
allowPropagation?: boolean;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class ActionHandler extends HTMLElement implements ActionHandlerInterface {
|
||||
|
||||
public bind(
|
||||
element: ActionHandlerElement,
|
||||
options?: FrigateCardActionHandlerOptions,
|
||||
options?: AdvancedCameraCardActionHandlerOptions,
|
||||
): void {
|
||||
if (element.actionHandlerOptions) {
|
||||
// Reset the options on an existing actionHandler.
|
||||
@@ -160,15 +160,15 @@ class ActionHandler extends HTMLElement implements ActionHandlerInterface {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('action-handler-frigate-card', ActionHandler);
|
||||
customElements.define('action-handler-advanced-camera-card', ActionHandler);
|
||||
|
||||
const getActionHandler = (): ActionHandler => {
|
||||
const body = document.body;
|
||||
if (body.querySelector('action-handler-frigate-card')) {
|
||||
return body.querySelector('action-handler-frigate-card') as ActionHandler;
|
||||
if (body.querySelector('action-handler-advanced-camera-card')) {
|
||||
return body.querySelector('action-handler-advanced-camera-card') as ActionHandler;
|
||||
}
|
||||
|
||||
const actionhandler = document.createElement('action-handler-frigate-card');
|
||||
const actionhandler = document.createElement('action-handler-advanced-camera-card');
|
||||
body.appendChild(actionhandler);
|
||||
|
||||
return actionhandler as ActionHandler;
|
||||
@@ -176,7 +176,7 @@ const getActionHandler = (): ActionHandler => {
|
||||
|
||||
const actionHandlerBind = (
|
||||
element: ActionHandlerElement,
|
||||
options?: FrigateCardActionHandlerOptions,
|
||||
options?: AdvancedCameraCardActionHandlerOptions,
|
||||
): void => {
|
||||
const actionhandler: ActionHandler = getActionHandler();
|
||||
if (!actionhandler) {
|
||||
@@ -193,7 +193,7 @@ export const actionHandler = directive(
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
|
||||
render(_options?: FrigateCardActionHandlerOptions) {}
|
||||
render(_options?: AdvancedCameraCardActionHandlerOptions) {}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -222,7 +222,7 @@ export interface ActionEventTarget extends EventTarget {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'action-handler-frigate-card': ActionHandler;
|
||||
'action-handler-advanced-camera-card': ActionHandler;
|
||||
}
|
||||
interface HASSDomEvents {
|
||||
action: ActionHandlerDetail;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FrigateCardError } from '../types.js';
|
||||
import { AdvancedCameraCardError } from '../types.js';
|
||||
|
||||
export class CameraInitializationError extends FrigateCardError {}
|
||||
export class CameraNoIDError extends FrigateCardError {}
|
||||
export class CameraInitializationError extends AdvancedCameraCardError {}
|
||||
export class CameraNoIDError extends AdvancedCameraCardError {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
|
||||
import { localize } from '../../localize/localize';
|
||||
import { FrigateCardError } from '../../types';
|
||||
import { AdvancedCameraCardError } from '../../types';
|
||||
import { homeAssistantWSRequest } from '../../utils/ha/ws-request';
|
||||
import { RecordingSegment } from '../types';
|
||||
import {
|
||||
@@ -38,7 +38,7 @@ export const getRecordingsSummary = async (
|
||||
camera: camera_name,
|
||||
|
||||
// Ask for the summary relative to HA timezone
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1267
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1267
|
||||
timezone: hass.config.time_zone,
|
||||
},
|
||||
true,
|
||||
@@ -100,7 +100,7 @@ export async function retainEvent(
|
||||
true,
|
||||
);
|
||||
if (!response.success) {
|
||||
throw new FrigateCardError(localize('error.failed_retain'), {
|
||||
throw new AdvancedCameraCardError(localize('error.failed_retain'), {
|
||||
request: retainRequest,
|
||||
response: response,
|
||||
});
|
||||
@@ -153,7 +153,7 @@ export const getEventSummary = async (
|
||||
instance_id: clientID,
|
||||
|
||||
// Ask for the summary relative to HA timezone
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1267
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1267
|
||||
timezone: hass.config.time_zone,
|
||||
},
|
||||
true,
|
||||
|
||||
@@ -228,7 +228,7 @@ export class CameraManager {
|
||||
}
|
||||
|
||||
// Engines are created sequentially, to avoid duplicate creation of the same
|
||||
// engine. See: https://github.com/dermotduffy/frigate-hass-card/issues/941
|
||||
// engine. See: https://github.com/dermotduffy/advanced-camera-card/issues/941
|
||||
const engineByConfig = await this._getEnginesForCameras(camerasConfig);
|
||||
|
||||
// Configuration is initialized in parallel.
|
||||
@@ -272,7 +272,7 @@ export class CameraManager {
|
||||
|
||||
log(
|
||||
this._api.getConfigManager().getCardWideConfig(),
|
||||
'Frigate Card CameraManager initialized (Cameras: ',
|
||||
'Advanced Camera Card CameraManager initialized (Cameras: ',
|
||||
this._store.getCameras(),
|
||||
`, Duration: ${
|
||||
(new Date().getTime() - initializationStartTime.getTime()) / 1000
|
||||
@@ -546,7 +546,7 @@ export class CameraManager {
|
||||
|
||||
log(
|
||||
this._api.getConfigManager().getCardWideConfig(),
|
||||
'Frigate Card CameraManager favorite request (',
|
||||
'Advanced Camera Card CameraManager favorite request (',
|
||||
`Duration: ${(new Date().getTime() - queryStartTime.getTime()) / 1000}s,`,
|
||||
'Media:',
|
||||
media.getID(),
|
||||
@@ -679,7 +679,7 @@ export class CameraManager {
|
||||
|
||||
log(
|
||||
this._api.getConfigManager().getCardWideConfig(),
|
||||
'Frigate Card CameraManager request [Input queries:',
|
||||
'Advanced Camera Card CameraManager request [Input queries:',
|
||||
_queries.length,
|
||||
', Cached output queries:',
|
||||
cachedOutputQueries,
|
||||
|
||||
@@ -181,7 +181,7 @@ export class ReolinkCameraManagerEngine extends BrowseMediaCameraManagerEngine {
|
||||
// First fetch all the Reolink cameras that show up under the media root,
|
||||
// that match the expected camera. Some Reolink cameras will not show up
|
||||
// here causing errors.
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/1723
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/1723
|
||||
const camerasWithMedia = await this._browseMediaManager.walkBrowseMedias(
|
||||
hass,
|
||||
[
|
||||
|
||||
@@ -48,7 +48,7 @@ export class CameraManagerStore implements CameraManagerReadOnlyConfigStore {
|
||||
// In setting the store cameras, take great care to replace/add first before
|
||||
// remove. Otherwise, there may be race conditions where the card attempts
|
||||
// to render a view with (momentarily) no camera.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1533
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1533
|
||||
|
||||
// Replace/Add the new cameras.
|
||||
for (const camera of cameras) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AdvancedCameraCardView, SSLCiphers } from '../config/types';
|
||||
import { CapabilityKey, Icon } from '../types';
|
||||
import { FrigateCardView, SSLCiphers } from '../config/types';
|
||||
import { ViewMedia } from '../view/media';
|
||||
|
||||
// ====
|
||||
@@ -114,7 +114,7 @@ export interface CameraManagerCameraMetadata {
|
||||
|
||||
export interface CameraEndpointsContext {
|
||||
media?: ViewMedia;
|
||||
view?: FrigateCardView;
|
||||
view?: AdvancedCameraCardView;
|
||||
}
|
||||
|
||||
export interface CameraEndpoint {
|
||||
|
||||
@@ -67,9 +67,9 @@ export class ActionsManager {
|
||||
if (
|
||||
config &&
|
||||
interaction &&
|
||||
// Don't call frigateCardHandleActionConfig() unless there is explicitly an
|
||||
// action defined (as it uses a default that is unhelpful for views that
|
||||
// have default tap/click actions).
|
||||
// Don't execute unless there is explicitly an action defined (as it uses
|
||||
// a default that is unhelpful for views that have default tap/click
|
||||
// actions).
|
||||
actionConfig
|
||||
) {
|
||||
this.executeActions(actionConfig, config);
|
||||
@@ -91,8 +91,8 @@ export class ActionsManager {
|
||||
};
|
||||
|
||||
/**
|
||||
* This method handles actions requested by components of the Frigate card
|
||||
* itself (e.g. menu, PTZ controller).
|
||||
* This method handles actions requested by components of the Advanced Camera
|
||||
* Card itself (e.g. menu, PTZ controller).
|
||||
*/
|
||||
public handleActionExecutionRequestEvent = async (
|
||||
ev: CustomEvent<ActionExecutionRequest>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ActionContext } from 'action';
|
||||
import { FrigateCardCustomAction } from '../../../config/types';
|
||||
import { AdvancedCameraCardCustomAction } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { Action, AuxillaryActionConfig } from '../types';
|
||||
|
||||
@@ -24,6 +24,6 @@ export class BaseAction<T> implements Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class FrigateCardAction<
|
||||
T extends FrigateCardCustomAction,
|
||||
export class AdvancedCameraCardAction<
|
||||
T extends AdvancedCameraCardCustomAction,
|
||||
> extends BaseAction<T> {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { CameraSelectActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class CameraSelectAction extends FrigateCardAction<CameraSelectActionConfig> {
|
||||
export class CameraSelectAction extends AdvancedCameraCardAction<CameraSelectActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
const selectCameraID =
|
||||
this._action.camera ??
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class CameraUIAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class CameraUIAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getCameraURLManager().openURL();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class DefaultAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class DefaultAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getViewManager().setViewDefaultWithNewQuery();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { DisplayModeActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class DisplayModeSelectAction extends FrigateCardAction<DisplayModeActionConfig> {
|
||||
export class DisplayModeSelectAction extends AdvancedCameraCardAction<DisplayModeActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getViewManager().setViewByParametersWithNewQuery({
|
||||
params: {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class DownloadAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class DownloadAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getDownloadManager().downloadViewerMedia();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class ExpandAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class ExpandAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getExpandManager().toggleExpanded();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class FullscreenAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class FullscreenAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getFullscreenManager().toggleFullscreen();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CardActionsAPI } from '../../types';
|
||||
import { BaseAction } from './base';
|
||||
|
||||
/**
|
||||
* Handles generic HA (non-Frigate) actions (e.g. 'more-info')
|
||||
* Handles generic HA actions (e.g. 'more-info')
|
||||
*/
|
||||
export class GenericAction extends BaseAction<ActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { LogActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class LogAction extends FrigateCardAction<LogActionConfig> {
|
||||
export class LogAction extends AdvancedCameraCardAction<LogActionConfig> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public async execute(_api: CardActionsAPI): Promise<void> {
|
||||
console[this._action.level](this._action.message);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { MediaPlayerActionConfig } from '../../../config/types';
|
||||
import { getStreamCameraID } from '../../../utils/substream';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class MediaPlayerAction extends FrigateCardAction<MediaPlayerActionConfig> {
|
||||
export class MediaPlayerAction extends AdvancedCameraCardAction<MediaPlayerActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
const mediaPlayer = this._action.media_player;
|
||||
const mediaPlayerController = api.getMediaPlayerManager();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class MenuToggleAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class MenuToggleAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getCardElementManager().toggleMenu();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class MicrophoneConnectAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class MicrophoneConnectAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getMicrophoneManager().connect();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class MicrophoneDisconnectAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class MicrophoneDisconnectAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getMicrophoneManager().disconnect();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class MicrophoneMuteAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class MicrophoneMuteAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getMicrophoneManager().mute();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class MicrophoneUnmuteAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class MicrophoneUnmuteAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getMicrophoneManager().unmute();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class MuteAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class MuteAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getMediaLoadedInfoManager().get()?.player?.mute();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class PauseAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class PauseAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getMediaLoadedInfoManager().get()?.player?.pause();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class PlayAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class PlayAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getMediaLoadedInfoManager().get()?.player?.play();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { PTZControlsActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class PTZControlsAction extends FrigateCardAction<PTZControlsActionConfig> {
|
||||
export class PTZControlsAction extends AdvancedCameraCardAction<PTZControlsActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getViewManager().setViewWithMergedContext({
|
||||
ptzControls: { enabled: this._action.enabled },
|
||||
|
||||
@@ -10,12 +10,12 @@ import { PTZDigitialActionConfig, ZOOM_MAX, ZOOM_MIN } from '../../../config/typ
|
||||
import { getPTZTarget } from '../../../utils/ptz';
|
||||
import { Timer } from '../../../utils/timer';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { TargetedActionContext } from '../types';
|
||||
import {
|
||||
setInProgressForThisTarget,
|
||||
stopInProgressForThisTarget,
|
||||
} from '../utils/action-state';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
const STEP_DELAY_SECONDS = 0.1;
|
||||
const STEP_ZOOM = 0.1;
|
||||
@@ -27,7 +27,7 @@ declare module 'action' {
|
||||
}
|
||||
}
|
||||
|
||||
export class PTZDigitalAction extends FrigateCardAction<PTZDigitialActionConfig> {
|
||||
export class PTZDigitalAction extends AdvancedCameraCardAction<PTZDigitialActionConfig> {
|
||||
protected _timer = new Timer();
|
||||
|
||||
protected async _stepChange(api: CardActionsAPI, targetID: string): Promise<void> {
|
||||
|
||||
@@ -2,11 +2,11 @@ import { PTZMultiActionConfig } from '../../../config/types';
|
||||
import { createPTZAction, createPTZDigitalAction } from '../../../utils/action';
|
||||
import { PTZType, getPTZTarget, hasCameraTruePTZ } from '../../../utils/ptz';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
import { PTZAction } from './ptz';
|
||||
import { PTZDigitalAction } from './ptz-digital';
|
||||
|
||||
export class PTZMultiAction extends FrigateCardAction<PTZMultiActionConfig> {
|
||||
export class PTZMultiAction extends AdvancedCameraCardAction<PTZMultiActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
const view = api.getViewManager().getView();
|
||||
let targetID: string | null = null;
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
setInProgressForThisTarget,
|
||||
stopInProgressForThisTarget,
|
||||
} from '../utils/action-state';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
interface PTZContext {
|
||||
[cameraID: string]: {
|
||||
@@ -20,7 +20,7 @@ declare module 'action' {
|
||||
}
|
||||
}
|
||||
|
||||
export class PTZAction extends FrigateCardAction<PTZActionConfig> {
|
||||
export class PTZAction extends AdvancedCameraCardAction<PTZActionConfig> {
|
||||
protected _timer = new Timer();
|
||||
|
||||
public async stop(): Promise<void> {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class ScreenshotAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class ScreenshotAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getDownloadManager().downloadScreenshot();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ import { SleepActionConfig } from '../../../config/types';
|
||||
import { sleep } from '../../../utils/basic';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { timeDeltaToSeconds } from '../utils/time-delta';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class SleepAction extends FrigateCardAction<SleepActionConfig> {
|
||||
export class SleepAction extends AdvancedCameraCardAction<SleepActionConfig> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public async execute(_api: CardActionsAPI): Promise<void> {
|
||||
await sleep(timeDeltaToSeconds(this._action.duration));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { StatusBarActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class StatusBarAction extends FrigateCardAction<StatusBarActionConfig> {
|
||||
export class StatusBarAction extends AdvancedCameraCardAction<StatusBarActionConfig> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
switch (this._action.status_bar_action) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { SubstreamOffViewModifier } from '../../view/modifiers/substream-off';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class SubstreamOffAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class SubstreamOffAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getViewManager().setViewByParameters({
|
||||
modifiers: [new SubstreamOffViewModifier()],
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { SubstreamOnViewModifier } from '../../view/modifiers/substream-on';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class SubstreamOnAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class SubstreamOnAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getViewManager().setViewByParameters({
|
||||
modifiers: [new SubstreamOnViewModifier(api)],
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { SubstreamSelectActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { SubstreamSelectViewModifier } from '../../view/modifiers/substream-select';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class SubstreamSelectAction extends FrigateCardAction<SubstreamSelectActionConfig> {
|
||||
export class SubstreamSelectAction extends AdvancedCameraCardAction<SubstreamSelectActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
api.getViewManager().setViewByParameters({
|
||||
modifiers: [new SubstreamSelectViewModifier(this._action.camera)],
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { GeneralActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class UnmuteAction extends FrigateCardAction<GeneralActionConfig> {
|
||||
export class UnmuteAction extends AdvancedCameraCardAction<GeneralActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getMediaLoadedInfoManager().get()?.player?.unmute();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ViewActionConfig } from '../../../config/types';
|
||||
import { CardActionsAPI } from '../../types';
|
||||
import { FrigateCardAction } from './base';
|
||||
import { AdvancedCameraCardAction } from './base';
|
||||
|
||||
export class ViewAction extends FrigateCardAction<ViewActionConfig> {
|
||||
export class ViewAction extends AdvancedCameraCardAction<ViewActionConfig> {
|
||||
public async execute(api: CardActionsAPI): Promise<void> {
|
||||
await api.getViewManager().setViewByParametersWithNewQuery({
|
||||
params: {
|
||||
view: this._action.frigate_card_action,
|
||||
view: this._action.advanced_camera_card_action,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ export class ActionFactory {
|
||||
cardID?: string;
|
||||
},
|
||||
): Action | null {
|
||||
const frigateCardAction = convertActionToCardCustomAction(action);
|
||||
if (action.action !== 'fire-dom-event' || !frigateCardAction) {
|
||||
const cardCustomAction = convertActionToCardCustomAction(action);
|
||||
if (action.action !== 'fire-dom-event' || !cardCustomAction) {
|
||||
// * There is a slight typing (but not functional) difference between
|
||||
// ActionType in this card and ActionConfig in `custom-card-helpers`. See
|
||||
// `ExtendedConfirmationRestrictionConfig` in `types.ts` for the source and
|
||||
@@ -54,15 +54,15 @@ export class ActionFactory {
|
||||
|
||||
if (
|
||||
// Command not intended for this card (e.g. query string command).
|
||||
frigateCardAction.card_id &&
|
||||
frigateCardAction.card_id !== options?.cardID
|
||||
cardCustomAction.card_id &&
|
||||
cardCustomAction.card_id !== options?.cardID
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (frigateCardAction.frigate_card_action) {
|
||||
switch (cardCustomAction.advanced_camera_card_action) {
|
||||
case 'default':
|
||||
return new DefaultAction(context, frigateCardAction, options?.config);
|
||||
return new DefaultAction(context, cardCustomAction, options?.config);
|
||||
case 'clip':
|
||||
case 'clips':
|
||||
case 'image':
|
||||
@@ -73,70 +73,70 @@ export class ActionFactory {
|
||||
case 'snapshots':
|
||||
case 'timeline':
|
||||
case 'diagnostics':
|
||||
return new ViewAction(context, frigateCardAction, options?.config);
|
||||
return new ViewAction(context, cardCustomAction, options?.config);
|
||||
case 'sleep':
|
||||
return new SleepAction(context, frigateCardAction, options?.config);
|
||||
return new SleepAction(context, cardCustomAction, options?.config);
|
||||
case 'download':
|
||||
return new DownloadAction(context, frigateCardAction, options?.config);
|
||||
return new DownloadAction(context, cardCustomAction, options?.config);
|
||||
case 'camera_ui':
|
||||
return new CameraUIAction(context, frigateCardAction, options?.config);
|
||||
return new CameraUIAction(context, cardCustomAction, options?.config);
|
||||
case 'expand':
|
||||
return new ExpandAction(context, frigateCardAction, options?.config);
|
||||
return new ExpandAction(context, cardCustomAction, options?.config);
|
||||
case 'fullscreen':
|
||||
return new FullscreenAction(context, frigateCardAction, options?.config);
|
||||
return new FullscreenAction(context, cardCustomAction, options?.config);
|
||||
case 'menu_toggle':
|
||||
return new MenuToggleAction(context, frigateCardAction, options?.config);
|
||||
return new MenuToggleAction(context, cardCustomAction, options?.config);
|
||||
case 'camera_select':
|
||||
return new CameraSelectAction(context, frigateCardAction, options?.config);
|
||||
return new CameraSelectAction(context, cardCustomAction, options?.config);
|
||||
case 'live_substream_select':
|
||||
return new SubstreamSelectAction(context, frigateCardAction, options?.config);
|
||||
return new SubstreamSelectAction(context, cardCustomAction, options?.config);
|
||||
case 'live_substream_off':
|
||||
return new SubstreamOffAction(context, frigateCardAction, options?.config);
|
||||
return new SubstreamOffAction(context, cardCustomAction, options?.config);
|
||||
case 'live_substream_on':
|
||||
return new SubstreamOnAction(context, frigateCardAction, options?.config);
|
||||
return new SubstreamOnAction(context, cardCustomAction, options?.config);
|
||||
case 'media_player':
|
||||
return new MediaPlayerAction(context, frigateCardAction, options?.config);
|
||||
return new MediaPlayerAction(context, cardCustomAction, options?.config);
|
||||
case 'microphone_connect':
|
||||
return new MicrophoneConnectAction(context, frigateCardAction, options?.config);
|
||||
return new MicrophoneConnectAction(context, cardCustomAction, options?.config);
|
||||
case 'microphone_disconnect':
|
||||
return new MicrophoneDisconnectAction(
|
||||
context,
|
||||
frigateCardAction,
|
||||
cardCustomAction,
|
||||
options?.config,
|
||||
);
|
||||
case 'microphone_mute':
|
||||
return new MicrophoneMuteAction(context, frigateCardAction, options?.config);
|
||||
return new MicrophoneMuteAction(context, cardCustomAction, options?.config);
|
||||
case 'microphone_unmute':
|
||||
return new MicrophoneUnmuteAction(context, frigateCardAction, options?.config);
|
||||
return new MicrophoneUnmuteAction(context, cardCustomAction, options?.config);
|
||||
case 'mute':
|
||||
return new MuteAction(context, frigateCardAction, options?.config);
|
||||
return new MuteAction(context, cardCustomAction, options?.config);
|
||||
case 'unmute':
|
||||
return new UnmuteAction(context, frigateCardAction, options?.config);
|
||||
return new UnmuteAction(context, cardCustomAction, options?.config);
|
||||
case 'play':
|
||||
return new PlayAction(context, frigateCardAction, options?.config);
|
||||
return new PlayAction(context, cardCustomAction, options?.config);
|
||||
case 'pause':
|
||||
return new PauseAction(context, frigateCardAction, options?.config);
|
||||
return new PauseAction(context, cardCustomAction, options?.config);
|
||||
case 'screenshot':
|
||||
return new ScreenshotAction(context, frigateCardAction, options?.config);
|
||||
return new ScreenshotAction(context, cardCustomAction, options?.config);
|
||||
case 'display_mode_select':
|
||||
return new DisplayModeSelectAction(context, frigateCardAction, options?.config);
|
||||
return new DisplayModeSelectAction(context, cardCustomAction, options?.config);
|
||||
case 'ptz':
|
||||
return new PTZAction(context, frigateCardAction, options?.config);
|
||||
return new PTZAction(context, cardCustomAction, options?.config);
|
||||
case 'ptz_digital':
|
||||
return new PTZDigitalAction(context, frigateCardAction, options?.config);
|
||||
return new PTZDigitalAction(context, cardCustomAction, options?.config);
|
||||
case 'ptz_multi':
|
||||
return new PTZMultiAction(context, frigateCardAction, options?.config);
|
||||
return new PTZMultiAction(context, cardCustomAction, options?.config);
|
||||
case 'ptz_controls':
|
||||
return new PTZControlsAction(context, frigateCardAction, options?.config);
|
||||
return new PTZControlsAction(context, cardCustomAction, options?.config);
|
||||
case 'log':
|
||||
return new LogAction(context, frigateCardAction, options?.config);
|
||||
return new LogAction(context, cardCustomAction, options?.config);
|
||||
case 'status_bar':
|
||||
return new StatusBarAction(context, frigateCardAction, options?.config);
|
||||
return new StatusBarAction(context, cardCustomAction, options?.config);
|
||||
}
|
||||
|
||||
/* istanbul ignore next: this path cannot be reached -- @preserve */
|
||||
console.warn(
|
||||
`Frigate card received unknown card action: ${frigateCardAction['frigate_card_action']}`,
|
||||
`Advanced Camera Card received unknown card action: ${cardCustomAction['advanced_camera_card_action']}`,
|
||||
);
|
||||
/* istanbul ignore next: this path cannot be reached -- @preserve */
|
||||
return null;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { dispatchFrigateCardEvent } from '../../../utils/basic';
|
||||
import { dispatchAdvancedCameraCardEvent } from '../../../utils/basic';
|
||||
import { ActionExecutionRequest } from '../types';
|
||||
|
||||
export const dispatchActionExecutionRequest = (
|
||||
element: HTMLElement,
|
||||
request: ActionExecutionRequest,
|
||||
) => {
|
||||
dispatchFrigateCardEvent(element, 'action:execution-request', request);
|
||||
dispatchAdvancedCameraCardEvent(element, 'action:execution-request', request);
|
||||
};
|
||||
|
||||
export interface ActionExecutionRequestEventTarget extends EventTarget {
|
||||
addEventListener(
|
||||
event: 'frigate-card:action:execution-request',
|
||||
event: 'advanced-camera-card:action:execution-request',
|
||||
listener: (
|
||||
this: ActionExecutionRequestEventTarget,
|
||||
ev: CustomEvent<ActionExecutionRequest>,
|
||||
@@ -23,7 +23,7 @@ export interface ActionExecutionRequestEventTarget extends EventTarget {
|
||||
options?: AddEventListenerOptions | boolean,
|
||||
): void;
|
||||
removeEventListener(
|
||||
event: 'frigate-card:action:execution-request',
|
||||
event: 'advanced-camera-card:action:execution-request',
|
||||
listener: (
|
||||
this: ActionExecutionRequestEventTarget,
|
||||
ev: CustomEvent<ActionExecutionRequest>,
|
||||
|
||||
@@ -31,7 +31,7 @@ export class AutomationsManager {
|
||||
!this._api.getHASSManager().hasHASS() ||
|
||||
// Never execute automations if the card hasn't finished initializing, as
|
||||
// it could cause a view change when camera loads are not finished.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1407
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1407
|
||||
!this._api.getInitializationManager().isInitializedMandatory() ||
|
||||
// Never execute automations if there's an error (as our automation loop
|
||||
// avoidance -- which shows as an error -- would not work!).
|
||||
|
||||
@@ -78,7 +78,7 @@ export class CardElementManager {
|
||||
...(this._api.getConfigManager().getConfig()?.view.render_entities ?? []),
|
||||
|
||||
// Refresh the card if media player state changes:
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/881
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/881
|
||||
...(this._api.getMediaPlayerManager().getMediaPlayers() ?? []),
|
||||
]);
|
||||
|
||||
@@ -109,7 +109,7 @@ export class CardElementManager {
|
||||
this._api.getInteractionManager().reportInteraction,
|
||||
);
|
||||
this._element.addEventListener(
|
||||
'frigate-card:action:execution-request',
|
||||
'advanced-camera-card:action:execution-request',
|
||||
this._api.getActionsManager().handleActionExecutionRequestEvent,
|
||||
);
|
||||
|
||||
@@ -179,7 +179,7 @@ export class CardElementManager {
|
||||
this._api.getInteractionManager().reportInteraction,
|
||||
);
|
||||
this._element.removeEventListener(
|
||||
'frigate-card:action:execution-request',
|
||||
'advanced-camera-card:action:execution-request',
|
||||
this._api.getActionsManager().handleActionExecutionRequestEvent,
|
||||
);
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@ import {
|
||||
setConfigValue,
|
||||
} from '../config/management';
|
||||
import {
|
||||
FrigateCardCondition,
|
||||
frigateConditionalSchema,
|
||||
AdvancedCameraCardCondition,
|
||||
advancedCameraCardConditionalSchema,
|
||||
Overrides,
|
||||
RawFrigateCardConfig,
|
||||
RawAdvancedCameraCardConfig,
|
||||
ViewDisplayMode,
|
||||
} from '../config/types';
|
||||
import { localize } from '../localize/localize';
|
||||
import { FrigateCardError, MediaLoadedInfo } from '../types';
|
||||
import { AdvancedCameraCardError, MediaLoadedInfo } from '../types';
|
||||
import { desparsifyArrays } from '../utils/basic';
|
||||
import { isCompanionApp } from '../utils/companion';
|
||||
import { CardConditionAPI, KeysState, MicrophoneState } from './types';
|
||||
@@ -38,25 +38,26 @@ export interface ConditionState {
|
||||
view?: string;
|
||||
}
|
||||
|
||||
class OverrideConfigurationError extends FrigateCardError {}
|
||||
class OverrideConfigurationError extends AdvancedCameraCardError {}
|
||||
|
||||
export class ConditionsEvaluateRequestEvent extends Event {
|
||||
public conditions: FrigateCardCondition[];
|
||||
public conditions: AdvancedCameraCardCondition[];
|
||||
public evaluation?: boolean;
|
||||
|
||||
constructor(conditions: FrigateCardCondition[], eventInitDict?: EventInit) {
|
||||
super('frigate-card:conditions:evaluate', eventInitDict);
|
||||
constructor(conditions: AdvancedCameraCardCondition[], eventInitDict?: EventInit) {
|
||||
super('advanced-camera-card:conditions:evaluate', eventInitDict);
|
||||
this.conditions = conditions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate whether a frigateCardCondition is met using an event to evaluate.
|
||||
* Evaluate whether an AdvancedCameraCardCondition is met using an event to
|
||||
* evaluate.
|
||||
* @returns A boolean indicating whether the condition is met.
|
||||
*/
|
||||
export function evaluateConditionViaEvent(
|
||||
element: HTMLElement,
|
||||
conditions?: FrigateCardCondition[],
|
||||
conditions?: AdvancedCameraCardCondition[],
|
||||
): boolean {
|
||||
if (!conditions) {
|
||||
return true;
|
||||
@@ -69,7 +70,7 @@ export function evaluateConditionViaEvent(
|
||||
|
||||
/* Special note on what's going on here:
|
||||
*
|
||||
* Some parts of the card (e.g. <frigate-card-elements>) may have arbitrary
|
||||
* Some parts of the card (e.g. <advanced-camera-card-elements>) may have arbitrary
|
||||
* complexity and layers (that this card doesn't control) between that master
|
||||
* element and the element that needs to evaluate the condition. In these
|
||||
* cases there's no clean way to pass state from the rest of card down through
|
||||
@@ -83,7 +84,7 @@ export function evaluateConditionViaEvent(
|
||||
return evaluateEvent.evaluation ?? false;
|
||||
}
|
||||
|
||||
export function getOverriddenConfig<RT extends RawFrigateCardConfig>(
|
||||
export function getOverriddenConfig<RT extends RawAdvancedCameraCardConfig>(
|
||||
manager: Readonly<ConditionsManager>,
|
||||
config: Readonly<RT>,
|
||||
options?: {
|
||||
@@ -198,9 +199,9 @@ export class ConditionsManager {
|
||||
public setConditionsFromConfig(): void {
|
||||
this.removeConditions();
|
||||
|
||||
const getAllConditions = (): FrigateCardCondition[] => {
|
||||
const getAllConditions = (): AdvancedCameraCardCondition[] => {
|
||||
const config = this._api.getConfigManager().getConfig();
|
||||
const conditions: FrigateCardCondition[] = [];
|
||||
const conditions: AdvancedCameraCardCondition[] = [];
|
||||
config?.overrides?.forEach((override) => conditions.push(...override.conditions));
|
||||
config?.automations?.forEach((automation) =>
|
||||
conditions.push(...automation.conditions),
|
||||
@@ -210,7 +211,7 @@ export class ConditionsManager {
|
||||
// custom elements that this card may not known. Here we recursively parse
|
||||
// down the elements tree, parsing as we go to find valid conditions.
|
||||
const getElementsConditions = (data: unknown): void => {
|
||||
const parseResult = frigateConditionalSchema.safeParse(data);
|
||||
const parseResult = advancedCameraCardConditionalSchema.safeParse(data);
|
||||
if (parseResult.success) {
|
||||
conditions.push(...parseResult.data.conditions);
|
||||
parseResult.data.elements?.forEach(getElementsConditions);
|
||||
@@ -265,7 +266,7 @@ export class ConditionsManager {
|
||||
}
|
||||
|
||||
public evaluateConditions(
|
||||
conditions: Readonly<FrigateCardCondition>[],
|
||||
conditions: Readonly<AdvancedCameraCardCondition>[],
|
||||
stateOverrides?: Partial<ConditionState>,
|
||||
): boolean {
|
||||
return conditions.every((conditionObj) =>
|
||||
@@ -274,7 +275,7 @@ export class ConditionsManager {
|
||||
}
|
||||
|
||||
protected _evaluateCondition(
|
||||
conditionObj: Readonly<FrigateCardCondition>,
|
||||
conditionObj: Readonly<AdvancedCameraCardCondition>,
|
||||
stateOverrides?: Partial<ConditionState>,
|
||||
): boolean {
|
||||
const state = {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import { isConfigUpgradeable } from '../../config/management.js';
|
||||
import { setProfiles } from '../../config/profiles/index.js';
|
||||
import {
|
||||
AdvancedCameraCardConfig,
|
||||
advancedCameraCardConfigSchema,
|
||||
CardWideConfig,
|
||||
FrigateCardConfig,
|
||||
frigateCardConfigSchema,
|
||||
RawFrigateCardConfig,
|
||||
RawAdvancedCameraCardConfig,
|
||||
} from '../../config/types.js';
|
||||
import { localize } from '../../localize/localize.js';
|
||||
import { setProfiles } from '../../config/profiles/index.js';
|
||||
import { getParseErrorPaths } from '../../utils/zod.js';
|
||||
import { getOverriddenConfig } from '../conditions-manager.js';
|
||||
import { InitializationAspect } from '../initialization-manager.js';
|
||||
@@ -22,9 +22,9 @@ export class ConfigManager {
|
||||
// get the correct configuration (which will return overrides as appropriate).
|
||||
// This variable must be called `_config` or `config` to be compatible with
|
||||
// card-mod.
|
||||
protected _config: FrigateCardConfig | null = null;
|
||||
protected _overriddenConfig: FrigateCardConfig | null = null;
|
||||
protected _rawConfig: RawFrigateCardConfig | null = null;
|
||||
protected _config: AdvancedCameraCardConfig | null = null;
|
||||
protected _overriddenConfig: AdvancedCameraCardConfig | null = null;
|
||||
protected _rawConfig: RawAdvancedCameraCardConfig | null = null;
|
||||
protected _cardWideConfig: CardWideConfig | null = null;
|
||||
|
||||
constructor(api: CardConfigAPI) {
|
||||
@@ -35,7 +35,7 @@ export class ConfigManager {
|
||||
return !!this.getConfig();
|
||||
}
|
||||
|
||||
public getConfig(): FrigateCardConfig | null {
|
||||
public getConfig(): AdvancedCameraCardConfig | null {
|
||||
return this._overriddenConfig ?? this._config;
|
||||
}
|
||||
|
||||
@@ -43,20 +43,20 @@ export class ConfigManager {
|
||||
return this._cardWideConfig;
|
||||
}
|
||||
|
||||
public getNonOverriddenConfig(): FrigateCardConfig | null {
|
||||
public getNonOverriddenConfig(): AdvancedCameraCardConfig | null {
|
||||
return this._config;
|
||||
}
|
||||
|
||||
public getRawConfig(): RawFrigateCardConfig | null {
|
||||
public getRawConfig(): RawAdvancedCameraCardConfig | null {
|
||||
return this._rawConfig;
|
||||
}
|
||||
|
||||
public setConfig(inputConfig?: RawFrigateCardConfig): void {
|
||||
public setConfig(inputConfig?: RawAdvancedCameraCardConfig): void {
|
||||
if (!inputConfig) {
|
||||
throw new Error(localize('error.invalid_configuration'));
|
||||
}
|
||||
|
||||
const parseResult = frigateCardConfigSchema.safeParse(inputConfig);
|
||||
const parseResult = advancedCameraCardConfigSchema.safeParse(inputConfig);
|
||||
if (!parseResult.success) {
|
||||
const configUpgradeable = isConfigUpgradeable(inputConfig);
|
||||
const hint = getParseErrorPaths(parseResult.error);
|
||||
@@ -113,11 +113,11 @@ export class ConfigManager {
|
||||
return;
|
||||
}
|
||||
|
||||
let overriddenConfig: FrigateCardConfig | null = null;
|
||||
let overriddenConfig: AdvancedCameraCardConfig | null = null;
|
||||
try {
|
||||
overriddenConfig = getOverriddenConfig(conditionsManager, this._config, {
|
||||
configOverrides: this._config.overrides,
|
||||
schema: frigateCardConfigSchema,
|
||||
schema: advancedCameraCardConfigSchema,
|
||||
});
|
||||
} catch (ev) {
|
||||
this._api.getMessageManager().setErrorIfHigherPriority(ev);
|
||||
@@ -162,7 +162,7 @@ export class ConfigManager {
|
||||
* card hard requires, use InitializationManager instead.
|
||||
*/
|
||||
protected async _initializeBackground(
|
||||
previousConfig: FrigateCardConfig | null,
|
||||
previousConfig: AdvancedCameraCardConfig | null,
|
||||
): Promise<void> {
|
||||
await this._api.getDefaultManager().initializeIfNecessary(previousConfig);
|
||||
await this._api.getMediaPlayerManager().initializeIfNecessary(previousConfig);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { LovelaceCardEditor } from '@dermotduffy/custom-card-helpers';
|
||||
import { ReactiveController } from 'lit';
|
||||
import { CameraManager } from '../camera-manager/manager';
|
||||
import { FrigateCardConfig } from '../config/types';
|
||||
import { AdvancedCameraCardConfig } from '../config/types';
|
||||
import {
|
||||
createDeviceRegistryCache,
|
||||
DeviceRegistryManager,
|
||||
@@ -177,7 +177,7 @@ export class CardController
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardEditor> {
|
||||
await import('../editor.js');
|
||||
return document.createElement('frigate-card-editor');
|
||||
return document.createElement('advanced-camera-card-editor');
|
||||
}
|
||||
|
||||
public getConfigManager(): ConfigManager {
|
||||
@@ -255,7 +255,7 @@ export class CardController
|
||||
return this._statusBarItemManager;
|
||||
}
|
||||
|
||||
public static getStubConfig(entities: string[]): FrigateCardConfig {
|
||||
public static getStubConfig(entities: string[]): AdvancedCameraCardConfig {
|
||||
const cameraEntity = entities.find((element) => element.startsWith('camera.'));
|
||||
return {
|
||||
cameras: [
|
||||
@@ -266,7 +266,7 @@ export class CardController
|
||||
// Need to use 'as unknown' to convince Typescript that this really isn't a
|
||||
// mistake, despite the miniscule size of the configuration vs the full type
|
||||
// description.
|
||||
} as unknown as FrigateCardConfig;
|
||||
} as unknown as AdvancedCameraCardConfig;
|
||||
}
|
||||
|
||||
public getStyleManager(): StyleManager {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import { FrigateCardConfig } from '../config/types';
|
||||
import { AdvancedCameraCardConfig } from '../config/types';
|
||||
import { createGeneralAction } from '../utils/action';
|
||||
import { isActionAllowedBasedOnInteractionState } from '../utils/interaction-mode';
|
||||
import { Timer } from '../utils/timer';
|
||||
@@ -17,7 +17,7 @@ export class DefaultManager {
|
||||
}
|
||||
|
||||
public async initializeIfNecessary(
|
||||
previousConfig: FrigateCardConfig | null,
|
||||
previousConfig: AdvancedCameraCardConfig | null,
|
||||
): Promise<void> {
|
||||
if (
|
||||
!isEqual(
|
||||
|
||||
@@ -9,7 +9,7 @@ const WEBKIT_PLAY_SECONDS = 0.5;
|
||||
/**
|
||||
* Fullscreen implementation for webkit based browsers that do not support the
|
||||
* standard Fullscreen API (expected to be exclusively iOS on an iPhone).
|
||||
* See: https://github.com/dermotduffy/frigate-hass-card/issues/1444
|
||||
* See: https://github.com/dermotduffy/advanced-camera-card/issues/1444
|
||||
*/
|
||||
export class WebkitFullScreenProvider
|
||||
extends FullscreenProviderBase
|
||||
|
||||
@@ -94,8 +94,8 @@ export class InitializationManager {
|
||||
!(await this._initializer.initializeMultipleIfNecessary({
|
||||
[InitializationAspect.CAMERAS]: async () => {
|
||||
// Recreate the camera manager to guarantee an immediate re-render.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1811
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1769
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1811
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1769
|
||||
this._api.createCameraManager();
|
||||
return await this._api.getCameraManager().initializeCamerasFromConfig();
|
||||
},
|
||||
@@ -103,7 +103,7 @@ export class InitializationManager {
|
||||
// Connecting the microphone (if configured) is considered mandatory to
|
||||
// avoid issues with some cameras that only allow 2-way audio on the
|
||||
// first stream initialized.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1235
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1235
|
||||
...(this._api.getMicrophoneManager().shouldConnectOnInitialization() && {
|
||||
[InitializationAspect.MICROPHONE_CONNECT]: async () => {
|
||||
// Recreate the microphone manager to guarantee an immediate
|
||||
|
||||
@@ -23,7 +23,7 @@ export class MediaLoadedInfoManager {
|
||||
|
||||
log(
|
||||
this._api.getConfigManager().getCardWideConfig(),
|
||||
`Frigate Card media load: `,
|
||||
`Advanced Camera Card media load: `,
|
||||
mediaLoadedInfo,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CameraConfig, FrigateCardConfig } from '../config/types';
|
||||
import { AdvancedCameraCardConfig, CameraConfig } from '../config/types';
|
||||
import {
|
||||
MEDIA_PLAYER_SUPPORT_BROWSE_MEDIA,
|
||||
MEDIA_PLAYER_SUPPORT_STOP,
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
} from '../const';
|
||||
import { localize } from '../localize/localize';
|
||||
import { errorToConsole } from '../utils/basic';
|
||||
import { Entity } from '../utils/ha/registry/entity/types';
|
||||
import { supportsFeature } from '../utils/ha';
|
||||
import { Entity } from '../utils/ha/registry/entity/types';
|
||||
import { ViewMedia } from '../view/media';
|
||||
import { ViewMediaClassifier } from '../view/media-classifier';
|
||||
import { CardMediaPlayerAPI } from './types';
|
||||
@@ -30,7 +30,7 @@ export class MediaPlayerManager {
|
||||
}
|
||||
|
||||
public async initializeIfNecessary(
|
||||
previousConfig: FrigateCardConfig | null,
|
||||
previousConfig: AdvancedCameraCardConfig | null,
|
||||
): Promise<void> {
|
||||
if (
|
||||
previousConfig?.menu.buttons.media_player.enabled !==
|
||||
@@ -80,7 +80,7 @@ export class MediaPlayerManager {
|
||||
// available in the HA state, only in the registry).
|
||||
this._mediaPlayers = mediaPlayers.filter((entityID) => {
|
||||
// Specifically allow for media players that are not found in the entity registry:
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1016
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1016
|
||||
const entity = mediaPlayerEntities?.get(entityID);
|
||||
return !entity || !entity.hidden_by;
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FrigateCardError, Message, MessageType } from '../types';
|
||||
import { AdvancedCameraCardError, Message, MessageType } from '../types';
|
||||
import { errorToConsole } from '../utils/basic';
|
||||
import { CardMessageAPI } from './types';
|
||||
|
||||
@@ -60,7 +60,7 @@ export class MessageManager {
|
||||
this.setMessageIfHigherPriority({
|
||||
message: prefix ? `${prefix}: ${error.message}` : String(error.message),
|
||||
type: 'error',
|
||||
...(error instanceof FrigateCardError && { context: error.context }),
|
||||
...(error instanceof AdvancedCameraCardError && { context: error.context }),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ export class MicrophoneManager {
|
||||
public isSupported(): boolean {
|
||||
// Some browsers will have mediaDevices/getUserMedia as undefined if
|
||||
// accessed over http.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1543
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1543
|
||||
return !!navigator.mediaDevices?.getUserMedia;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FrigateCardCustomAction, ViewActionConfig } from '../config/types';
|
||||
import { AdvancedCameraCardCustomAction, ViewActionConfig } from '../config/types';
|
||||
import { createCameraAction, createGeneralAction } from '../utils/action.js';
|
||||
import { ViewParameters } from '../view/view';
|
||||
import { CardQueryStringAPI } from './types';
|
||||
@@ -9,7 +9,7 @@ interface QueryStringViewIntent {
|
||||
default?: boolean;
|
||||
substream?: string;
|
||||
};
|
||||
other?: FrigateCardCustomAction[];
|
||||
other?: AdvancedCameraCardCustomAction[];
|
||||
}
|
||||
|
||||
export class QueryStringManager {
|
||||
@@ -72,14 +72,14 @@ export class QueryStringManager {
|
||||
const result: QueryStringViewIntent = {};
|
||||
for (const action of this._getActions()) {
|
||||
if (this._isViewAction(action)) {
|
||||
(result.view ??= {}).view = action.frigate_card_action;
|
||||
(result.view ??= {}).view = action.advanced_camera_card_action;
|
||||
(result.view ??= {}).default = undefined;
|
||||
} else if (action.frigate_card_action === 'default') {
|
||||
} else if (action.advanced_camera_card_action === 'default') {
|
||||
(result.view ??= {}).default = true;
|
||||
(result.view ??= {}).view = undefined;
|
||||
} else if (action.frigate_card_action === 'camera_select') {
|
||||
} else if (action.advanced_camera_card_action === 'camera_select') {
|
||||
(result.view ??= {}).camera = action.camera;
|
||||
} else if (action.frigate_card_action === 'live_substream_select') {
|
||||
} else if (action.advanced_camera_card_action === 'live_substream_select') {
|
||||
(result.view ??= {}).substream = action.camera;
|
||||
} else {
|
||||
(result.other ??= []).push(action);
|
||||
@@ -88,11 +88,11 @@ export class QueryStringManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
protected _getActions(): FrigateCardCustomAction[] {
|
||||
protected _getActions(): AdvancedCameraCardCustomAction[] {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const actions: FrigateCardCustomAction[] = [];
|
||||
const actions: AdvancedCameraCardCustomAction[] = [];
|
||||
const actionRE = new RegExp(
|
||||
/^frigate-card-action([.:](?<cardID>\w+))?[.:](?<action>\w+)/,
|
||||
/^(advanced-camera-card|frigate-card)-action([.:](?<cardID>\w+))?[.:](?<action>\w+)/,
|
||||
);
|
||||
for (const [key, value] of params.entries()) {
|
||||
const match = key.match(actionRE);
|
||||
@@ -102,7 +102,7 @@ export class QueryStringManager {
|
||||
const cardID: string | undefined = match.groups['cardID'];
|
||||
const action = match.groups['action'];
|
||||
|
||||
let customAction: FrigateCardCustomAction | null = null;
|
||||
let customAction: AdvancedCameraCardCustomAction | null = null;
|
||||
switch (action) {
|
||||
case 'camera_select':
|
||||
case 'live_substream_select':
|
||||
@@ -133,7 +133,7 @@ export class QueryStringManager {
|
||||
break;
|
||||
default:
|
||||
console.warn(
|
||||
`Frigate card received unknown card action in query string: ${action}`,
|
||||
`Advanced Camera Card received unknown card action in query string: ${action}`,
|
||||
);
|
||||
}
|
||||
if (customAction) {
|
||||
@@ -144,9 +144,9 @@ export class QueryStringManager {
|
||||
}
|
||||
|
||||
protected _isViewAction = (
|
||||
action: FrigateCardCustomAction,
|
||||
action: AdvancedCameraCardCustomAction,
|
||||
): action is ViewActionConfig => {
|
||||
switch (action.frigate_card_action) {
|
||||
switch (action.advanced_camera_card_action) {
|
||||
case 'clip':
|
||||
case 'clips':
|
||||
case 'diagnostics':
|
||||
|
||||
@@ -62,7 +62,7 @@ export class StatusBarItemManager {
|
||||
...(title
|
||||
? [
|
||||
{
|
||||
type: 'custom:frigate-card-status-bar-string' as const,
|
||||
type: 'custom:advanced-camera-card-status-bar-string' as const,
|
||||
string: title,
|
||||
expand: true,
|
||||
sufficient: true,
|
||||
@@ -74,7 +74,7 @@ export class StatusBarItemManager {
|
||||
...(resolution
|
||||
? [
|
||||
{
|
||||
type: 'custom:frigate-card-status-bar-string' as const,
|
||||
type: 'custom:advanced-camera-card-status-bar-string' as const,
|
||||
string: resolution,
|
||||
...options?.statusConfig?.items.resolution,
|
||||
},
|
||||
@@ -84,7 +84,7 @@ export class StatusBarItemManager {
|
||||
...(technology && technology === 'webrtc'
|
||||
? [
|
||||
{
|
||||
type: 'custom:frigate-card-status-bar-icon' as const,
|
||||
type: 'custom:advanced-camera-card-status-bar-icon' as const,
|
||||
icon: 'mdi:webrtc',
|
||||
...options?.statusConfig?.items.technology,
|
||||
},
|
||||
@@ -92,7 +92,7 @@ export class StatusBarItemManager {
|
||||
: !!technology
|
||||
? [
|
||||
{
|
||||
type: 'custom:frigate-card-status-bar-string' as const,
|
||||
type: 'custom:advanced-camera-card-status-bar-string' as const,
|
||||
string: technology.toUpperCase(),
|
||||
...options?.statusConfig?.items.technology,
|
||||
},
|
||||
@@ -102,7 +102,7 @@ export class StatusBarItemManager {
|
||||
...(engineIcon
|
||||
? [
|
||||
{
|
||||
type: 'custom:frigate-card-status-bar-icon' as const,
|
||||
type: 'custom:advanced-camera-card-status-bar-icon' as const,
|
||||
icon: engineIcon,
|
||||
...options?.statusConfig?.items.engine,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { StyleInfo } from 'lit/directives/style-map';
|
||||
import {
|
||||
FrigateCardConfig,
|
||||
frigateCardConfigDefaults,
|
||||
AdvancedCameraCardConfig,
|
||||
configDefaults,
|
||||
ThemeConfig,
|
||||
ThemeName,
|
||||
} from '../config/types';
|
||||
@@ -25,7 +25,7 @@ export class StyleManager {
|
||||
// as dimension configuration does not apply in fullscreen or expanded mode.
|
||||
const lastKnown = this._api.getMediaLoadedInfoManager().getLastKnown();
|
||||
card.style.setProperty(
|
||||
'--frigate-card-expand-aspect-ratio',
|
||||
'--advanced-camera-card-expand-aspect-ratio',
|
||||
view?.isAnyMediaView() && lastKnown
|
||||
? `${lastKnown.width} / ${lastKnown.height}`
|
||||
: 'unset',
|
||||
@@ -35,16 +35,16 @@ export class StyleManager {
|
||||
// space.
|
||||
const isGrid = view?.isGrid();
|
||||
card.style.setProperty(
|
||||
'--frigate-card-expand-width',
|
||||
'--advanced-camera-card-expand-width',
|
||||
!isGrid && view?.isAnyMediaView()
|
||||
? 'none'
|
||||
: 'var(--frigate-card-expand-max-width)',
|
||||
: 'var(--advanced-camera-card-expand-max-width)',
|
||||
);
|
||||
card.style.setProperty(
|
||||
'--frigate-card-expand-height',
|
||||
'--advanced-camera-card-expand-height',
|
||||
!isGrid && view?.isAnyMediaView()
|
||||
? 'none'
|
||||
: 'var(--frigate-card-expand-max-height)',
|
||||
: 'var(--advanced-camera-card-expand-max-height)',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ export class StyleManager {
|
||||
protected _getThemeNames(themeConfig: ThemeConfig): ThemeName[] | null {
|
||||
return themeConfig.themes.length
|
||||
? themeConfig.themes
|
||||
: frigateCardConfigDefaults.view.theme.themes;
|
||||
: configDefaults.view.theme.themes;
|
||||
}
|
||||
|
||||
protected _setDimmable(): void {
|
||||
@@ -92,7 +92,7 @@ export class StyleManager {
|
||||
const config = this._api.getConfigManager().getConfig();
|
||||
if (config) {
|
||||
const card = this._api.getCardElementManager().getElement();
|
||||
card.style.setProperty('--frigate-card-height', config.dimensions.height);
|
||||
card.style.setProperty('--advanced-camera-card-height', config.dimensions.height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class StyleManager {
|
||||
|
||||
const styles = performance?.style ?? {};
|
||||
for (const configKey of Object.keys(styles)) {
|
||||
const CSSKey = `--frigate-card-css-${configKey.replaceAll('_', '-')}`;
|
||||
const CSSKey = `--advanced-camera-card-css-${configKey.replaceAll('_', '-')}`;
|
||||
if (styles[configKey] === false) {
|
||||
element.style.setProperty(CSSKey, STYLE_DISABLE_MAP[configKey]);
|
||||
} else {
|
||||
@@ -116,7 +116,7 @@ export class StyleManager {
|
||||
}
|
||||
|
||||
protected _isAspectRatioEnforced(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
view?: View | null,
|
||||
): boolean {
|
||||
const aspectRatioMode = config.dimensions.aspect_ratio_mode;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
FRIGATE_CARD_VIEW_DEFAULT,
|
||||
FrigateCardConfig,
|
||||
FrigateCardView,
|
||||
VIEW_DEFAULT,
|
||||
AdvancedCameraCardConfig,
|
||||
AdvancedCameraCardView,
|
||||
ViewDisplayMode,
|
||||
} from '../../config/types';
|
||||
import { localize } from '../../localize/localize';
|
||||
@@ -26,7 +26,7 @@ export class ViewFactory {
|
||||
|
||||
// Neither options.baseView.camera nor options.baseView.view are respected
|
||||
// here, since this is the default view / camera.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1564
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1564
|
||||
|
||||
let cameraID: string | null = null;
|
||||
const viewName = options?.params?.view ?? config.view.default;
|
||||
@@ -101,11 +101,8 @@ export class ViewFactory {
|
||||
}
|
||||
|
||||
if (!this.isViewSupportedByCamera(cameraID, viewName)) {
|
||||
if (
|
||||
options?.failSafe &&
|
||||
this.isViewSupportedByCamera(cameraID, FRIGATE_CARD_VIEW_DEFAULT)
|
||||
) {
|
||||
viewName = FRIGATE_CARD_VIEW_DEFAULT;
|
||||
if (options?.failSafe && this.isViewSupportedByCamera(cameraID, VIEW_DEFAULT)) {
|
||||
viewName = VIEW_DEFAULT;
|
||||
} else {
|
||||
const capabilities = this._api
|
||||
.getCameraManager()
|
||||
@@ -124,7 +121,7 @@ export class ViewFactory {
|
||||
const configuredDisplayMode = this._getDefaultDisplayModeForView(viewName, config);
|
||||
const displayMode =
|
||||
// Prioritize the configured display mode (if present).
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1812
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1812
|
||||
(viewName !== options?.baseView?.view ? configuredDisplayMode : null) ??
|
||||
options?.params?.displayMode ??
|
||||
options?.baseView?.displayMode ??
|
||||
@@ -147,13 +144,16 @@ export class ViewFactory {
|
||||
return view;
|
||||
}
|
||||
|
||||
public isViewSupportedByCamera(cameraID: string, view: FrigateCardView): boolean {
|
||||
public isViewSupportedByCamera(
|
||||
cameraID: string,
|
||||
view: AdvancedCameraCardView,
|
||||
): boolean {
|
||||
return !!getCameraIDsForViewName(this._api.getCameraManager(), view, cameraID).size;
|
||||
}
|
||||
|
||||
protected _getDefaultDisplayModeForView(
|
||||
viewName: FrigateCardView,
|
||||
config: FrigateCardConfig,
|
||||
viewName: AdvancedCameraCardView,
|
||||
config: AdvancedCameraCardConfig,
|
||||
): ViewDisplayMode | null {
|
||||
let mode: ViewDisplayMode | null = null;
|
||||
switch (viewName) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ViewContext } from 'view';
|
||||
import { FrigateCardView } from '../../config/types.js';
|
||||
import { FrigateCardError } from '../../types.js';
|
||||
import { AdvancedCameraCardView } from '../../config/types.js';
|
||||
import { AdvancedCameraCardError } from '../../types.js';
|
||||
import { MediaQueriesResults } from '../../view/media-queries-results.js';
|
||||
import { MediaQueries } from '../../view/media-queries.js';
|
||||
import { ViewMedia } from '../../view/media.js';
|
||||
@@ -72,9 +72,9 @@ export interface ViewManagerInterface {
|
||||
|
||||
setViewWithMergedContext(context: ViewContext | null): void;
|
||||
|
||||
isViewSupportedByCamera(cameraID: string, view: FrigateCardView): boolean;
|
||||
isViewSupportedByCamera(cameraID: string, view: AdvancedCameraCardView): boolean;
|
||||
hasMajorMediaChange(oldView?: View | null, newView?: View | null): boolean;
|
||||
}
|
||||
|
||||
export class ViewNoCameraError extends FrigateCardError {}
|
||||
export class ViewIncompatible extends FrigateCardError {}
|
||||
export class ViewNoCameraError extends AdvancedCameraCardError {}
|
||||
export class ViewIncompatible extends AdvancedCameraCardError {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ViewContext } from 'view';
|
||||
import { FrigateCardView } from '../../config/types';
|
||||
import { AdvancedCameraCardView } from '../../config/types';
|
||||
import { log } from '../../utils/debug';
|
||||
import { getStreamCameraID } from '../../utils/substream';
|
||||
import { MediaQueriesClassifier } from '../../view/media-queries-classifier';
|
||||
@@ -217,7 +217,7 @@ export class ViewManager implements ViewManagerInterface {
|
||||
// target media of the gallery (e.g. clips, snapshots or recordings) is
|
||||
// equal to the queries that are currently used in the viewer.
|
||||
//
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/885
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/885
|
||||
|
||||
const switchingFromViewerToGallery =
|
||||
this._view?.isViewerView() && newView?.isGalleryView();
|
||||
@@ -233,7 +233,10 @@ export class ViewManager implements ViewManagerInterface {
|
||||
}
|
||||
}
|
||||
|
||||
public isViewSupportedByCamera(cameraID: string, view: FrigateCardView): boolean {
|
||||
public isViewSupportedByCamera(
|
||||
cameraID: string,
|
||||
view: AdvancedCameraCardView,
|
||||
): boolean {
|
||||
return !!getCameraIDsForViewName(this._api.getCameraManager(), view, cameraID).size;
|
||||
}
|
||||
|
||||
@@ -266,7 +269,7 @@ export class ViewManager implements ViewManagerInterface {
|
||||
// If the query string contains a view related action, we don't set any view
|
||||
// here and allow that action to be triggered by the next call of to execute
|
||||
// query actions (called at least once per render cycle).
|
||||
// Related: https://github.com/dermotduffy/frigate-hass-card/issues/1200
|
||||
// Related: https://github.com/dermotduffy/advanced-camera-card/issues/1200
|
||||
if (!this._api.getQueryStringManager().hasViewRelatedActionsToRun()) {
|
||||
// This is not awaited to allow the initialization to complete before the
|
||||
// query is answered.
|
||||
@@ -280,7 +283,7 @@ export class ViewManager implements ViewManagerInterface {
|
||||
|
||||
log(
|
||||
this._api.getConfigManager().getCardWideConfig(),
|
||||
`Frigate Card view change: `,
|
||||
`Advanced Camera Card view change: `,
|
||||
view,
|
||||
);
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ export class ViewQueryExecutor {
|
||||
new MergeContextViewModifier({
|
||||
// Force the window to start at the most recent time, not
|
||||
// necessarily when the most recent event/recording was:
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/1301
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/1301
|
||||
timeline: {
|
||||
window: {
|
||||
start: sub(now, {
|
||||
|
||||
+63
-58
@@ -11,29 +11,29 @@ import { ConditionsEvaluateRequestEvent } from './card-controller/conditions-man
|
||||
import { CardController } from './card-controller/controller';
|
||||
import { MenuButtonController } from './components-lib/menu-button-controller';
|
||||
import './components/elements.js';
|
||||
import { FrigateCardElements } from './components/elements.js';
|
||||
import { AdvancedCameraCardElements } from './components/elements.js';
|
||||
import './components/loading.js';
|
||||
import './components/menu.js';
|
||||
import { FrigateCardMenu } from './components/menu.js';
|
||||
import { AdvancedCameraCardMenu } from './components/menu.js';
|
||||
import './components/message.js';
|
||||
import { renderMessage } from './components/message.js';
|
||||
import './components/overlay.js';
|
||||
import { FrigateCardOverlay } from './components/overlay.js';
|
||||
import { AdvancedCameraCardOverlay } from './components/overlay.js';
|
||||
import './components/status-bar';
|
||||
import './components/thumbnail-carousel.js';
|
||||
import './components/views.js';
|
||||
import { FrigateCardViews } from './components/views.js';
|
||||
import { AdvancedCameraCardViews } from './components/views.js';
|
||||
import {
|
||||
FrigateCardConfig,
|
||||
AdvancedCameraCardConfig,
|
||||
MenuItem,
|
||||
RawFrigateCardConfig,
|
||||
RawAdvancedCameraCardConfig,
|
||||
StatusBarItem,
|
||||
} from './config/types';
|
||||
import { REPO_URL } from './const.js';
|
||||
import { localize } from './localize/localize.js';
|
||||
import cardStyle from './scss/card.scss';
|
||||
import { ExtendedHomeAssistant, MediaLoadedInfo, Message } from './types.js';
|
||||
import { frigateCardHasAction } from './utils/action.js';
|
||||
import { hasAction } from './utils/action.js';
|
||||
import { getReleaseVersion } from './utils/diagnostics';
|
||||
|
||||
// ***************************************************************************
|
||||
@@ -57,23 +57,14 @@ import { getReleaseVersion } from './utils/diagnostics';
|
||||
* - Directly specifying hooks (e.g. for snapshot viewing with simple <img> tags)
|
||||
*/
|
||||
|
||||
/** Actions (action/menu/ll-custom events):
|
||||
*
|
||||
* The card supports actions being configured in a number of places (e.g. tap on
|
||||
* an element, double_tap on a menu item, hold on the live view). These actions
|
||||
* are handled by frigateCardHandleActionConfig(). For Frigate-card specific
|
||||
* actions, the frigateCardHandleActionConfig() call will result in an ll-custom
|
||||
* DOM event being fired, which needs to be caught at the card level to handle.
|
||||
*/
|
||||
|
||||
// ***************************************************************************
|
||||
// Static Initializers
|
||||
// ***************************************************************************
|
||||
|
||||
console.info(
|
||||
`%c FRIGATE-HASS-CARD \n` + `%c ${localize('common.version')} ` + getReleaseVersion(),
|
||||
'color: pink; font-weight: bold; background: black',
|
||||
'color: white; font-weight: bold; background: dimgray',
|
||||
`%c 📷 Advanced Camera Card %c ${getReleaseVersion()} `,
|
||||
'padding: 3px; color: black; background: pink;',
|
||||
'padding: 3px; color: black; background: white;',
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -81,22 +72,22 @@ console.info(
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any).customCards.push({
|
||||
type: 'frigate-card',
|
||||
name: localize('common.frigate_card'),
|
||||
description: localize('common.frigate_card_description'),
|
||||
type: 'advanced-camera-card',
|
||||
name: localize('common.advanced_camera_card'),
|
||||
description: localize('common.advanced_camera_card_description'),
|
||||
preview: true,
|
||||
documentationURL: REPO_URL,
|
||||
});
|
||||
|
||||
// ***************************************************************************
|
||||
// Main FrigateCard WebComponent
|
||||
// Main AdvancedCameraCard WebComponent
|
||||
//
|
||||
// Any non-rendering / non-lit related functionality should be added to
|
||||
// CardController instead of this file.
|
||||
// ***************************************************************************
|
||||
|
||||
@customElement('frigate-card')
|
||||
class FrigateCard extends LitElement {
|
||||
@customElement('advanced-camera-card')
|
||||
class AdvancedCameraCard extends LitElement {
|
||||
protected _controller = new CardController(
|
||||
this,
|
||||
// Callback to scroll the main pane back to the top (example usecase: scrolling
|
||||
@@ -109,14 +100,14 @@ class FrigateCard extends LitElement {
|
||||
|
||||
protected _menuButtonController = new MenuButtonController();
|
||||
|
||||
protected _refMenu: Ref<FrigateCardMenu> = createRef();
|
||||
protected _refOverlay: Ref<FrigateCardOverlay> = createRef();
|
||||
protected _refMenu: Ref<AdvancedCameraCardMenu> = createRef();
|
||||
protected _refOverlay: Ref<AdvancedCameraCardOverlay> = createRef();
|
||||
protected _refMain: Ref<HTMLElement> = createRef();
|
||||
protected _refElements: Ref<FrigateCardElements> = createRef();
|
||||
protected _refViews: Ref<FrigateCardViews> = createRef();
|
||||
protected _refElements: Ref<AdvancedCameraCardElements> = createRef();
|
||||
protected _refViews: Ref<AdvancedCameraCardViews> = createRef();
|
||||
|
||||
// Convenience methods for very frequently accessed attributes.
|
||||
get _config(): FrigateCardConfig | null {
|
||||
get _config(): AdvancedCameraCardConfig | null {
|
||||
return this._controller.getConfigManager().getConfig();
|
||||
}
|
||||
|
||||
@@ -145,7 +136,10 @@ class FrigateCard extends LitElement {
|
||||
return await CardController.getConfigElement();
|
||||
}
|
||||
|
||||
public static getStubConfig(_: HomeAssistant, entities: string[]): FrigateCardConfig {
|
||||
public static getStubConfig(
|
||||
_: HomeAssistant,
|
||||
entities: string[],
|
||||
): AdvancedCameraCardConfig {
|
||||
return CardController.getStubConfig(entities);
|
||||
}
|
||||
|
||||
@@ -153,7 +147,7 @@ class FrigateCard extends LitElement {
|
||||
// Update the components that need to know about condition changes. Trigger
|
||||
// updates directly on them to them to avoid the performance hit of a entire
|
||||
// card re-render (esp. when using card-mod).
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/678
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/678
|
||||
if (this._refViews.value) {
|
||||
this._refViews.value.conditionsManagerEpoch =
|
||||
this._controller.getConditionsManager().getEpoch() ?? undefined;
|
||||
@@ -164,7 +158,7 @@ class FrigateCard extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
public setConfig(config: RawFrigateCardConfig): void {
|
||||
public setConfig(config: RawAdvancedCameraCardConfig): void {
|
||||
this._controller.getConfigManager().setConfig(config);
|
||||
}
|
||||
|
||||
@@ -246,7 +240,9 @@ class FrigateCard extends LitElement {
|
||||
|
||||
return html`
|
||||
${position === 'overlay'
|
||||
? html`<frigate-card-overlay>${getContents('overlay')}</frigate-card-overlay>`
|
||||
? html`<advanced-camera-card-overlay
|
||||
>${getContents('overlay')}</advanced-camera-card-overlay
|
||||
>`
|
||||
: html`<div class="outerlay" data-position="${position}">
|
||||
${getContents('outerlay')}
|
||||
</div>`}
|
||||
@@ -259,7 +255,7 @@ class FrigateCard extends LitElement {
|
||||
return;
|
||||
}
|
||||
return html`
|
||||
<frigate-card-menu
|
||||
<advanced-camera-card-menu
|
||||
${ref(this._refMenu)}
|
||||
slot=${ifDefined(slot)}
|
||||
.hass=${this._hass}
|
||||
@@ -280,7 +276,7 @@ class FrigateCard extends LitElement {
|
||||
},
|
||||
)}
|
||||
.entityRegistryManager=${this._controller.getEntityRegistryManager()}
|
||||
></frigate-card-menu>
|
||||
></advanced-camera-card-menu>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -290,7 +286,7 @@ class FrigateCard extends LitElement {
|
||||
}
|
||||
|
||||
return html`
|
||||
<frigate-card-status-bar
|
||||
<advanced-camera-card-status-bar
|
||||
slot=${ifDefined(slot)}
|
||||
.items=${this._controller.getStatusBarItemManager().calculateItems({
|
||||
statusConfig: this._config.status_bar,
|
||||
@@ -299,7 +295,7 @@ class FrigateCard extends LitElement {
|
||||
mediaLoadedInfo: this._controller.getMediaLoadedInfoManager().get(),
|
||||
})}
|
||||
.config=${this._config.status_bar}
|
||||
></frigate-card-status-bar>
|
||||
></advanced-camera-card-status-bar>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -359,36 +355,36 @@ class FrigateCard extends LitElement {
|
||||
html` <ha-card
|
||||
id="ha-card"
|
||||
.actionHandler=${actionHandler({
|
||||
hasHold: frigateCardHasAction(actions.hold_action),
|
||||
hasDoubleClick: frigateCardHasAction(actions.double_tap_action),
|
||||
hasHold: hasAction(actions.hold_action),
|
||||
hasDoubleClick: hasAction(actions.double_tap_action),
|
||||
})}
|
||||
style="${styleMap(this._controller.getStyleManager().getAspectRatioStyle())}"
|
||||
@frigate-card:message=${(ev: CustomEvent<Message>) =>
|
||||
@advanced-camera-card:message=${(ev: CustomEvent<Message>) =>
|
||||
this._controller.getMessageManager().setMessageIfHigherPriority(ev.detail)}
|
||||
@frigate-card:media:loaded=${(ev: CustomEvent<MediaLoadedInfo>) =>
|
||||
@advanced-camera-card:media:loaded=${(ev: CustomEvent<MediaLoadedInfo>) =>
|
||||
this._controller.getMediaLoadedInfoManager().set(ev.detail)}
|
||||
@frigate-card:media:unloaded=${() =>
|
||||
@advanced-camera-card:media:unloaded=${() =>
|
||||
this._controller.getMediaLoadedInfoManager().clear()}
|
||||
@frigate-card:media:volumechange=${
|
||||
@advanced-camera-card:media:volumechange=${
|
||||
() => this.requestUpdate() /* Refresh mute menu button */
|
||||
}
|
||||
@frigate-card:media:play=${
|
||||
@advanced-camera-card:media:play=${
|
||||
() => this.requestUpdate() /* Refresh play/pause menu button */
|
||||
}
|
||||
@frigate-card:media:pause=${
|
||||
@advanced-camera-card:media:pause=${
|
||||
() => this.requestUpdate() /* Refresh play/pause menu button */
|
||||
}
|
||||
@frigate-card:focus=${() => this.focus()}
|
||||
@advanced-camera-card:focus=${() => this.focus()}
|
||||
>
|
||||
${showLoading
|
||||
? html`<frigate-card-loading
|
||||
? html`<advanced-camera-card-loading
|
||||
?loaded=${this._controller.getInitializationManager().wasEverInitialized()}
|
||||
></frigate-card-loading>`
|
||||
></advanced-camera-card-loading>`
|
||||
: ''}
|
||||
${this._renderMenuStatusContainer('top')}
|
||||
${this._renderMenuStatusContainer('overlay')}
|
||||
<div ${ref(this._refMain)} class="${classMap(mainClasses)}">
|
||||
<frigate-card-views
|
||||
<advanced-camera-card-views
|
||||
${ref(this._refViews)}
|
||||
.hass=${this._hass}
|
||||
.viewManagerEpoch=${this._controller.getViewManager().getEpoch()}
|
||||
@@ -410,7 +406,7 @@ class FrigateCard extends LitElement {
|
||||
? this._controller.getTriggersManager().getTriggeredCameraIDs()
|
||||
: undefined}
|
||||
.deviceRegistryManager=${this._controller.getDeviceRegistryManager()}
|
||||
></frigate-card-views>
|
||||
></advanced-camera-card-views>
|
||||
${this._controller.getMessageManager().hasMessage()
|
||||
? // Keep message rendering to last to show messages that may have been
|
||||
// generated during the render.
|
||||
@@ -421,32 +417,36 @@ class FrigateCard extends LitElement {
|
||||
${this._config?.elements
|
||||
? // Elements need to render after the main views so it can render 'on
|
||||
// top'.
|
||||
html` <frigate-card-elements
|
||||
html` <advanced-camera-card-elements
|
||||
${ref(this._refElements)}
|
||||
.hass=${this._hass}
|
||||
.elements=${this._config?.elements}
|
||||
.conditionsManagerEpoch=${this._controller
|
||||
.getConditionsManager()
|
||||
?.getEpoch()}
|
||||
@frigate-card:menu:add=${(ev: CustomEvent<MenuItem>) => {
|
||||
@advanced-camera-card:menu:add=${(ev: CustomEvent<MenuItem>) => {
|
||||
this._menuButtonController.addDynamicMenuButton(ev.detail);
|
||||
this.requestUpdate();
|
||||
}}
|
||||
@frigate-card:menu:remove=${(ev: CustomEvent<MenuItem>) => {
|
||||
@advanced-camera-card:menu:remove=${(ev: CustomEvent<MenuItem>) => {
|
||||
this._menuButtonController.removeDynamicMenuButton(ev.detail);
|
||||
this.requestUpdate();
|
||||
}}
|
||||
@frigate-card:status-bar:add=${(ev: CustomEvent<StatusBarItem>) => {
|
||||
@advanced-camera-card:status-bar:add=${(
|
||||
ev: CustomEvent<StatusBarItem>,
|
||||
) => {
|
||||
this._controller
|
||||
.getStatusBarItemManager()
|
||||
.addDynamicStatusBarItem(ev.detail);
|
||||
}}
|
||||
@frigate-card:status-bar:remove=${(ev: CustomEvent<StatusBarItem>) => {
|
||||
@advanced-camera-card:status-bar:remove=${(
|
||||
ev: CustomEvent<StatusBarItem>,
|
||||
) => {
|
||||
this._controller
|
||||
.getStatusBarItemManager()
|
||||
.removeDynamicStatusBarItem(ev.detail);
|
||||
}}
|
||||
@frigate-card:conditions:evaluate=${(
|
||||
@advanced-camera-card:conditions:evaluate=${(
|
||||
ev: ConditionsEvaluateRequestEvent,
|
||||
) => {
|
||||
ev.evaluation = this._controller
|
||||
@@ -454,7 +454,7 @@ class FrigateCard extends LitElement {
|
||||
?.evaluateConditions(ev.conditions);
|
||||
}}
|
||||
>
|
||||
</frigate-card-elements>`
|
||||
</advanced-camera-card-elements>`
|
||||
: ``}
|
||||
</ha-card>`,
|
||||
);
|
||||
@@ -477,8 +477,13 @@ class FrigateCard extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the old name around for backwards compatibility.
|
||||
@customElement('frigate-card')
|
||||
class FrigateCard extends AdvancedCameraCard {}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'advanced-camera-card': AdvancedCameraCard;
|
||||
'frigate-card': FrigateCard;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { LitElement, ReactiveController } from 'lit';
|
||||
import { MediaLoadedInfo } from '../../types.js';
|
||||
import {
|
||||
FrigateCardMediaLoadedEventTarget,
|
||||
AdvancedCameraCardMediaLoadedEventTarget,
|
||||
dispatchExistingMediaLoadedInfoAsEvent,
|
||||
} from '../../utils/media-info.js';
|
||||
import { FrigateCardMessageEventTarget } from '../message/dispatch.js';
|
||||
import { AdvancedCameraCardMessageEventTarget } from '../message/dispatch.js';
|
||||
|
||||
interface LiveViewContext {
|
||||
// A cameraID override (used for dependencies/substreams to force a different
|
||||
@@ -24,8 +24,8 @@ interface LastMediaLoadedInfo {
|
||||
}
|
||||
|
||||
type LiveControllerHost = LitElement &
|
||||
FrigateCardMediaLoadedEventTarget &
|
||||
FrigateCardMessageEventTarget;
|
||||
AdvancedCameraCardMediaLoadedEventTarget &
|
||||
AdvancedCameraCardMessageEventTarget;
|
||||
|
||||
export class LiveController implements ReactiveController {
|
||||
protected _host: LiveControllerHost;
|
||||
@@ -56,13 +56,19 @@ export class LiveController implements ReactiveController {
|
||||
public hostConnected(): void {
|
||||
this._intersectionObserver.observe(this._host);
|
||||
|
||||
this._host.addEventListener('frigate-card:media:loaded', this._handleMediaLoaded);
|
||||
this._host.addEventListener(
|
||||
'advanced-camera-card:media:loaded',
|
||||
this._handleMediaLoaded,
|
||||
);
|
||||
}
|
||||
|
||||
public hostDisconnected(): void {
|
||||
this._intersectionObserver.disconnect();
|
||||
|
||||
this._host.removeEventListener('frigate-card:media:loaded', this._handleMediaLoaded);
|
||||
this._host.removeEventListener(
|
||||
'advanced-camera-card:media:loaded',
|
||||
this._handleMediaLoaded,
|
||||
);
|
||||
}
|
||||
|
||||
public isInBackground(): boolean {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { dispatchFrigateCardEvent } from '../../../utils/basic';
|
||||
import { dispatchAdvancedCameraCardEvent } from '../../../utils/basic';
|
||||
|
||||
export function dispatchLiveErrorEvent(element: EventTarget): void {
|
||||
dispatchFrigateCardEvent(element, 'live:error');
|
||||
dispatchAdvancedCameraCardEvent(element, 'live:error');
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
AutoPlayCondition,
|
||||
AutoUnmuteCondition,
|
||||
} from '../config/types.js';
|
||||
import { FrigateCardMediaPlayer } from '../types.js';
|
||||
import { FrigateCardMediaLoadedEventTarget } from '../utils/media-info.js';
|
||||
import { AdvancedCameraCardMediaPlayer } from '../types.js';
|
||||
import { AdvancedCameraCardMediaLoadedEventTarget } from '../utils/media-info.js';
|
||||
import { Timer } from '../utils/timer.js';
|
||||
|
||||
export interface MediaActionsControllerOptions {
|
||||
@@ -21,8 +21,8 @@ export interface MediaActionsControllerOptions {
|
||||
microphoneMuteSeconds?: number;
|
||||
}
|
||||
|
||||
type RenderRoot = HTMLElement & FrigateCardMediaLoadedEventTarget;
|
||||
type PlayerElement = HTMLElement & FrigateCardMediaPlayer;
|
||||
type RenderRoot = HTMLElement & AdvancedCameraCardMediaLoadedEventTarget;
|
||||
type PlayerElement = HTMLElement & AdvancedCameraCardMediaPlayer;
|
||||
|
||||
/**
|
||||
* General note: Always unmute before playing, since Chrome may pause a piece of
|
||||
@@ -191,7 +191,7 @@ export class MediaActionsController {
|
||||
|
||||
protected _removeChildHandlers(): void {
|
||||
for (const [child, callback] of this._eventListeners.entries()) {
|
||||
child.removeEventListener('frigate-card:media:loaded', callback);
|
||||
child.removeEventListener('advanced-camera-card:media:loaded', callback);
|
||||
}
|
||||
this._eventListeners.clear();
|
||||
}
|
||||
@@ -223,7 +223,7 @@ export class MediaActionsController {
|
||||
for (const [index, child] of this._children.entries()) {
|
||||
const eventListener = () => this._mediaLoadedHandler(index);
|
||||
this._eventListeners.set(child, eventListener);
|
||||
child.addEventListener('frigate-card:media:loaded', eventListener);
|
||||
child.addEventListener('advanced-camera-card:media:loaded', eventListener);
|
||||
}
|
||||
}
|
||||
protected async _intersectionHandler(
|
||||
|
||||
@@ -4,12 +4,12 @@ import Masonry from 'masonry-layout';
|
||||
import { ViewDisplayConfig } from '../config/types';
|
||||
import { MediaLoadedInfo } from '../types';
|
||||
import {
|
||||
dispatchFrigateCardEvent,
|
||||
dispatchAdvancedCameraCardEvent,
|
||||
getChildrenFromElement,
|
||||
setOrRemoveAttribute,
|
||||
} from '../utils/basic';
|
||||
import {
|
||||
FrigateCardMediaLoadedEventTarget,
|
||||
AdvancedCameraCardMediaLoadedEventTarget,
|
||||
dispatchExistingMediaLoadedInfoAsEvent,
|
||||
dispatchMediaUnloadedEvent,
|
||||
} from '../utils/media-info';
|
||||
@@ -24,7 +24,7 @@ const MEDIA_GRID_DEFAULT_SELECTED_WIDTH_FACTOR = 2.0;
|
||||
const MEDIA_GRID_HORIZONTAL_GUTTER_WIDTH = 1;
|
||||
|
||||
type GridID = string;
|
||||
type MediaGridChild = HTMLElement & FrigateCardMediaLoadedEventTarget;
|
||||
type MediaGridChild = HTMLElement & AdvancedCameraCardMediaLoadedEventTarget;
|
||||
type MediaGridContents = Map<GridID, MediaGridChild>;
|
||||
|
||||
export interface MediaGridSelected {
|
||||
@@ -137,7 +137,7 @@ export class MediaGridController {
|
||||
}
|
||||
|
||||
this._selected = id;
|
||||
dispatchFrigateCardEvent(this._host, 'media-grid:selected', { selected: id });
|
||||
dispatchAdvancedCameraCardEvent(this._host, 'media-grid:selected', { selected: id });
|
||||
|
||||
const mediaLoadedInfo = this._mediaLoadedInfoMap.get(id);
|
||||
if (mediaLoadedInfo) {
|
||||
@@ -155,7 +155,7 @@ export class MediaGridController {
|
||||
public unselectAll() {
|
||||
if (this._selected !== null) {
|
||||
dispatchMediaUnloadedEvent(this._host);
|
||||
dispatchFrigateCardEvent(this._host, 'media-grid:unselected');
|
||||
dispatchAdvancedCameraCardEvent(this._host, 'media-grid:unselected');
|
||||
}
|
||||
this._selected = null;
|
||||
this._updateSelectedStylesOnElements();
|
||||
@@ -251,7 +251,7 @@ export class MediaGridController {
|
||||
});
|
||||
|
||||
child.addEventListener(
|
||||
'frigate-card:media:loaded',
|
||||
'advanced-camera-card:media:loaded',
|
||||
this._handleMediaLoadedInfoEvent,
|
||||
);
|
||||
}
|
||||
@@ -262,7 +262,7 @@ export class MediaGridController {
|
||||
});
|
||||
|
||||
child.removeEventListener(
|
||||
'frigate-card:media:loaded',
|
||||
'advanced-camera-card:media:loaded',
|
||||
this._handleMediaLoadedInfoEvent,
|
||||
);
|
||||
}
|
||||
@@ -345,12 +345,12 @@ export class MediaGridController {
|
||||
|
||||
protected _setColumnSizeStyles(): void {
|
||||
this._host.style.setProperty(
|
||||
'--frigate-card-grid-column-size',
|
||||
'--advanced-camera-card-grid-column-size',
|
||||
`${this._getColumnSize()}px`,
|
||||
);
|
||||
|
||||
this._host.style.setProperty(
|
||||
'--frigate-card-grid-selected-width-factor',
|
||||
'--advanced-camera-card-grid-selected-width-factor',
|
||||
`${
|
||||
this._displayConfig?.grid_selected_width_factor ??
|
||||
MEDIA_GRID_DEFAULT_SELECTED_WIDTH_FACTOR
|
||||
|
||||
@@ -6,12 +6,11 @@ import { MediaPlayerManager } from '../card-controller/media-player-manager';
|
||||
import { MicrophoneManager } from '../card-controller/microphone-manager';
|
||||
import { ViewManager } from '../card-controller/view/view-manager';
|
||||
import {
|
||||
FRIGATE_CARD_VIEWS_USER_SPECIFIED,
|
||||
FrigateCardConfig,
|
||||
FrigateCardCustomAction,
|
||||
AdvancedCameraCardConfig,
|
||||
AdvancedCameraCardCustomAction,
|
||||
MenuItem,
|
||||
VIEWS_USER_SPECIFIED,
|
||||
} from '../config/types';
|
||||
import { FRIGATE_BUTTON_MENU_ICON } from '../const';
|
||||
import { localize } from '../localize/localize.js';
|
||||
import { MediaLoadedInfo } from '../types';
|
||||
import {
|
||||
@@ -63,12 +62,12 @@ export class MenuButtonController {
|
||||
*/
|
||||
public calculateButtons(
|
||||
hass: HomeAssistant,
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
options?: MenuButtonControllerOptions,
|
||||
): MenuItem[] {
|
||||
return [
|
||||
this._getDefaultButton(config),
|
||||
this._getIrisButton(config),
|
||||
this._getCamerasButton(config, cameraManager, options?.view),
|
||||
this._getSubstreamsButton(config, cameraManager, options?.view),
|
||||
this._getLiveButton(config, options?.view, options?.viewManager),
|
||||
@@ -107,27 +106,25 @@ export class MenuButtonController {
|
||||
].filter(isTruthy);
|
||||
}
|
||||
|
||||
protected _getDefaultButton(config: FrigateCardConfig): MenuItem {
|
||||
protected _getIrisButton(config: AdvancedCameraCardConfig): MenuItem {
|
||||
return {
|
||||
// Use a magic icon value that the menu will use to render the custom
|
||||
// Frigate icon.
|
||||
icon: FRIGATE_BUTTON_MENU_ICON,
|
||||
...config.menu.buttons.frigate,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
title: localize('config.menu.buttons.frigate'),
|
||||
icon: 'iris',
|
||||
...config.menu.buttons.iris,
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.iris'),
|
||||
// The default button always shows regardless of whether the menu is
|
||||
// hidden or not.
|
||||
permanent: true,
|
||||
tap_action:
|
||||
config.menu?.style === 'hidden'
|
||||
? (createGeneralAction('menu_toggle') as FrigateCardCustomAction)
|
||||
: (createGeneralAction('default') as FrigateCardCustomAction),
|
||||
hold_action: createGeneralAction('diagnostics') as FrigateCardCustomAction,
|
||||
? (createGeneralAction('menu_toggle') as AdvancedCameraCardCustomAction)
|
||||
: (createGeneralAction('default') as AdvancedCameraCardCustomAction),
|
||||
hold_action: createGeneralAction('diagnostics') as AdvancedCameraCardCustomAction,
|
||||
};
|
||||
}
|
||||
|
||||
protected _getCamerasButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
@@ -153,7 +150,7 @@ export class MenuButtonController {
|
||||
return {
|
||||
icon: 'mdi:video-switch',
|
||||
...config.menu.buttons.cameras,
|
||||
type: 'custom:frigate-card-menu-submenu',
|
||||
type: 'custom:advanced-camera-card-menu-submenu',
|
||||
title: localize('config.menu.buttons.cameras'),
|
||||
items: submenuItems,
|
||||
};
|
||||
@@ -162,7 +159,7 @@ export class MenuButtonController {
|
||||
}
|
||||
|
||||
protected _getSubstreamsButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
@@ -190,10 +187,10 @@ export class MenuButtonController {
|
||||
substreamAwareCameraID !== view.camera ? this._getEmphasizedStyle() : {},
|
||||
title: localize('config.menu.buttons.substreams'),
|
||||
...config.menu.buttons.substreams,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
tap_action: createGeneralAction(
|
||||
hasSubstream(view) ? 'live_substream_off' : 'live_substream_on',
|
||||
) as FrigateCardCustomAction,
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
};
|
||||
} else if (streams.length > 2) {
|
||||
const menuItems = Array.from(streams, (streamID) => {
|
||||
@@ -216,7 +213,7 @@ export class MenuButtonController {
|
||||
style:
|
||||
substreamAwareCameraID !== view.camera ? this._getEmphasizedStyle() : {},
|
||||
...config.menu.buttons.substreams,
|
||||
type: 'custom:frigate-card-menu-submenu',
|
||||
type: 'custom:advanced-camera-card-menu-submenu',
|
||||
items: menuItems,
|
||||
};
|
||||
}
|
||||
@@ -225,7 +222,7 @@ export class MenuButtonController {
|
||||
}
|
||||
|
||||
protected _getLiveButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
view?: View | null,
|
||||
viewManager?: ViewManager | null,
|
||||
): MenuItem | null {
|
||||
@@ -233,16 +230,16 @@ export class MenuButtonController {
|
||||
? {
|
||||
icon: 'mdi:cctv',
|
||||
...config.menu.buttons.live,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.live'),
|
||||
style: view.is('live') ? this._getEmphasizedStyle() : {},
|
||||
tap_action: createGeneralAction('live') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('live') as AdvancedCameraCardCustomAction,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getClipsButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
view?: View | null,
|
||||
viewManager?: ViewManager | null,
|
||||
): MenuItem | null {
|
||||
@@ -250,17 +247,17 @@ export class MenuButtonController {
|
||||
? {
|
||||
icon: 'mdi:filmstrip',
|
||||
...config.menu.buttons.clips,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.clips'),
|
||||
style: view?.is('clips') ? this._getEmphasizedStyle() : {},
|
||||
tap_action: createGeneralAction('clips') as FrigateCardCustomAction,
|
||||
hold_action: createGeneralAction('clip') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('clips') as AdvancedCameraCardCustomAction,
|
||||
hold_action: createGeneralAction('clip') as AdvancedCameraCardCustomAction,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getSnapshotsButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
view?: View | null,
|
||||
viewManager?: ViewManager | null,
|
||||
): MenuItem | null {
|
||||
@@ -268,17 +265,17 @@ export class MenuButtonController {
|
||||
? {
|
||||
icon: 'mdi:camera',
|
||||
...config.menu.buttons.snapshots,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.snapshots'),
|
||||
style: view?.is('snapshots') ? this._getEmphasizedStyle() : {},
|
||||
tap_action: createGeneralAction('snapshots') as FrigateCardCustomAction,
|
||||
hold_action: createGeneralAction('snapshot') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('snapshots') as AdvancedCameraCardCustomAction,
|
||||
hold_action: createGeneralAction('snapshot') as AdvancedCameraCardCustomAction,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getRecordingsButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
view?: View | null,
|
||||
viewManager?: ViewManager | null,
|
||||
): MenuItem | null {
|
||||
@@ -286,17 +283,21 @@ export class MenuButtonController {
|
||||
? {
|
||||
icon: 'mdi:album',
|
||||
...config.menu.buttons.recordings,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.recordings'),
|
||||
style: view.is('recordings') ? this._getEmphasizedStyle() : {},
|
||||
tap_action: createGeneralAction('recordings') as FrigateCardCustomAction,
|
||||
hold_action: createGeneralAction('recording') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction(
|
||||
'recordings',
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
hold_action: createGeneralAction(
|
||||
'recording',
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getImageButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
view?: View | null,
|
||||
viewManager?: ViewManager | null,
|
||||
): MenuItem | null {
|
||||
@@ -304,16 +305,16 @@ export class MenuButtonController {
|
||||
? {
|
||||
icon: 'mdi:image',
|
||||
...config.menu.buttons.image,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.image'),
|
||||
style: view?.is('image') ? this._getEmphasizedStyle() : {},
|
||||
tap_action: createGeneralAction('image') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('image') as AdvancedCameraCardCustomAction,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getTimelineButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
view?: View | null,
|
||||
viewManager?: ViewManager | null,
|
||||
): MenuItem | null {
|
||||
@@ -321,16 +322,16 @@ export class MenuButtonController {
|
||||
? {
|
||||
icon: 'mdi:chart-gantt',
|
||||
...config.menu.buttons.timeline,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.timeline'),
|
||||
style: view.is('timeline') ? this._getEmphasizedStyle() : {},
|
||||
tap_action: createGeneralAction('timeline') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('timeline') as AdvancedCameraCardCustomAction,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getDownloadButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
@@ -342,31 +343,31 @@ export class MenuButtonController {
|
||||
return {
|
||||
icon: 'mdi:download',
|
||||
...config.menu.buttons.download,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.download'),
|
||||
tap_action: createGeneralAction('download') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('download') as AdvancedCameraCardCustomAction,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected _getCameraUIButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
showCameraUIButton?: boolean,
|
||||
): MenuItem | null {
|
||||
return showCameraUIButton
|
||||
? {
|
||||
icon: 'mdi:web',
|
||||
...config.menu.buttons.camera_ui,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.camera_ui'),
|
||||
tap_action: createGeneralAction('camera_ui') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('camera_ui') as AdvancedCameraCardCustomAction,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getMicrophoneButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
microphoneManager?: MicrophoneManager | null,
|
||||
currentMediaLoadedInfo?: MediaLoadedInfo | null,
|
||||
): MenuItem | null {
|
||||
@@ -382,23 +383,23 @@ export class MenuButtonController {
|
||||
? 'mdi:microphone-off'
|
||||
: 'mdi:microphone',
|
||||
...config.menu.buttons.microphone,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.microphone'),
|
||||
style: unavailable || muted ? {} : this._getEmphasizedStyle(true),
|
||||
...(!unavailable &&
|
||||
buttonType === 'momentary' && {
|
||||
start_tap_action: createGeneralAction(
|
||||
'microphone_unmute',
|
||||
) as FrigateCardCustomAction,
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
end_tap_action: createGeneralAction(
|
||||
'microphone_mute',
|
||||
) as FrigateCardCustomAction,
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
}),
|
||||
...(!unavailable &&
|
||||
buttonType === 'toggle' && {
|
||||
tap_action: createGeneralAction(
|
||||
muted ? 'microphone_unmute' : 'microphone_mute',
|
||||
) as FrigateCardCustomAction,
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -406,21 +407,21 @@ export class MenuButtonController {
|
||||
}
|
||||
|
||||
protected _getExpandButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
inExpandedMode?: boolean,
|
||||
): MenuItem {
|
||||
return {
|
||||
icon: inExpandedMode ? 'mdi:arrow-collapse-all' : 'mdi:arrow-expand-all',
|
||||
...config.menu.buttons.expand,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.expand'),
|
||||
tap_action: createGeneralAction('expand') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('expand') as AdvancedCameraCardCustomAction,
|
||||
style: inExpandedMode ? this._getEmphasizedStyle() : {},
|
||||
};
|
||||
}
|
||||
|
||||
protected _getFullscreenButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
fullscreenManager?: FullscreenManager | null,
|
||||
): MenuItem | null {
|
||||
const inFullscreen = fullscreenManager?.isInFullscreen();
|
||||
@@ -428,9 +429,11 @@ export class MenuButtonController {
|
||||
? {
|
||||
icon: inFullscreen ? 'mdi:fullscreen-exit' : 'mdi:fullscreen',
|
||||
...config.menu.buttons.fullscreen,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.fullscreen'),
|
||||
tap_action: createGeneralAction('fullscreen') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction(
|
||||
'fullscreen',
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
style: inFullscreen ? this._getEmphasizedStyle() : {},
|
||||
}
|
||||
: null;
|
||||
@@ -438,7 +441,7 @@ export class MenuButtonController {
|
||||
|
||||
protected _getCastButton(
|
||||
hass: HomeAssistant,
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
view?: View | null,
|
||||
mediaPlayerController?: MediaPlayerManager | null,
|
||||
@@ -475,7 +478,7 @@ export class MenuButtonController {
|
||||
return {
|
||||
icon: 'mdi:cast',
|
||||
...config.menu.buttons.media_player,
|
||||
type: 'custom:frigate-card-menu-submenu',
|
||||
type: 'custom:advanced-camera-card-menu-submenu',
|
||||
title: localize('config.menu.buttons.media_player'),
|
||||
items: mediaPlayerItems,
|
||||
};
|
||||
@@ -484,7 +487,7 @@ export class MenuButtonController {
|
||||
}
|
||||
|
||||
protected _getPlayPauseButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
currentMediaLoadedInfo?: MediaLoadedInfo | null,
|
||||
): MenuItem | null {
|
||||
if (
|
||||
@@ -496,18 +499,18 @@ export class MenuButtonController {
|
||||
return {
|
||||
icon: paused ? 'mdi:play' : 'mdi:pause',
|
||||
...config.menu.buttons.play,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.play'),
|
||||
tap_action: createGeneralAction(
|
||||
paused ? 'play' : 'pause',
|
||||
) as FrigateCardCustomAction,
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected _getMuteUnmuteButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
currentMediaLoadedInfo?: MediaLoadedInfo | null,
|
||||
): MenuItem | null {
|
||||
if (
|
||||
@@ -519,34 +522,34 @@ export class MenuButtonController {
|
||||
return {
|
||||
icon: muted ? 'mdi:volume-off' : 'mdi:volume-high',
|
||||
...config.menu.buttons.mute,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.mute'),
|
||||
tap_action: createGeneralAction(
|
||||
muted ? 'unmute' : 'mute',
|
||||
) as FrigateCardCustomAction,
|
||||
) as AdvancedCameraCardCustomAction,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected _getScreenshotButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
currentMediaLoadedInfo?: MediaLoadedInfo | null,
|
||||
): MenuItem | null {
|
||||
if (currentMediaLoadedInfo && currentMediaLoadedInfo.player) {
|
||||
return {
|
||||
icon: 'mdi:monitor-screenshot',
|
||||
...config.menu.buttons.screenshot,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.screenshot'),
|
||||
tap_action: createGeneralAction('screenshot') as FrigateCardCustomAction,
|
||||
tap_action: createGeneralAction('screenshot') as AdvancedCameraCardCustomAction,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected _getDisplayModeButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
@@ -563,7 +566,7 @@ export class MenuButtonController {
|
||||
icon: isGrid ? 'mdi:grid-off' : 'mdi:grid',
|
||||
...config.menu.buttons.display_mode,
|
||||
style: isGrid ? this._getEmphasizedStyle() : {},
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: isGrid
|
||||
? localize('display_modes.single')
|
||||
: localize('display_modes.grid'),
|
||||
@@ -574,7 +577,7 @@ export class MenuButtonController {
|
||||
}
|
||||
|
||||
protected _getPTZControlsButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
@@ -602,7 +605,7 @@ export class MenuButtonController {
|
||||
icon: 'mdi:pan',
|
||||
...config.menu.buttons.ptz_controls,
|
||||
style: isOn ? this._getEmphasizedStyle() : {},
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.ptz_controls'),
|
||||
tap_action: createPTZControlsAction(!isOn),
|
||||
};
|
||||
@@ -611,7 +614,7 @@ export class MenuButtonController {
|
||||
}
|
||||
|
||||
protected _getPTZHomeButton(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
@@ -633,11 +636,11 @@ export class MenuButtonController {
|
||||
return {
|
||||
icon: 'mdi:home',
|
||||
...config.menu.buttons.ptz_home,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.ptz_home'),
|
||||
tap_action: createPTZMultiAction({
|
||||
targetID: target.targetID,
|
||||
}) as FrigateCardCustomAction,
|
||||
}) as AdvancedCameraCardCustomAction,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -649,11 +652,11 @@ export class MenuButtonController {
|
||||
if (critical) {
|
||||
return {
|
||||
animation: 'pulse 3s infinite',
|
||||
color: 'var(--frigate-card-menu-button-critical-color)',
|
||||
color: 'var(--advanced-camera-card-menu-button-critical-color)',
|
||||
};
|
||||
}
|
||||
return {
|
||||
color: 'var(--frigate-card-menu-button-active-color)',
|
||||
color: 'var(--advanced-camera-card-menu-button-active-color)',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -664,7 +667,7 @@ export class MenuButtonController {
|
||||
* @returns A StyleInfo object.
|
||||
*/
|
||||
protected _getStyleFromActions(
|
||||
config: FrigateCardConfig,
|
||||
config: AdvancedCameraCardConfig,
|
||||
button: MenuItem,
|
||||
options?: MenuButtonControllerOptions,
|
||||
): StyleInfo {
|
||||
@@ -677,28 +680,28 @@ export class MenuButtonController {
|
||||
]) {
|
||||
const actions = Array.isArray(actionSet) ? actionSet : [actionSet];
|
||||
for (const action of actions) {
|
||||
// All frigate card actions will have action of 'fire-dom-event' and
|
||||
// All advanced camera card actions will have action of 'fire-dom-event' and
|
||||
// styling only applies to those.
|
||||
if (
|
||||
!action ||
|
||||
action.action !== 'fire-dom-event' ||
|
||||
!('frigate_card_action' in action)
|
||||
!('advanced_camera_card_action' in action)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const frigateCardAction = action as FrigateCardCustomAction;
|
||||
const customCardAction = action as AdvancedCameraCardCustomAction;
|
||||
if (
|
||||
FRIGATE_CARD_VIEWS_USER_SPECIFIED.some(
|
||||
VIEWS_USER_SPECIFIED.some(
|
||||
(viewName) =>
|
||||
viewName === frigateCardAction.frigate_card_action &&
|
||||
options?.view?.is(frigateCardAction.frigate_card_action),
|
||||
viewName === customCardAction.advanced_camera_card_action &&
|
||||
options?.view?.is(customCardAction.advanced_camera_card_action),
|
||||
) ||
|
||||
(frigateCardAction.frigate_card_action === 'default' &&
|
||||
(customCardAction.advanced_camera_card_action === 'default' &&
|
||||
options?.view?.is(config.view.default)) ||
|
||||
(frigateCardAction.frigate_card_action === 'fullscreen' &&
|
||||
(customCardAction.advanced_camera_card_action === 'fullscreen' &&
|
||||
!!options?.fullscreenManager?.isInFullscreen()) ||
|
||||
(frigateCardAction.frigate_card_action === 'camera_select' &&
|
||||
options?.view?.camera === frigateCardAction.camera)
|
||||
(customCardAction.advanced_camera_card_action === 'camera_select' &&
|
||||
options?.view?.camera === customCardAction.camera)
|
||||
) {
|
||||
return this._getEmphasizedStyle();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { LitElement } from 'lit';
|
||||
import { orderBy } from 'lodash-es';
|
||||
import { dispatchActionExecutionRequest } from '../card-controller/actions/utils/execution-request.js';
|
||||
import {
|
||||
FRIGATE_MENU_PRIORITY_MAX,
|
||||
MENU_PRIORITY_MAX,
|
||||
type ActionType,
|
||||
type ActionsConfig,
|
||||
type MenuConfig,
|
||||
@@ -28,7 +28,7 @@ export class MenuController {
|
||||
public setMenuConfig(config: MenuConfig): void {
|
||||
this._config = config;
|
||||
this._host.style.setProperty(
|
||||
'--frigate-card-menu-button-size',
|
||||
'--advanced-camera-card-menu-button-size',
|
||||
`${config.button_size}px`,
|
||||
);
|
||||
|
||||
@@ -164,8 +164,7 @@ export class MenuController {
|
||||
// If the menu is hidden, the buttons that toggle the menu must come
|
||||
// first.
|
||||
return (
|
||||
priority +
|
||||
(this._isHidingMenu() && button.permanent ? FRIGATE_MENU_PRIORITY_MAX : 0)
|
||||
priority + (this._isHidingMenu() && button.permanent ? MENU_PRIORITY_MAX : 0)
|
||||
);
|
||||
},
|
||||
['desc'],
|
||||
@@ -178,6 +177,6 @@ export class MenuController {
|
||||
|
||||
protected _isUnknownActionMenuToggleAction(action: ActionType): boolean {
|
||||
const parsedAction = convertActionToCardCustomAction(action);
|
||||
return !!parsedAction && parsedAction.frigate_card_action == 'menu_toggle';
|
||||
return !!parsedAction && parsedAction.advanced_camera_card_action == 'menu_toggle';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { FrigateCardError, Message } from '../../types';
|
||||
import { dispatchFrigateCardEvent } from '../../utils/basic';
|
||||
import { AdvancedCameraCardError, Message } from '../../types';
|
||||
import { dispatchAdvancedCameraCardEvent } from '../../utils/basic';
|
||||
|
||||
// Facilitates correct typing of event handlers.
|
||||
export interface FrigateCardMessageEventTarget extends EventTarget {
|
||||
export interface AdvancedCameraCardMessageEventTarget extends EventTarget {
|
||||
addEventListener(
|
||||
event: 'frigate-card:message',
|
||||
listener: (this: FrigateCardMessageEventTarget, ev: CustomEvent<Message>) => void,
|
||||
event: 'advanced-camera-card:message',
|
||||
listener: (
|
||||
this: AdvancedCameraCardMessageEventTarget,
|
||||
ev: CustomEvent<Message>,
|
||||
) => void,
|
||||
options?: AddEventListenerOptions | boolean,
|
||||
): void;
|
||||
addEventListener(
|
||||
@@ -14,8 +17,11 @@ export interface FrigateCardMessageEventTarget extends EventTarget {
|
||||
options?: AddEventListenerOptions | boolean,
|
||||
): void;
|
||||
removeEventListener(
|
||||
event: 'frigate-card:message',
|
||||
listener: (this: FrigateCardMessageEventTarget, ev: CustomEvent<Message>) => void,
|
||||
event: 'advanced-camera-card:message',
|
||||
listener: (
|
||||
this: AdvancedCameraCardMessageEventTarget,
|
||||
ev: CustomEvent<Message>,
|
||||
) => void,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
removeEventListener(
|
||||
@@ -33,15 +39,15 @@ export interface FrigateCardMessageEventTarget extends EventTarget {
|
||||
* @param element The element to send the event.
|
||||
* @param message The message to show.
|
||||
*/
|
||||
export const dispatchFrigateCardErrorEvent = (
|
||||
export const dispatchAdvancedCameraCardErrorEvent = (
|
||||
element: EventTarget,
|
||||
error: unknown,
|
||||
): void => {
|
||||
if (error instanceof Error) {
|
||||
dispatchFrigateCardEvent<Message>(element, 'message', {
|
||||
dispatchAdvancedCameraCardEvent<Message>(element, 'message', {
|
||||
message: error.message,
|
||||
type: 'error',
|
||||
...(error instanceof FrigateCardError && { context: error.context }),
|
||||
...(error instanceof AdvancedCameraCardError && { context: error.context }),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ import orderBy from 'lodash-es/orderBy';
|
||||
import { dispatchActionExecutionRequest } from '../card-controller/actions/utils/execution-request';
|
||||
import {
|
||||
ActionsConfig,
|
||||
FRIGATE_STATUS_BAR_PRIORITY_DEFAULT,
|
||||
STATUS_BAR_PRIORITY_DEFAULT,
|
||||
StatusBarConfig,
|
||||
StatusBarItem,
|
||||
} from '../config/types';
|
||||
@@ -33,7 +33,7 @@ export class StatusBarController {
|
||||
|
||||
const newItems = orderBy(
|
||||
exclusiveItems.length ? exclusiveItems : items,
|
||||
(item) => item.priority ?? FRIGATE_STATUS_BAR_PRIORITY_DEFAULT,
|
||||
(item) => item.priority ?? STATUS_BAR_PRIORITY_DEFAULT,
|
||||
'desc',
|
||||
);
|
||||
|
||||
@@ -53,7 +53,7 @@ export class StatusBarController {
|
||||
public setConfig(config: StatusBarConfig): void {
|
||||
this._config = config;
|
||||
this._host.style.setProperty(
|
||||
'--frigate-card-status-bar-height',
|
||||
'--advanced-camera-card-status-bar-height',
|
||||
`${config.height}px`,
|
||||
);
|
||||
|
||||
@@ -97,11 +97,11 @@ export class StatusBarController {
|
||||
|
||||
protected _getSufficientValue(item: StatusBarItem): string | null {
|
||||
/* istanbul ignore else: cannot happen -- @preserve */
|
||||
if (item.type === 'custom:frigate-card-status-bar-icon') {
|
||||
if (item.type === 'custom:advanced-camera-card-status-bar-icon') {
|
||||
return item.icon;
|
||||
} else if (item.type === 'custom:frigate-card-status-bar-string') {
|
||||
} else if (item.type === 'custom:advanced-camera-card-status-bar-string') {
|
||||
return item.string;
|
||||
} else if (item.type === 'custom:frigate-card-status-bar-image') {
|
||||
} else if (item.type === 'custom:advanced-camera-card-status-bar-image') {
|
||||
return item.image;
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@@ -24,7 +24,7 @@ const TIMELINE_FRESHNESS_TOLERANCE_SECONDS = 30;
|
||||
// instead of clean recording blocks.
|
||||
const TIMELINE_RECORDING_SEGMENT_CONSECUTIVE_TOLERANCE_SECONDS = 60;
|
||||
|
||||
export interface FrigateCardTimelineItem extends TimelineItem {
|
||||
export interface AdvancedCameraCardTimelineItem extends TimelineItem {
|
||||
// Use numbers to avoid significant volumes of Date object construction (for
|
||||
// high-quantity recording segments).
|
||||
start: number;
|
||||
@@ -38,7 +38,7 @@ export interface FrigateCardTimelineItem extends TimelineItem {
|
||||
|
||||
export class TimelineDataSource {
|
||||
protected _cameraManager: CameraManager;
|
||||
protected _dataset: DataSet<FrigateCardTimelineItem> = new DataSet();
|
||||
protected _dataset: DataSet<AdvancedCameraCardTimelineItem> = new DataSet();
|
||||
|
||||
// The ranges in which recordings have been calculated and added for.
|
||||
// Calculating recordings is a very expensive process since it is based on
|
||||
@@ -66,7 +66,7 @@ export class TimelineDataSource {
|
||||
this._showRecordings = showRecordings;
|
||||
}
|
||||
|
||||
get dataset(): DataSet<FrigateCardTimelineItem> {
|
||||
get dataset(): DataSet<AdvancedCameraCardTimelineItem> {
|
||||
return this._dataset;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ export class TimelineDataSource {
|
||||
}
|
||||
|
||||
const mediaArray = await this._cameraManager.executeMediaQueries(eventQueries);
|
||||
const data: FrigateCardTimelineItem[] = [];
|
||||
const data: AdvancedCameraCardTimelineItem[] = [];
|
||||
for (const media of mediaArray ?? []) {
|
||||
const startTime = media.getStartTime();
|
||||
const id = media.getID();
|
||||
@@ -160,15 +160,15 @@ export class TimelineDataSource {
|
||||
}
|
||||
|
||||
protected async _refreshRecordings(window: TimelineWindow): Promise<void> {
|
||||
type FrigateCardTimelineItemWithEnd = ModifyInterface<
|
||||
FrigateCardTimelineItem,
|
||||
type AdvancedCameraCardTimelineItemWithEnd = ModifyInterface<
|
||||
AdvancedCameraCardTimelineItem,
|
||||
{ end: number }
|
||||
>;
|
||||
|
||||
const convertSegmentToRecording = (
|
||||
cameraID: string,
|
||||
segment: RecordingSegment,
|
||||
): FrigateCardTimelineItemWithEnd => {
|
||||
): AdvancedCameraCardTimelineItemWithEnd => {
|
||||
return {
|
||||
id: `recording-${cameraID}-${segment.id}`,
|
||||
group: cameraID,
|
||||
@@ -181,11 +181,11 @@ export class TimelineDataSource {
|
||||
|
||||
const getExistingRecordingsForCameraID = (
|
||||
cameraID: string,
|
||||
): FrigateCardTimelineItemWithEnd[] => {
|
||||
): AdvancedCameraCardTimelineItemWithEnd[] => {
|
||||
return this._dataset.get({
|
||||
filter: (item) =>
|
||||
item.type == 'background' && item.group === cameraID && item.end !== undefined,
|
||||
}) as FrigateCardTimelineItemWithEnd[];
|
||||
}) as AdvancedCameraCardTimelineItemWithEnd[];
|
||||
};
|
||||
|
||||
const deleteRecordingsForCameraID = (cameraID: string): void => {
|
||||
@@ -196,7 +196,9 @@ export class TimelineDataSource {
|
||||
);
|
||||
};
|
||||
|
||||
const addRecordings = (recordings: FrigateCardTimelineItemWithEnd[]): void => {
|
||||
const addRecordings = (
|
||||
recordings: AdvancedCameraCardTimelineItemWithEnd[],
|
||||
): void => {
|
||||
this._dataset.add(recordings);
|
||||
};
|
||||
|
||||
@@ -247,7 +249,7 @@ export class TimelineDataSource {
|
||||
const compressedRecordings = compressRanges(
|
||||
mergedRecordings,
|
||||
TIMELINE_RECORDING_SEGMENT_CONSECUTIVE_TOLERANCE_SECONDS,
|
||||
) as FrigateCardTimelineItemWithEnd[];
|
||||
) as AdvancedCameraCardTimelineItemWithEnd[];
|
||||
|
||||
deleteRecordingsForCameraID(cameraID);
|
||||
addRecordings(compressedRecordings);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import Panzoom, { PanzoomEventDetail, PanzoomObject } from '@dermotduffy/panzoom';
|
||||
import throttle from 'lodash-es/throttle';
|
||||
import round from 'lodash-es/round';
|
||||
import throttle from 'lodash-es/throttle';
|
||||
import {
|
||||
arefloatsApproximatelyEqual,
|
||||
dispatchFrigateCardEvent,
|
||||
dispatchAdvancedCameraCardEvent,
|
||||
isHoverableDevice,
|
||||
} from '../../utils/basic';
|
||||
import {
|
||||
@@ -76,7 +76,7 @@ export class ZoomController {
|
||||
// Even though the click is stopped,the card still needs to gain focus so
|
||||
// that keyboard shortcuts will work immediately after the card is clicked
|
||||
// upon.
|
||||
dispatchFrigateCardEvent(this._element, 'focus');
|
||||
dispatchAdvancedCameraCardEvent(this._element, 'focus');
|
||||
}
|
||||
this._allowClick = true;
|
||||
};
|
||||
@@ -133,7 +133,7 @@ export class ZoomController {
|
||||
|
||||
// Disable automatic touchAction setting from Panzoom() as otherwise it
|
||||
// effectively disables dashboard scrolling. See:
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/1181
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/1181
|
||||
touchAction: '',
|
||||
|
||||
// Set the initial pan/zoom values to avoid an initial unzoomed view.
|
||||
@@ -211,11 +211,11 @@ export class ZoomController {
|
||||
if (unzoomed && this._zoomed) {
|
||||
this._zoomed = false;
|
||||
this._setTouchAction(true);
|
||||
dispatchFrigateCardEvent(this._element, 'zoom:unzoomed');
|
||||
dispatchAdvancedCameraCardEvent(this._element, 'zoom:unzoomed');
|
||||
} else if (!unzoomed && !this._zoomed) {
|
||||
this._zoomed = true;
|
||||
this._setTouchAction(false);
|
||||
dispatchFrigateCardEvent(this._element, 'zoom:zoomed');
|
||||
dispatchAdvancedCameraCardEvent(this._element, 'zoom:zoomed');
|
||||
}
|
||||
|
||||
const converted = this._convertXYPanToPercent(pz.x, pz.y, pz.scale);
|
||||
@@ -229,7 +229,7 @@ export class ZoomController {
|
||||
unzoomed: unzoomed,
|
||||
};
|
||||
|
||||
dispatchFrigateCardEvent(this._element, 'zoom:change', observed);
|
||||
dispatchAdvancedCameraCardEvent(this._element, 'zoom:change', observed);
|
||||
}
|
||||
|
||||
protected _isZoomEqual(a: PartialZoomSettings, b: PartialZoomSettings): boolean {
|
||||
@@ -319,7 +319,7 @@ export class ZoomController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from Frigate card pan % values to Panzoom X/Y transformation
|
||||
* Convert from Advanced Camera Card pan % values to Panzoom X/Y transformation
|
||||
* coordinates.
|
||||
* @param x The x translation value.
|
||||
* @param y The y translation value.
|
||||
@@ -439,7 +439,7 @@ export class ZoomController {
|
||||
return (
|
||||
!this._isUnzoomed(this._panzoom?.getScale()) ||
|
||||
// TouchEvent does not exist on Firefox on non-touch events. See:
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/1174
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/1174
|
||||
(window.TouchEvent && ev instanceof TouchEvent && ev.touches.length > 1) ||
|
||||
(ev instanceof WheelEvent && ev.ctrlKey)
|
||||
);
|
||||
|
||||
@@ -22,8 +22,8 @@ export type EmblaCarouselPlugins = CreatePluginType<
|
||||
Record<string, unknown>
|
||||
>[];
|
||||
|
||||
@customElement('frigate-card-carousel')
|
||||
export class FrigateCardCarousel extends LitElement {
|
||||
@customElement('advanced-camera-card-carousel')
|
||||
export class AdvancedCameraCardCarousel extends LitElement {
|
||||
@property({ attribute: true, reflect: true })
|
||||
public direction: CarouselDirection = 'horizontal';
|
||||
|
||||
@@ -124,6 +124,6 @@ export class FrigateCardCarousel extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-carousel': FrigateCardCarousel;
|
||||
'advanced-camera-card-carousel': AdvancedCameraCardCarousel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ import { createRef, ref, Ref } from 'lit/directives/ref.js';
|
||||
import { localize } from '../localize/localize';
|
||||
import datePickerStyle from '../scss/date-picker.scss';
|
||||
import { stopEventFromActivatingCardWideActions } from '../utils/action';
|
||||
import { dispatchFrigateCardEvent } from '../utils/basic';
|
||||
import { dispatchAdvancedCameraCardEvent } from '../utils/basic';
|
||||
import './icon';
|
||||
|
||||
export interface DatePickerEvent {
|
||||
date: Date | null;
|
||||
}
|
||||
|
||||
@customElement('frigate-card-date-picker')
|
||||
export class FrigateCardDatePicker extends LitElement {
|
||||
@customElement('advanced-camera-card-date-picker')
|
||||
export class AdvancedCameraCardDatePicker extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public icon?: string;
|
||||
|
||||
@@ -32,7 +32,7 @@ export class FrigateCardDatePicker extends LitElement {
|
||||
const changed = () => {
|
||||
const value = this._refInput.value?.value;
|
||||
|
||||
dispatchFrigateCardEvent<DatePickerEvent>(this, 'date-picker:change', {
|
||||
dispatchAdvancedCameraCardEvent<DatePickerEvent>(this, 'date-picker:change', {
|
||||
date: value ? new Date(value) : null,
|
||||
});
|
||||
};
|
||||
@@ -45,7 +45,7 @@ export class FrigateCardDatePicker extends LitElement {
|
||||
@input=${() => changed()}
|
||||
@change=${() => changed()}
|
||||
/>
|
||||
<frigate-card-icon
|
||||
<advanced-camera-card-icon
|
||||
aria-label="${localize('timeline.select_date')}"
|
||||
title="${localize('timeline.select_date')}"
|
||||
.icon=${{ icon: this.icon ?? `mdi:calendar-search` }}
|
||||
@@ -54,7 +54,7 @@ export class FrigateCardDatePicker extends LitElement {
|
||||
this._refInput.value?.showPicker();
|
||||
}}
|
||||
>
|
||||
</frigate-card-icon>`;
|
||||
</advanced-camera-card-icon>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
@@ -64,6 +64,6 @@ export class FrigateCardDatePicker extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-date-picker': FrigateCardDatePicker;
|
||||
'advanced-camera-card-date-picker': AdvancedCameraCardDatePicker;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
|
||||
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { until } from 'lit/directives/until.js';
|
||||
import { RawFrigateCardConfig } from '../config/types';
|
||||
import { RawAdvancedCameraCardConfig } from '../config/types';
|
||||
import { localize } from '../localize/localize';
|
||||
import basicBlockStyle from '../scss/basic-block.scss';
|
||||
import { getDiagnostics } from '../utils/diagnostics';
|
||||
import { DeviceRegistryManager } from '../utils/ha/registry/device';
|
||||
import { renderMessage } from './message';
|
||||
|
||||
@customElement('frigate-card-diagnostics')
|
||||
export class FrigateCardDiagnostics extends LitElement {
|
||||
@customElement('advanced-camera-card-diagnostics')
|
||||
export class AdvancedCameraCardDiagnostics extends LitElement {
|
||||
// Not a reactive property to avoid multiple diagnostics fetches.
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@@ -18,7 +18,7 @@ export class FrigateCardDiagnostics extends LitElement {
|
||||
public deviceRegistryManager?: DeviceRegistryManager;
|
||||
|
||||
@property({ attribute: false })
|
||||
public rawConfig?: RawFrigateCardConfig;
|
||||
public rawConfig?: RawAdvancedCameraCardConfig;
|
||||
|
||||
protected async _renderDiagnostics(): Promise<TemplateResult> {
|
||||
const diagnostics = await getDiagnostics(
|
||||
@@ -52,6 +52,6 @@ export class FrigateCardDiagnostics extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-diagnostics': FrigateCardDiagnostics;
|
||||
'advanced-camera-card-diagnostics': AdvancedCameraCardDiagnostics;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ export interface DrawerIcons {
|
||||
closed?: string;
|
||||
}
|
||||
|
||||
@customElement('frigate-card-drawer')
|
||||
export class FrigateCardDrawer extends LitElement {
|
||||
@customElement('advanced-camera-card-drawer')
|
||||
export class AdvancedCameraCardDrawer extends LitElement {
|
||||
@property({ attribute: true, reflect: true })
|
||||
public location: 'left' | 'right' = 'left';
|
||||
|
||||
@@ -122,7 +122,7 @@ export class FrigateCardDrawer extends LitElement {
|
||||
this.open = !this.open;
|
||||
}}
|
||||
>
|
||||
<frigate-card-icon
|
||||
<advanced-camera-card-icon
|
||||
class="control"
|
||||
.icon="${{
|
||||
icon: this.open
|
||||
@@ -133,13 +133,13 @@ export class FrigateCardDrawer extends LitElement {
|
||||
// Only open the drawer on mousenter when the device
|
||||
// supports hover (otherwise iOS may end up passing on
|
||||
// subsequent click events to a different element, see:
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/801
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/801
|
||||
if (this._isHoverableDevice && !this.open) {
|
||||
this.open = true;
|
||||
}
|
||||
}}
|
||||
>
|
||||
</frigate-card-icon>
|
||||
</advanced-camera-card-icon>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
@@ -155,7 +155,7 @@ export class FrigateCardDrawer extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-drawer': FrigateCardDrawer;
|
||||
'advanced-camera-card-drawer': AdvancedCameraCardDrawer;
|
||||
'side-drawer': SideDrawer;
|
||||
}
|
||||
}
|
||||
|
||||
+80
-66
@@ -12,9 +12,9 @@ import {
|
||||
ConditionsManagerEpoch,
|
||||
evaluateConditionViaEvent,
|
||||
} from '../card-controller/conditions-manager.js';
|
||||
import { dispatchFrigateCardErrorEvent } from '../components-lib/message/dispatch.js';
|
||||
import { dispatchAdvancedCameraCardErrorEvent } from '../components-lib/message/dispatch.js';
|
||||
import {
|
||||
FrigateConditional,
|
||||
AdvancedCameraCardConditional,
|
||||
MenuIcon,
|
||||
MenuItem,
|
||||
MenuStateIcon,
|
||||
@@ -28,8 +28,8 @@ import {
|
||||
} from '../config/types.js';
|
||||
import { localize } from '../localize/localize.js';
|
||||
import elementsStyle from '../scss/elements.scss';
|
||||
import { FrigateCardError } from '../types.js';
|
||||
import { dispatchFrigateCardEvent, errorToConsole } from '../utils/basic.js';
|
||||
import { AdvancedCameraCardError } from '../types.js';
|
||||
import { dispatchAdvancedCameraCardEvent, errorToConsole } from '../utils/basic.js';
|
||||
|
||||
/* A note on picture element rendering:
|
||||
*
|
||||
@@ -52,7 +52,7 @@ import { dispatchFrigateCardEvent, errorToConsole } from '../utils/basic.js';
|
||||
* correctly. These custom elements 'render' by firing events that are caught by
|
||||
* the card to call for inclusion/exclusion of the menu icon in question.
|
||||
*
|
||||
* One major complexity here is that the top <frigate-card-elements> element
|
||||
* One major complexity here is that the top <advanced-camera-card-elements> element
|
||||
* will not necessarily know when a menu icon is no longer rendered because of a
|
||||
* conditional that no-longer evaluates to true. As such, it cannot know when to
|
||||
* signal for the menu icon removal. Furthermore, the menu icon element itself
|
||||
@@ -60,7 +60,7 @@ import { dispatchFrigateCardEvent, errorToConsole } from '../utils/basic.js';
|
||||
* so normal event propagation at that point will not work. Instead, we must
|
||||
* catch the menu icon _addition_ and register the eventhandler for the removal
|
||||
* directly on the child (which will have no parent at time of calling). That
|
||||
* then triggers <frigate-card-elements> to re-dispatch a removal event for
|
||||
* then triggers <advanced-camera-card-elements> to re-dispatch a removal event for
|
||||
* upper layers to handle correctly.
|
||||
*/
|
||||
|
||||
@@ -71,8 +71,8 @@ interface HuiConditionalElement extends HTMLElement {
|
||||
|
||||
// A small wrapper around a HA conditional element used to render a set of
|
||||
// picture elements.
|
||||
@customElement('frigate-card-elements-core')
|
||||
export class FrigateCardElementsCore extends LitElement {
|
||||
@customElement('advanced-camera-card-elements-core')
|
||||
export class AdvancedCameraCardElementsCore extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public elements?: PictureElements;
|
||||
|
||||
@@ -116,7 +116,7 @@ export class FrigateCardElementsCore extends LitElement {
|
||||
element.setConfig(config);
|
||||
} catch (e) {
|
||||
errorToConsole(e as Error, console.error);
|
||||
throw new FrigateCardError(localize('error.invalid_elements_config'));
|
||||
throw new AdvancedCameraCardError(localize('error.invalid_elements_config'));
|
||||
}
|
||||
return element;
|
||||
}
|
||||
@@ -133,7 +133,7 @@ export class FrigateCardElementsCore extends LitElement {
|
||||
this._root = this._createRoot();
|
||||
}
|
||||
} catch (e) {
|
||||
return dispatchFrigateCardErrorEvent(this, e as FrigateCardError);
|
||||
return dispatchAdvancedCameraCardErrorEvent(this, e as AdvancedCameraCardError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,17 +148,17 @@ export class FrigateCardElementsCore extends LitElement {
|
||||
protected updated(): void {
|
||||
if (this.hass && this._root) {
|
||||
// Always update hass. It is used as a trigger to re-evaluate conditions
|
||||
// down the chain, see the note on FrigateCardElementsConditional.
|
||||
// down the chain, see the note on AdvancedCameraCardElementsConditional.
|
||||
this._root.hass = this.hass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The master <frigate-card-elements> class, handles event listeners and styles.
|
||||
* The master <advanced-camera-card-elements> class, handles event listeners and styles.
|
||||
*/
|
||||
@customElement('frigate-card-elements')
|
||||
export class FrigateCardElements extends LitElement {
|
||||
@customElement('advanced-camera-card-elements')
|
||||
export class AdvancedCameraCardElements extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@@ -181,13 +181,17 @@ export class FrigateCardElements extends LitElement {
|
||||
protected _menuRemoveHandler = (ev: Event): void => {
|
||||
// Re-dispatch event from this element (instead of the disconnected one, as
|
||||
// there is no parent of the disconnected element).
|
||||
dispatchFrigateCardEvent<MenuItem>(this, 'menu:remove', (ev as CustomEvent).detail);
|
||||
dispatchAdvancedCameraCardEvent<MenuItem>(
|
||||
this,
|
||||
'menu:remove',
|
||||
(ev as CustomEvent).detail,
|
||||
);
|
||||
};
|
||||
|
||||
protected _statusBarRemoveHandler = (ev: Event): void => {
|
||||
// Re-dispatch event from this element (instead of the disconnected one, as
|
||||
// there is no parent of the disconnected element).
|
||||
dispatchFrigateCardEvent<StatusBarItem>(
|
||||
dispatchAdvancedCameraCardEvent<StatusBarItem>(
|
||||
this,
|
||||
'status-bar:remove',
|
||||
(ev as CustomEvent).detail,
|
||||
@@ -200,7 +204,11 @@ export class FrigateCardElements extends LitElement {
|
||||
if (!path.length) {
|
||||
return;
|
||||
}
|
||||
this._addHandler(path[0], 'frigate-card:menu:remove', this._menuRemoveHandler);
|
||||
this._addHandler(
|
||||
path[0],
|
||||
'advanced-camera-card:menu:remove',
|
||||
this._menuRemoveHandler,
|
||||
);
|
||||
};
|
||||
|
||||
protected _statusBarAddHandler = (ev: Event): void => {
|
||||
@@ -211,7 +219,7 @@ export class FrigateCardElements extends LitElement {
|
||||
}
|
||||
this._addHandler(
|
||||
path[0],
|
||||
'frigate-card:status-bar:add',
|
||||
'advanced-camera-card:status-bar:add',
|
||||
this._statusBarRemoveHandler,
|
||||
);
|
||||
};
|
||||
@@ -221,23 +229,29 @@ export class FrigateCardElements extends LitElement {
|
||||
|
||||
// Catch icons being added to the menu or status-bar (so their removal can
|
||||
// be subsequently handled).
|
||||
this.addEventListener('frigate-card:menu:add', this._menuAddHandler);
|
||||
this.addEventListener('frigate-card:status-bar:add', this._statusBarAddHandler);
|
||||
this.addEventListener('advanced-camera-card:menu:add', this._menuAddHandler);
|
||||
this.addEventListener(
|
||||
'advanced-camera-card:status-bar:add',
|
||||
this._statusBarAddHandler,
|
||||
);
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
this.removeEventListener('frigate-card:menu:add', this._menuAddHandler);
|
||||
this.addEventListener('frigate-card:status-bar:add', this._statusBarAddHandler);
|
||||
this.removeEventListener('advanced-camera-card:menu:add', this._menuAddHandler);
|
||||
this.addEventListener(
|
||||
'advanced-camera-card:status-bar:add',
|
||||
this._statusBarAddHandler,
|
||||
);
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`<frigate-card-elements-core
|
||||
return html`<advanced-camera-card-elements-core
|
||||
.hass=${this.hass}
|
||||
.conditionsManagerEpoch=${this.conditionsManagerEpoch}
|
||||
.elements=${this.elements}
|
||||
>
|
||||
</frigate-card-elements-core>`;
|
||||
</advanced-camera-card-elements-core>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
@@ -246,19 +260,19 @@ export class FrigateCardElements extends LitElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* An element that can render others based on Frigate state (e.g. only show
|
||||
* overlays in particular views). This is the Frigate Card equivalent to the HA
|
||||
* conditional card.
|
||||
* An element that can render others based on card state (e.g. only show
|
||||
* overlays in particular views). This is the Advanced Camera Card equivalent to
|
||||
* the HA conditional card.
|
||||
*/
|
||||
@customElement('frigate-card-conditional')
|
||||
export class FrigateCardElementsConditional extends LitElement {
|
||||
protected _config?: FrigateConditional;
|
||||
@customElement('advanced-camera-card-conditional')
|
||||
export class AdvancedCameraCardElementsConditional extends LitElement {
|
||||
protected _config?: AdvancedCameraCardConditional;
|
||||
|
||||
// A note on hass as an update mechanism:
|
||||
//
|
||||
// Every set of hass is treated as a reason to re-evaluate. Given that this
|
||||
// node may be buried down the DOM (as a descendent of non-Frigate card
|
||||
// elements), the hass object is used as the (only) trigger for condition
|
||||
// node may be buried down the DOM (as a descendent of non-Advanced Camera
|
||||
// Card elements), the hass object is used as the (only) trigger for condition
|
||||
// re-fetch even if hass itself has not changed.
|
||||
@property({ attribute: false, hasChanged: () => true })
|
||||
public hass?: HomeAssistant;
|
||||
@@ -267,7 +281,7 @@ export class FrigateCardElementsConditional extends LitElement {
|
||||
* Set the card configuration.
|
||||
* @param config The card configuration.
|
||||
*/
|
||||
public setConfig(config: FrigateConditional): void {
|
||||
public setConfig(config: AdvancedCameraCardConditional): void {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
@@ -296,17 +310,17 @@ export class FrigateCardElementsConditional extends LitElement {
|
||||
*/
|
||||
protected render(): TemplateResult | void {
|
||||
if (evaluateConditionViaEvent(this, this._config?.conditions)) {
|
||||
return html` <frigate-card-elements-core
|
||||
return html` <advanced-camera-card-elements-core
|
||||
.hass=${this.hass}
|
||||
.elements=${this._config?.elements}
|
||||
>
|
||||
</frigate-card-elements-core>`;
|
||||
</advanced-camera-card-elements-core>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A base class for rendering menu icons / menu state icons.
|
||||
export class FrigateCardElementsBaseItem<ConfigType> extends LitElement {
|
||||
export class AdvancedCameraCardElementsBaseItem<ConfigType> extends LitElement {
|
||||
protected _eventCategory: string;
|
||||
|
||||
constructor(eventCategory: string) {
|
||||
@@ -324,7 +338,7 @@ export class FrigateCardElementsBaseItem<ConfigType> extends LitElement {
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
if (this._config) {
|
||||
dispatchFrigateCardEvent<ConfigType>(
|
||||
dispatchAdvancedCameraCardEvent<ConfigType>(
|
||||
this,
|
||||
`${this._eventCategory}:add`,
|
||||
this._config,
|
||||
@@ -334,7 +348,7 @@ export class FrigateCardElementsBaseItem<ConfigType> extends LitElement {
|
||||
|
||||
disconnectedCallback(): void {
|
||||
if (this._config) {
|
||||
dispatchFrigateCardEvent<ConfigType>(
|
||||
dispatchAdvancedCameraCardEvent<ConfigType>(
|
||||
this,
|
||||
`${this._eventCategory}:remove`,
|
||||
this._config,
|
||||
@@ -344,56 +358,56 @@ export class FrigateCardElementsBaseItem<ConfigType> extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
export class FrigateCardElementsBaseMenuItem<
|
||||
export class AdvancedCameraCardElementsBaseMenuItem<
|
||||
ConfigType,
|
||||
> extends FrigateCardElementsBaseItem<ConfigType> {
|
||||
> extends AdvancedCameraCardElementsBaseItem<ConfigType> {
|
||||
constructor() {
|
||||
super('menu');
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('frigate-card-menu-icon')
|
||||
export class FrigateCardElementsMenuIcon extends FrigateCardElementsBaseMenuItem<MenuIcon> {}
|
||||
@customElement('advanced-camera-card-menu-icon')
|
||||
export class AdvancedCameraCardElementsMenuIcon extends AdvancedCameraCardElementsBaseMenuItem<MenuIcon> {}
|
||||
|
||||
@customElement('frigate-card-menu-state-icon')
|
||||
export class FrigateCardElementsMenuStateIcon extends FrigateCardElementsBaseMenuItem<MenuStateIcon> {}
|
||||
@customElement('advanced-camera-card-menu-state-icon')
|
||||
export class AdvancedCameraCardElementsMenuStateIcon extends AdvancedCameraCardElementsBaseMenuItem<MenuStateIcon> {}
|
||||
|
||||
@customElement('frigate-card-menu-submenu')
|
||||
export class FrigateCardElementsMenuSubmenu extends FrigateCardElementsBaseMenuItem<MenuSubmenu> {}
|
||||
@customElement('advanced-camera-card-menu-submenu')
|
||||
export class AdvancedCameraCardElementsMenuSubmenu extends AdvancedCameraCardElementsBaseMenuItem<MenuSubmenu> {}
|
||||
|
||||
@customElement('frigate-card-menu-submenu-select')
|
||||
export class FrigateCardElementsMenuSubmenuSelect extends FrigateCardElementsBaseMenuItem<MenuSubmenuSelect> {}
|
||||
@customElement('advanced-camera-card-menu-submenu-select')
|
||||
export class AdvancedCameraCardElementsMenuSubmenuSelect extends AdvancedCameraCardElementsBaseMenuItem<MenuSubmenuSelect> {}
|
||||
|
||||
export class FrigateCardElementsBaseStatusBarItem<
|
||||
export class AdvancedCameraCardElementsBaseStatusBarItem<
|
||||
ConfigType,
|
||||
> extends FrigateCardElementsBaseItem<ConfigType> {
|
||||
> extends AdvancedCameraCardElementsBaseItem<ConfigType> {
|
||||
constructor() {
|
||||
super('status-bar');
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('frigate-card-status-bar-icon')
|
||||
export class FrigateCardElementsStatusBarIcon extends FrigateCardElementsBaseStatusBarItem<StatusBarIcon> {}
|
||||
@customElement('advanced-camera-card-status-bar-icon')
|
||||
export class AdvancedCameraCardElementsStatusBarIcon extends AdvancedCameraCardElementsBaseStatusBarItem<StatusBarIcon> {}
|
||||
|
||||
@customElement('frigate-card-status-bar-image')
|
||||
export class FrigateCardElementsStatusBarImage extends FrigateCardElementsBaseStatusBarItem<StatusBarImage> {}
|
||||
@customElement('advanced-camera-card-status-bar-image')
|
||||
export class AdvancedCameraCardElementsStatusBarImage extends AdvancedCameraCardElementsBaseStatusBarItem<StatusBarImage> {}
|
||||
|
||||
@customElement('frigate-card-status-bar-string')
|
||||
export class FrigateCardElementsStatusBarString extends FrigateCardElementsBaseStatusBarItem<StatusBarString> {}
|
||||
@customElement('advanced-camera-card-status-bar-string')
|
||||
export class AdvancedCameraCardElementsStatusBarString extends AdvancedCameraCardElementsBaseStatusBarItem<StatusBarString> {}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-conditional': FrigateCardElementsConditional;
|
||||
'frigate-card-elements': FrigateCardElements;
|
||||
'frigate-card-elements-core': FrigateCardElementsCore;
|
||||
'advanced-camera-card-conditional': AdvancedCameraCardElementsConditional;
|
||||
'advanced-camera-card-elements': AdvancedCameraCardElements;
|
||||
'advanced-camera-card-elements-core': AdvancedCameraCardElementsCore;
|
||||
|
||||
'frigate-card-menu-icon': FrigateCardElementsMenuIcon;
|
||||
'frigate-card-menu-state-icon': FrigateCardElementsMenuStateIcon;
|
||||
'frigate-card-menu-submenu': FrigateCardElementsMenuSubmenu;
|
||||
'frigate-card-menu-submenu-select': FrigateCardElementsMenuSubmenuSelect;
|
||||
'advanced-camera-card-menu-icon': AdvancedCameraCardElementsMenuIcon;
|
||||
'advanced-camera-card-menu-state-icon': AdvancedCameraCardElementsMenuStateIcon;
|
||||
'advanced-camera-card-menu-submenu': AdvancedCameraCardElementsMenuSubmenu;
|
||||
'advanced-camera-card-menu-submenu-select': AdvancedCameraCardElementsMenuSubmenuSelect;
|
||||
|
||||
'frigate-card-status-bar-icon': FrigateCardElementsStatusBarIcon;
|
||||
'frigate-card-status-bar-image': FrigateCardElementsStatusBarImage;
|
||||
'frigate-card-status-bar-string': FrigateCardElementsStatusBarString;
|
||||
'advanced-camera-card-status-bar-icon': AdvancedCameraCardElementsStatusBarIcon;
|
||||
'advanced-camera-card-status-bar-image': AdvancedCameraCardElementsStatusBarImage;
|
||||
'advanced-camera-card-status-bar-string': AdvancedCameraCardElementsStatusBarString;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-23
@@ -13,11 +13,7 @@ import throttle from 'lodash-es/throttle';
|
||||
import { CameraManager, ExtendedMediaQueryResult } from '../camera-manager/manager.js';
|
||||
import { EventQuery, MediaQuery, RecordingQuery } from '../camera-manager/types';
|
||||
import { ViewManagerEpoch } from '../card-controller/view/types.js';
|
||||
import {
|
||||
CardWideConfig,
|
||||
frigateCardConfigDefaults,
|
||||
GalleryConfig,
|
||||
} from '../config/types';
|
||||
import { CardWideConfig, configDefaults, GalleryConfig } from '../config/types';
|
||||
import { localize } from '../localize/localize';
|
||||
import galleryCoreStyle from '../scss/gallery-core.scss';
|
||||
import galleryStyle from '../scss/gallery.scss';
|
||||
@@ -45,8 +41,8 @@ const GALLERY_MEDIA_FILTER_MENU_ICONS = {
|
||||
|
||||
const MIN_GALLERY_EXTENSION_SECONDS = 0.5;
|
||||
|
||||
@customElement('frigate-card-gallery')
|
||||
export class FrigateCardGallery extends LitElement {
|
||||
@customElement('advanced-camera-card-gallery')
|
||||
export class AdvancedCameraCardGallery extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public hass?: ExtendedHomeAssistant;
|
||||
|
||||
@@ -78,7 +74,7 @@ export class FrigateCardGallery extends LitElement {
|
||||
}
|
||||
|
||||
return html`
|
||||
<frigate-card-surround-basic
|
||||
<advanced-camera-card-surround-basic
|
||||
.drawerIcons=${{
|
||||
...(this.galleryConfig &&
|
||||
this.galleryConfig.controls.filter.mode !== 'none' && {
|
||||
@@ -87,24 +83,24 @@ export class FrigateCardGallery extends LitElement {
|
||||
}}
|
||||
>
|
||||
${this.galleryConfig && this.galleryConfig.controls.filter.mode !== 'none'
|
||||
? html` <frigate-card-media-filter
|
||||
? html` <advanced-camera-card-media-filter
|
||||
.hass=${this.hass}
|
||||
.cameraManager=${this.cameraManager}
|
||||
.viewManagerEpoch=${this.viewManagerEpoch}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
slot=${this.galleryConfig.controls.filter.mode}
|
||||
>
|
||||
</frigate-card-media-filter>`
|
||||
</advanced-camera-card-media-filter>`
|
||||
: ''}
|
||||
<frigate-card-gallery-core
|
||||
<advanced-camera-card-gallery-core
|
||||
.hass=${this.hass}
|
||||
.viewManagerEpoch=${this.viewManagerEpoch}
|
||||
.galleryConfig=${this.galleryConfig}
|
||||
.cameraManager=${this.cameraManager}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
>
|
||||
</frigate-card-gallery-core>
|
||||
</frigate-card-surround-basic>
|
||||
</advanced-camera-card-gallery-core>
|
||||
</advanced-camera-card-surround-basic>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -113,8 +109,8 @@ export class FrigateCardGallery extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('frigate-card-gallery-core')
|
||||
export class FrigateCardGalleryCore extends LitElement {
|
||||
@customElement('advanced-camera-card-gallery-core')
|
||||
export class AdvancedCameraCardGalleryCore extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public hass?: ExtendedHomeAssistant;
|
||||
|
||||
@@ -266,12 +262,12 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
protected _setColumnCount(): void {
|
||||
const thumbnailSize =
|
||||
this.galleryConfig?.controls.thumbnails.size ??
|
||||
frigateCardConfigDefaults.media_gallery.controls.thumbnails.size;
|
||||
configDefaults.media_gallery.controls.thumbnails.size;
|
||||
const columns = this.galleryConfig?.controls.thumbnails.show_details
|
||||
? Math.max(1, Math.floor(this.clientWidth / THUMBNAIL_DETAILS_WIDTH_MIN))
|
||||
: Math.max(1, Math.ceil(this.clientWidth / thumbnailSize));
|
||||
|
||||
this.style.setProperty('--frigate-card-gallery-columns', String(columns));
|
||||
this.style.setProperty('--advanced-camera-card-gallery-columns', String(columns));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,7 +357,7 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
this._setColumnCount();
|
||||
if (this.galleryConfig?.controls.thumbnails.size) {
|
||||
this.style.setProperty(
|
||||
'--frigate-card-thumbnail-size',
|
||||
'--advanced-camera-card-thumbnail-size',
|
||||
`${this.galleryConfig.controls.thumbnails.size}px`,
|
||||
);
|
||||
}
|
||||
@@ -424,7 +420,7 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
: ''}
|
||||
${this._media.map(
|
||||
(media, index) =>
|
||||
html`<frigate-card-thumbnail
|
||||
html`<advanced-camera-card-thumbnail
|
||||
${media === selected ? ref(this._refSelected) : ''}
|
||||
class=${classMap({
|
||||
selected: media === selected,
|
||||
@@ -456,7 +452,7 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
>
|
||||
</frigate-card-thumbnail>`,
|
||||
</advanced-camera-card-thumbnail>`,
|
||||
)}
|
||||
${this._showLoaderBottom
|
||||
? html`${renderProgressIndicator({
|
||||
@@ -479,7 +475,7 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
// As a special case, if the view has changed and did not previously exist
|
||||
// (i.e. first setting of it), we intentionally scroll the gallery to the
|
||||
// selected element in that view (if any).
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/885
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/885
|
||||
if (
|
||||
// If this update cycle updated the view ...
|
||||
changedProps.has('viewManagerEpoch') &&
|
||||
@@ -503,7 +499,7 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-gallery-core': FrigateCardGalleryCore;
|
||||
'frigate-card-gallery': FrigateCardGallery;
|
||||
'advanced-camera-card-gallery-core': AdvancedCameraCardGalleryCore;
|
||||
'advanced-camera-card-gallery': AdvancedCameraCardGallery;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ import { IconController } from '../components-lib/icon-controller';
|
||||
import iconStyle from '../scss/icon.scss';
|
||||
import { Icon } from '../types';
|
||||
|
||||
@customElement('frigate-card-icon')
|
||||
export class FrigateCardIcon extends LitElement {
|
||||
@customElement('advanced-camera-card-icon')
|
||||
export class AdvancedCameraCardIcon extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@@ -83,6 +83,6 @@ export class FrigateCardIcon extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-icon': FrigateCardIcon;
|
||||
'advanced-camera-card-icon': AdvancedCameraCardIcon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ import { CameraManager } from '../camera-manager/manager.js';
|
||||
import { getCameraEntityFromConfig } from '../camera-manager/utils/camera-entity-from-config.js';
|
||||
import { CachedValueController } from '../components-lib/cached-value-controller.js';
|
||||
import { CameraConfig, ImageMode, ImageViewConfig } from '../config/types.js';
|
||||
import defaultImage from '../images/frigate-bird-in-sky.jpg';
|
||||
import defaultImage from '../images/iris-screensaver.jpg';
|
||||
import { localize } from '../localize/localize.js';
|
||||
import imageStyle from '../scss/image.scss';
|
||||
import {
|
||||
FrigateCardMediaPlayer,
|
||||
AdvancedCameraCardMediaPlayer,
|
||||
FullscreenElement,
|
||||
MediaLoadedInfo,
|
||||
Message,
|
||||
@@ -60,8 +60,11 @@ export const resolveImageMode = (options?: {
|
||||
return 'screensaver';
|
||||
};
|
||||
|
||||
@customElement('frigate-card-image-base')
|
||||
export class FrigateCardImageBase extends LitElement implements FrigateCardMediaPlayer {
|
||||
@customElement('advanced-camera-card-image-base')
|
||||
export class AdvancedCameraCardImageBase
|
||||
extends LitElement
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
@property({ attribute: false })
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@@ -215,7 +218,7 @@ export class FrigateCardImageBase extends LitElement implements FrigateCardMedia
|
||||
* (detects old or disconnected states). Using an old state is problematic as
|
||||
* it runs the risk that the JS has an old access token for the camera, and
|
||||
* that results in a notification on the HA UI about a failed login. See:
|
||||
* https://github.com/dermotduffy/frigate-hass-card/issues/398 .
|
||||
* https://github.com/dermotduffy/advanced-camera-card/issues/398 .
|
||||
* @param entity The entity.
|
||||
* @returns The state or null if not acceptable.
|
||||
*/
|
||||
@@ -263,7 +266,7 @@ export class FrigateCardImageBase extends LitElement implements FrigateCardMedia
|
||||
// image may be using an old-expired token and re-use prior to
|
||||
// re-generation of a new URL would generate an unauthorized request
|
||||
// (401), see:
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/398
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/398
|
||||
this._cachedValueController?.stopTimer();
|
||||
this._cachedValueController?.clearValue();
|
||||
this._forceSafeImage();
|
||||
@@ -409,6 +412,6 @@ export class FrigateCardImageBase extends LitElement implements FrigateCardMedia
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-image-base': FrigateCardImageBase;
|
||||
'advanced-camera-card-image-base': AdvancedCameraCardImageBase;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-10
@@ -17,15 +17,18 @@ import { handleZoomSettingsObservedEvent } from '../components-lib/zoom/zoom-vie
|
||||
import { CameraConfig, ImageViewConfig } from '../config/types';
|
||||
import { IMAGE_VIEW_ZOOM_TARGET_SENTINEL } from '../const';
|
||||
import basicBlockStyle from '../scss/basic-block.scss';
|
||||
import { FrigateCardMediaPlayer, FullscreenElement } from '../types.js';
|
||||
import { AdvancedCameraCardMediaPlayer, FullscreenElement } from '../types.js';
|
||||
import { aspectRatioToString } from '../utils/basic';
|
||||
import { updateElementStyleFromMediaLayoutConfig } from '../utils/media-layout.js';
|
||||
import './image-base';
|
||||
import { resolveImageMode } from './image-base';
|
||||
import './zoomer.js';
|
||||
|
||||
@customElement('frigate-card-image')
|
||||
export class FrigateCardImage extends LitElement implements FrigateCardMediaPlayer {
|
||||
@customElement('advanced-camera-card-image')
|
||||
export class AdvancedCameraCardImage
|
||||
extends LitElement
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
@property({ attribute: false })
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@@ -41,7 +44,7 @@ export class FrigateCardImage extends LitElement implements FrigateCardMediaPlay
|
||||
@property({ attribute: false })
|
||||
public imageConfig?: ImageViewConfig;
|
||||
|
||||
protected _refImage: Ref<Element & FrigateCardMediaPlayer> = createRef();
|
||||
protected _refImage: Ref<Element & AdvancedCameraCardMediaPlayer> = createRef();
|
||||
|
||||
public async play(): Promise<void> {
|
||||
await this._refImage.value?.play();
|
||||
@@ -114,7 +117,7 @@ export class FrigateCardImage extends LitElement implements FrigateCardMediaPlay
|
||||
});
|
||||
|
||||
return this.imageConfig?.zoomable
|
||||
? html` <frigate-card-zoomer
|
||||
? html` <advanced-camera-card-zoomer
|
||||
.defaultSettings=${guard(
|
||||
[this.imageConfig, this.cameraConfig?.dimensions?.layout],
|
||||
() =>
|
||||
@@ -126,7 +129,7 @@ export class FrigateCardImage extends LitElement implements FrigateCardMediaPlay
|
||||
: undefined,
|
||||
)}
|
||||
.settings=${view?.context?.zoom?.[zoomTarget]?.requested}
|
||||
@frigate-card:zoom:change=${(ev: CustomEvent<ZoomSettingsObserved>) =>
|
||||
@advanced-camera-card:zoom:change=${(ev: CustomEvent<ZoomSettingsObserved>) =>
|
||||
handleZoomSettingsObservedEvent(
|
||||
ev,
|
||||
this.viewManagerEpoch?.manager,
|
||||
@@ -134,7 +137,7 @@ export class FrigateCardImage extends LitElement implements FrigateCardMediaPlay
|
||||
)}
|
||||
>
|
||||
${template}
|
||||
</frigate-card-zoomer>`
|
||||
</advanced-camera-card-zoomer>`
|
||||
: template;
|
||||
}
|
||||
|
||||
@@ -144,14 +147,14 @@ export class FrigateCardImage extends LitElement implements FrigateCardMediaPlay
|
||||
}
|
||||
|
||||
return this._useZoomIfRequired(html`
|
||||
<frigate-card-image-base
|
||||
<advanced-camera-card-image-base
|
||||
${ref(this._refImage)}
|
||||
.hass=${this.hass}
|
||||
.view=${this.viewManagerEpoch?.manager.getView()}
|
||||
.imageConfig=${this.imageConfig}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
>
|
||||
</frigate-card-image-base>
|
||||
</advanced-camera-card-image-base>
|
||||
`);
|
||||
}
|
||||
|
||||
@@ -162,6 +165,6 @@ export class FrigateCardImage extends LitElement implements FrigateCardMediaPlay
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-image': FrigateCardImage;
|
||||
'advanced-camera-card-image': AdvancedCameraCardImage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ import keyAssignerStyle from '../scss/key-assigner.scss';
|
||||
import { localize } from '../localize/localize';
|
||||
import './icon';
|
||||
|
||||
@customElement('frigate-card-key-assigner')
|
||||
export class FrigateCardKeyAssigner extends LitElement {
|
||||
@customElement('advanced-camera-card-key-assigner')
|
||||
export class AdvancedCameraCardKeyAssigner extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public label?: string;
|
||||
|
||||
@@ -49,7 +49,7 @@ export class FrigateCardKeyAssigner extends LitElement {
|
||||
this._controller.toggleAssigning();
|
||||
}}
|
||||
>
|
||||
<frigate-card-icon .icon=${{ icon: 'mdi:keyboard-settings' }}></frigate-card-icon>
|
||||
<advanced-camera-card-icon .icon=${{ icon: 'mdi:keyboard-settings' }}></advanced-camera-card-icon>
|
||||
<span class="${classMap({
|
||||
dotdotdot: this._controller.isAssigning(),
|
||||
})}">
|
||||
@@ -63,9 +63,9 @@ export class FrigateCardKeyAssigner extends LitElement {
|
||||
this._controller.setValue(null);
|
||||
}}
|
||||
>
|
||||
<frigate-card-icon
|
||||
<advanced-camera-card-icon
|
||||
.icon=${{ icon: 'mdi:keyboard-off' }}
|
||||
></frigate-card-icon>
|
||||
></advanced-camera-card-icon>
|
||||
<span> ${localize('key_assigner.unassign')} </span>
|
||||
</ha-button>`
|
||||
: ''
|
||||
@@ -87,6 +87,6 @@ export class FrigateCardKeyAssigner extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-key-assigner': FrigateCardKeyAssigner;
|
||||
'advanced-camera-card-key-assigner': AdvancedCameraCardKeyAssigner;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ import {
|
||||
import { MicrophoneState } from '../../card-controller/types.js';
|
||||
import { ViewManagerEpoch } from '../../card-controller/view/types.js';
|
||||
import { MediaActionsController } from '../../components-lib/media-actions-controller.js';
|
||||
import { dispatchFrigateCardErrorEvent } from '../../components-lib/message/dispatch.js';
|
||||
import { dispatchAdvancedCameraCardErrorEvent } from '../../components-lib/message/dispatch.js';
|
||||
import { ZoomSettingsObserved } from '../../components-lib/zoom/types.js';
|
||||
import { handleZoomSettingsObservedEvent } from '../../components-lib/zoom/zoom-view-context.js';
|
||||
import {
|
||||
CameraConfig,
|
||||
CardWideConfig,
|
||||
frigateCardConfigDefaults,
|
||||
configDefaults,
|
||||
LiveConfig,
|
||||
liveConfigAbsoluteRootSchema,
|
||||
Overrides,
|
||||
@@ -45,11 +45,11 @@ import '../carousel';
|
||||
import { EmblaCarouselPlugins } from '../carousel.js';
|
||||
import '../next-prev-control.js';
|
||||
import '../ptz.js';
|
||||
import { FrigateCardPTZ } from '../ptz.js';
|
||||
import { AdvancedCameraCardPTZ } from '../ptz.js';
|
||||
import './provider.js';
|
||||
import { FrigateCardLiveProvider } from './provider.js';
|
||||
import { AdvancedCameraCardLiveProvider } from './provider.js';
|
||||
|
||||
const FRIGATE_CARD_LIVE_PROVIDER = 'frigate-card-live-provider';
|
||||
const ADVANCED_CAMERA_CARD_LIVE_PROVIDER = 'advanced-camera-card-live-provider';
|
||||
|
||||
interface CameraNeighbor {
|
||||
id: string;
|
||||
@@ -61,8 +61,8 @@ interface CameraNeighbors {
|
||||
next?: CameraNeighbor;
|
||||
}
|
||||
|
||||
@customElement('frigate-card-live-carousel')
|
||||
export class FrigateCardLiveCarousel extends LitElement {
|
||||
@customElement('advanced-camera-card-live-carousel')
|
||||
export class AdvancedCameraCardLiveCarousel extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public hass?: ExtendedHomeAssistant;
|
||||
|
||||
@@ -95,7 +95,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
|
||||
// Index between camera name and slide number.
|
||||
protected _cameraToSlide: Record<string, number> = {};
|
||||
protected _refPTZControl: Ref<FrigateCardPTZ> = createRef();
|
||||
protected _refPTZControl: Ref<AdvancedCameraCardPTZ> = createRef();
|
||||
protected _refCarousel: Ref<HTMLElement> = createRef();
|
||||
|
||||
protected _mediaActionsController = new MediaActionsController();
|
||||
@@ -118,7 +118,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
protected _getTransitionEffect(): TransitionEffect {
|
||||
return (
|
||||
this.overriddenLiveConfig?.transition_effect ??
|
||||
frigateCardConfigDefaults.live.transition_effect
|
||||
configDefaults.live.transition_effect
|
||||
);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
changedProps.has('overriddenLiveConfig')
|
||||
) {
|
||||
this._mediaActionsController.setOptions({
|
||||
playerSelector: FRIGATE_CARD_LIVE_PROVIDER,
|
||||
playerSelector: ADVANCED_CAMERA_CARD_LIVE_PROVIDER,
|
||||
...(this.overriddenLiveConfig?.auto_play && {
|
||||
autoPlayConditions: this.overriddenLiveConfig.auto_play,
|
||||
}),
|
||||
@@ -254,8 +254,8 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
}
|
||||
|
||||
const liveProvider = slide?.querySelector(
|
||||
FRIGATE_CARD_LIVE_PROVIDER,
|
||||
) as FrigateCardLiveProvider | null;
|
||||
ADVANCED_CAMERA_CARD_LIVE_PROVIDER,
|
||||
) as AdvancedCameraCardLiveProvider | null;
|
||||
if (liveProvider) {
|
||||
liveProvider.load = action === 'load';
|
||||
}
|
||||
@@ -280,7 +280,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
try {
|
||||
// The condition controller object contains the currently live camera, which
|
||||
// (in the carousel for example) is not necessarily the live camera *this*
|
||||
// <frigate-card-live-provider> is rendering right now, so we provide a
|
||||
// <advanced-camera-card-live-provider> is rendering right now, so we provide a
|
||||
// stateOverride to evaluate the condition in that context.
|
||||
liveConfig = getOverriddenConfig(
|
||||
this.conditionsManagerEpoch.manager,
|
||||
@@ -292,7 +292,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
},
|
||||
).live;
|
||||
} catch (ev) {
|
||||
return dispatchFrigateCardErrorEvent(this, ev);
|
||||
return dispatchAdvancedCameraCardErrorEvent(this, ev);
|
||||
}
|
||||
|
||||
const cameraMetadata = this.cameraManager.getCameraMetadata(cameraID);
|
||||
@@ -300,7 +300,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
|
||||
return html`
|
||||
<div class="embla__slide">
|
||||
<frigate-card-live-provider
|
||||
<advanced-camera-card-live-provider
|
||||
?load=${!liveConfig.lazy_load}
|
||||
.microphoneState=${view?.camera === cameraID
|
||||
? this.microphoneState
|
||||
@@ -315,14 +315,14 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
.zoomSettings=${view?.context?.zoom?.[cameraID]?.requested}
|
||||
@frigate-card:zoom:change=${(ev: CustomEvent<ZoomSettingsObserved>) =>
|
||||
@advanced-camera-card:zoom:change=${(ev: CustomEvent<ZoomSettingsObserved>) =>
|
||||
handleZoomSettingsObservedEvent(
|
||||
ev,
|
||||
this.viewManagerEpoch?.manager,
|
||||
cameraID,
|
||||
)}
|
||||
>
|
||||
</frigate-card-live-provider>
|
||||
</advanced-camera-card-live-provider>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -381,7 +381,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
? neighbors?.previous
|
||||
: neighbors?.next;
|
||||
|
||||
return html`<frigate-card-next-previous-control
|
||||
return html`<advanced-camera-card-next-previous-control
|
||||
slot=${side}
|
||||
.hass=${this.hass}
|
||||
.side=${side}
|
||||
@@ -394,7 +394,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
>
|
||||
</frigate-card-next-previous-control>`;
|
||||
</advanced-camera-card-next-previous-control>`;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
@@ -424,7 +424,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
// options/plugins actually change.
|
||||
|
||||
return html`
|
||||
<frigate-card-carousel
|
||||
<advanced-camera-card-carousel
|
||||
${ref(this._refCarousel)}
|
||||
.loop=${hasMultipleCameras}
|
||||
.dragEnabled=${hasMultipleCameras && this.overriddenLiveConfig?.draggable}
|
||||
@@ -434,11 +434,11 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
)}
|
||||
.selected=${this._getSelectedCameraIndex()}
|
||||
transitionEffect=${this._getTransitionEffect()}
|
||||
@frigate-card:carousel:select=${this._setViewHandler.bind(this)}
|
||||
@frigate-card:media:loaded=${() => {
|
||||
@advanced-camera-card:carousel:select=${this._setViewHandler.bind(this)}
|
||||
@advanced-camera-card:media:loaded=${() => {
|
||||
this._mediaHasLoaded = true;
|
||||
}}
|
||||
@frigate-card:media:unloaded=${() => {
|
||||
@advanced-camera-card:media:unloaded=${() => {
|
||||
this._mediaHasLoaded = false;
|
||||
}}
|
||||
>
|
||||
@@ -447,14 +447,14 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
${slides}
|
||||
<!-- -->
|
||||
${this._renderNextPrevious('right', neighbors)}
|
||||
</frigate-card-carousel>
|
||||
<frigate-card-ptz
|
||||
</advanced-camera-card-carousel>
|
||||
<advanced-camera-card-ptz
|
||||
.config=${this.overriddenLiveConfig.controls.ptz}
|
||||
.cameraManager=${this.cameraManager}
|
||||
.cameraID=${getStreamCameraID(view, this.viewFilterCameraID)}
|
||||
.forceVisibility=${forcePTZVisibility}
|
||||
>
|
||||
</frigate-card-ptz>
|
||||
</advanced-camera-card-ptz>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -486,7 +486,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
|
||||
// If the view has changed, or if the media actions controller has just been
|
||||
// initialized, then call the necessary media action.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1626
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1626
|
||||
if (initialized || changedProperties.has('viewManagerEpoch')) {
|
||||
this._setMediaTarget();
|
||||
}
|
||||
@@ -499,6 +499,6 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-carousel': FrigateCardLiveCarousel;
|
||||
'advanced-camera-card-live-carousel': AdvancedCameraCardLiveCarousel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ import { ExtendedHomeAssistant } from '../../types.js';
|
||||
import { contentsChanged } from '../../utils/basic.js';
|
||||
import './carousel.js';
|
||||
|
||||
@customElement('frigate-card-live-grid')
|
||||
export class FrigateCardLiveGrid extends LitElement {
|
||||
@customElement('advanced-camera-card-live-grid')
|
||||
export class AdvancedCameraCardLiveGrid extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public hass?: ExtendedHomeAssistant;
|
||||
|
||||
@@ -56,7 +56,7 @@ export class FrigateCardLiveGrid extends LitElement {
|
||||
const triggeredCameraID = cameraID ?? view?.camera;
|
||||
|
||||
return html`
|
||||
<frigate-card-live-carousel
|
||||
<advanced-camera-card-live-carousel
|
||||
grid-id=${ifDefined(cameraID)}
|
||||
.hass=${this.hass}
|
||||
.viewManagerEpoch=${this.viewManagerEpoch}
|
||||
@@ -71,7 +71,7 @@ export class FrigateCardLiveGrid extends LitElement {
|
||||
?triggered=${triggeredCameraID &&
|
||||
!!this.triggeredCameraIDs?.has(triggeredCameraID)}
|
||||
>
|
||||
</frigate-card-live-carousel>
|
||||
</advanced-camera-card-live-carousel>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -110,14 +110,15 @@ export class FrigateCardLiveGrid extends LitElement {
|
||||
}
|
||||
|
||||
return html`
|
||||
<frigate-card-media-grid
|
||||
<advanced-camera-card-media-grid
|
||||
.selected=${this.viewManagerEpoch?.manager.getView()?.camera}
|
||||
.displayConfig=${this.overriddenLiveConfig?.display}
|
||||
@frigate-card:media-grid:selected=${(ev: CustomEvent<MediaGridSelected>) =>
|
||||
this._gridSelectCamera(ev.detail.selected)}
|
||||
@advanced-camera-card:media-grid:selected=${(
|
||||
ev: CustomEvent<MediaGridSelected>,
|
||||
) => this._gridSelectCamera(ev.detail.selected)}
|
||||
>
|
||||
${[...cameraIDs].map((cameraID) => this._renderCarousel(cameraID))}
|
||||
</frigate-card-media-grid>
|
||||
</advanced-camera-card-media-grid>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -128,6 +129,6 @@ export class FrigateCardLiveGrid extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-grid': FrigateCardLiveGrid;
|
||||
'advanced-camera-card-live-grid': AdvancedCameraCardLiveGrid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import { ExtendedHomeAssistant } from '../../types.js';
|
||||
import { contentsChanged } from '../../utils/basic.js';
|
||||
import './grid.js';
|
||||
|
||||
@customElement('frigate-card-live')
|
||||
export class FrigateCardLive extends LitElement {
|
||||
@customElement('advanced-camera-card-live')
|
||||
export class AdvancedCameraCardLive extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public conditionsManagerEpoch?: ConditionsManagerEpoch;
|
||||
|
||||
@@ -57,7 +57,7 @@ export class FrigateCardLive extends LitElement {
|
||||
// - Various events are captured to prevent them propagating upwards if the
|
||||
// card is in the background.
|
||||
return html`
|
||||
<frigate-card-live-grid
|
||||
<advanced-camera-card-live-grid
|
||||
.hass=${this.hass}
|
||||
.viewManagerEpoch=${this.viewManagerEpoch}
|
||||
.nonOverriddenLiveConfig=${this.nonOverriddenLiveConfig}
|
||||
@@ -70,7 +70,7 @@ export class FrigateCardLive extends LitElement {
|
||||
.microphoneState=${this.microphoneState}
|
||||
.triggeredCameraIDs=${this.triggeredCameraIDs}
|
||||
>
|
||||
</frigate-card-live-grid>
|
||||
</advanced-camera-card-live-grid>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,6 @@ export class FrigateCardLive extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live': FrigateCardLive;
|
||||
'advanced-camera-card-live': AdvancedCameraCardLive;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { PartialZoomSettings } from '../../components-lib/zoom/types.js';
|
||||
import {
|
||||
CameraConfig,
|
||||
CardWideConfig,
|
||||
frigateCardConfigDefaults,
|
||||
configDefaults,
|
||||
LiveConfig,
|
||||
LiveProvider,
|
||||
} from '../../config/types.js';
|
||||
@@ -26,7 +26,7 @@ import { localize } from '../../localize/localize.js';
|
||||
import liveProviderStyle from '../../scss/live-provider.scss';
|
||||
import {
|
||||
ExtendedHomeAssistant,
|
||||
FrigateCardMediaPlayer,
|
||||
AdvancedCameraCardMediaPlayer,
|
||||
FullscreenElement,
|
||||
} from '../../types.js';
|
||||
import { aspectRatioToString } from '../../utils/basic.js';
|
||||
@@ -39,10 +39,10 @@ import '../next-prev-control.js';
|
||||
import '../ptz.js';
|
||||
import '../surround.js';
|
||||
|
||||
@customElement('frigate-card-live-provider')
|
||||
export class FrigateCardLiveProvider
|
||||
@customElement('advanced-camera-card-live-provider')
|
||||
export class AdvancedCameraCardLiveProvider
|
||||
extends LitElement
|
||||
implements FrigateCardMediaPlayer
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
@property({ attribute: false })
|
||||
public hass?: ExtendedHomeAssistant;
|
||||
@@ -84,7 +84,7 @@ export class FrigateCardLiveProvider
|
||||
@state()
|
||||
protected _showStreamTroubleshooting = false;
|
||||
|
||||
protected _refProvider: Ref<LitElement & FrigateCardMediaPlayer> = createRef();
|
||||
protected _refProvider: Ref<LitElement & AdvancedCameraCardMediaPlayer> = createRef();
|
||||
|
||||
// A note on dynamic imports:
|
||||
//
|
||||
@@ -94,7 +94,7 @@ export class FrigateCardLiveProvider
|
||||
// underlying code is not yet loaded.
|
||||
//
|
||||
// Test case: A card with a non-live view, but live pre-loaded, attempts to
|
||||
// call mute() when the <frigate-card-live> element first renders in the
|
||||
// call mute() when the <advanced-camera-card-live> element first renders in the
|
||||
// background. These calls fail without waiting for loading here.
|
||||
protected _importPromises: Promise<unknown>[] = [];
|
||||
|
||||
@@ -168,7 +168,7 @@ export class FrigateCardLiveProvider
|
||||
} else if (this.cameraConfig?.frigate.camera_name) {
|
||||
return 'jsmpeg';
|
||||
}
|
||||
return frigateCardConfigDefaults.cameras.live_provider;
|
||||
return configDefaults.cameras.live_provider;
|
||||
}
|
||||
return this.cameraConfig?.live_provider || 'image';
|
||||
}
|
||||
@@ -254,7 +254,7 @@ export class FrigateCardLiveProvider
|
||||
|
||||
protected _useZoomIfRequired(template: TemplateResult): TemplateResult {
|
||||
return this.liveConfig?.zoomable
|
||||
? html` <frigate-card-zoomer
|
||||
? html` <advanced-camera-card-zoomer
|
||||
.defaultSettings=${guard([this.cameraConfig?.dimensions?.layout], () =>
|
||||
this.cameraConfig?.dimensions?.layout
|
||||
? {
|
||||
@@ -264,11 +264,11 @@ export class FrigateCardLiveProvider
|
||||
: undefined,
|
||||
)}
|
||||
.settings=${this.zoomSettings}
|
||||
@frigate-card:zoom:zoomed=${() => this.setControls(false)}
|
||||
@frigate-card:zoom:unzoomed=${() => this.setControls()}
|
||||
@advanced-camera-card:zoom:zoomed=${() => this.setControls(false)}
|
||||
@advanced-camera-card:zoom:unzoomed=${() => this.setControls()}
|
||||
>
|
||||
${template}
|
||||
</frigate-card-zoomer>`
|
||||
</advanced-camera-card-zoomer>`
|
||||
: template;
|
||||
}
|
||||
|
||||
@@ -331,12 +331,12 @@ export class FrigateCardLiveProvider
|
||||
|
||||
return html`${this._useZoomIfRequired(html`
|
||||
${showImageDuringLoading || provider === 'image'
|
||||
? html` <frigate-card-live-image
|
||||
? html` <advanced-camera-card-live-image
|
||||
${ref(this._refProvider)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
@frigate-card:live:error=${() => this._providerErrorHandler()}
|
||||
@frigate-card:media:loaded=${(ev: Event) => {
|
||||
@advanced-camera-card:live:error=${() => this._providerErrorHandler()}
|
||||
@advanced-camera-card:media:loaded=${(ev: Event) => {
|
||||
if (provider === 'image') {
|
||||
// Only count the media has loaded if the required provider is
|
||||
// the image (not just the temporary image shown during
|
||||
@@ -347,21 +347,21 @@ export class FrigateCardLiveProvider
|
||||
}
|
||||
}}
|
||||
>
|
||||
</frigate-card-live-image>`
|
||||
</advanced-camera-card-live-image>`
|
||||
: html``}
|
||||
${provider === 'ha'
|
||||
? html` <frigate-card-live-ha
|
||||
? html` <advanced-camera-card-live-ha
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
?controls=${this.liveConfig.controls.builtin}
|
||||
@frigate-card:live:error=${() => this._providerErrorHandler()}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
@advanced-camera-card:live:error=${() => this._providerErrorHandler()}
|
||||
@advanced-camera-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-ha>`
|
||||
</advanced-camera-card-live-ha>`
|
||||
: provider === 'go2rtc'
|
||||
? html`<frigate-card-live-go2rtc
|
||||
? html`<advanced-camera-card-live-go2rtc
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
@@ -370,12 +370,14 @@ export class FrigateCardLiveProvider
|
||||
.microphoneState=${this.microphoneState}
|
||||
.microphoneConfig=${this.liveConfig.microphone}
|
||||
?controls=${this.liveConfig.controls.builtin}
|
||||
@frigate-card:live:error=${() => this._providerErrorHandler()}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
@advanced-camera-card:live:error=${() => this._providerErrorHandler()}
|
||||
@advanced-camera-card:media:loaded=${this._videoMediaShowHandler.bind(
|
||||
this,
|
||||
)}
|
||||
>
|
||||
</frigate-card-live-go2rtc>`
|
||||
</advanced-camera-card-live-go2rtc>`
|
||||
: provider === 'webrtc-card'
|
||||
? html`<frigate-card-live-webrtc-card
|
||||
? html`<advanced-camera-card-live-webrtc-card
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
@@ -383,32 +385,36 @@ export class FrigateCardLiveProvider
|
||||
.cameraEndpoints=${this.cameraEndpoints}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
?controls=${this.liveConfig.controls.builtin}
|
||||
@frigate-card:live:error=${() => this._providerErrorHandler()}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
@advanced-camera-card:live:error=${() => this._providerErrorHandler()}
|
||||
@advanced-camera-card:media:loaded=${this._videoMediaShowHandler.bind(
|
||||
this,
|
||||
)}
|
||||
>
|
||||
</frigate-card-live-webrtc-card>`
|
||||
</advanced-camera-card-live-webrtc-card>`
|
||||
: provider === 'jsmpeg'
|
||||
? html` <frigate-card-live-jsmpeg
|
||||
? html` <advanced-camera-card-live-jsmpeg
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
.cameraEndpoints=${this.cameraEndpoints}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:live:error=${() => this._providerErrorHandler()}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
@advanced-camera-card:live:error=${() => this._providerErrorHandler()}
|
||||
@advanced-camera-card:media:loaded=${this._videoMediaShowHandler.bind(
|
||||
this,
|
||||
)}
|
||||
>
|
||||
</frigate-card-live-jsmpeg>`
|
||||
</advanced-camera-card-live-jsmpeg>`
|
||||
: html``}
|
||||
`)}
|
||||
${showLoadingIcon
|
||||
? html`<frigate-card-icon
|
||||
? html`<advanced-camera-card-icon
|
||||
title=${localize('error.awaiting_live')}
|
||||
.icon=${{ icon: 'mdi:progress-helper' }}
|
||||
@click=${() => {
|
||||
this._showStreamTroubleshooting = !this._showStreamTroubleshooting;
|
||||
}}
|
||||
></frigate-card-icon>`
|
||||
></advanced-camera-card-icon>`
|
||||
: ''}
|
||||
${this._showStreamTroubleshooting
|
||||
? renderMessage(
|
||||
@@ -430,6 +436,6 @@ export class FrigateCardLiveProvider
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-provider': FrigateCardLiveProvider;
|
||||
'advanced-camera-card-live-provider': AdvancedCameraCardLiveProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# go2rtc Player
|
||||
|
||||
This is a modified version of the go2rtc example video player code, modified for
|
||||
use in the Frigate card. In order to make future maintenance easier,
|
||||
use in the Advanced Camera Card. In order to make future maintenance easier,
|
||||
modifications have been kept to a minimum.
|
||||
|
||||
## Original Example Code
|
||||
|
||||
@@ -15,7 +15,7 @@ import { localize } from '../../../../localize/localize.js';
|
||||
import liveGo2RTCStyle from '../../../../scss/live-go2rtc.scss';
|
||||
import {
|
||||
ExtendedHomeAssistant,
|
||||
FrigateCardMediaPlayer,
|
||||
AdvancedCameraCardMediaPlayer,
|
||||
FullscreenElement,
|
||||
Message,
|
||||
} from '../../../../types.js';
|
||||
@@ -25,7 +25,7 @@ import { screenshotMedia } from '../../../../utils/screenshot.js';
|
||||
import { renderMessage } from '../../../message.js';
|
||||
import { VideoRTC } from './video-rtc.js';
|
||||
|
||||
customElements.define('frigate-card-live-go2rtc-player', VideoRTC);
|
||||
customElements.define('advanced-camera-card-live-go2rtc-player', VideoRTC);
|
||||
|
||||
// Note (2023-02-18): Depending on the behavior of the player / browser is
|
||||
// possible this URL will need to be re-signed in order to avoid HA spamming
|
||||
@@ -34,8 +34,11 @@ customElements.define('frigate-card-live-go2rtc-player', VideoRTC);
|
||||
// provider).
|
||||
const GO2RTC_URL_SIGN_EXPIRY_SECONDS = 24 * 60 * 60;
|
||||
|
||||
@customElement('frigate-card-live-go2rtc')
|
||||
export class FrigateCardGo2RTC extends LitElement implements FrigateCardMediaPlayer {
|
||||
@customElement('advanced-camera-card-live-go2rtc')
|
||||
export class AdvancedCameraCardGo2RTC
|
||||
extends LitElement
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
// Not an reactive property to avoid resetting the video.
|
||||
public hass?: ExtendedHomeAssistant;
|
||||
|
||||
@@ -116,7 +119,7 @@ export class FrigateCardGo2RTC extends LitElement implements FrigateCardMediaPla
|
||||
super.connectedCallback();
|
||||
|
||||
// Reset the player when reconnected to the DOM.
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/996
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/996
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
@@ -205,6 +208,6 @@ export class FrigateCardGo2RTC extends LitElement implements FrigateCardMediaPla
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-go2rtc': FrigateCardGo2RTC;
|
||||
'advanced-camera-card-live-go2rtc': AdvancedCameraCardGo2RTC;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ export class VideoRTC extends HTMLElement {
|
||||
onmessage: Record<string, (msg: { type: string; value: string }) => void>;
|
||||
|
||||
// Custom methods/members.
|
||||
containingPlayer: FrigateCardMediaPlayer | null;
|
||||
containingPlayer: AdvancedCameraCardMediaPlayer | null;
|
||||
microphoneStream: MediaStream | null;
|
||||
reconnect();
|
||||
|
||||
|
||||
@@ -162,8 +162,8 @@ export class VideoRTC extends HTMLElement {
|
||||
this.microphoneStream = null;
|
||||
|
||||
/**
|
||||
* A reference to a containing FrigateCardMediaPlayer object.
|
||||
* @type {FrigateCardMediaPlayer}}
|
||||
* A reference to a containing AdvancedCameraCardMediaPlayer object.
|
||||
* @type {AdvancedCameraCardMediaPlayer}}
|
||||
*/
|
||||
this.containingPlayer = null;
|
||||
|
||||
@@ -222,7 +222,7 @@ export class VideoRTC extends HTMLElement {
|
||||
* https://developer.chrome.com/blog/autoplay/
|
||||
*/
|
||||
play() {
|
||||
// Frigate card controls playing at a higher level.
|
||||
// Advanced Camera Card controls playing at a higher level.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +303,7 @@ export class VideoRTC extends HTMLElement {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
this.video.addEventListener('error', (_ev) => {
|
||||
// For Frigate Card, we avoid log spam here from errors, and also don't
|
||||
// For Advanced Camera Card, we avoid log spam here from errors, and also don't
|
||||
// attempt to close the websocket unless the connection is open (otherwise
|
||||
// on reconnect() an exception will be thrown here that we're attempting
|
||||
// to close a connection that's not open)
|
||||
@@ -405,7 +405,7 @@ export class VideoRTC extends HTMLElement {
|
||||
if (this.pc) {
|
||||
// Do not close the (microphone) track attached to the peer connection as
|
||||
// that is controlled by MicrophoneManager.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1810
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1810
|
||||
|
||||
this.pc.close();
|
||||
this.pc = null;
|
||||
|
||||
@@ -7,10 +7,13 @@ import '../../../patches/ha-camera-stream';
|
||||
import '../../../patches/ha-hls-player.js';
|
||||
import '../../../patches/ha-web-rtc-player.js';
|
||||
import liveHAStyle from '../../../scss/live-ha.scss';
|
||||
import { FrigateCardMediaPlayer, FullscreenElement } from '../../../types.js';
|
||||
import { AdvancedCameraCardMediaPlayer, FullscreenElement } from '../../../types.js';
|
||||
|
||||
@customElement('frigate-card-live-ha')
|
||||
export class FrigateCardLiveHA extends LitElement implements FrigateCardMediaPlayer {
|
||||
@customElement('advanced-camera-card-live-ha')
|
||||
export class AdvancedCameraCardLiveHA
|
||||
extends LitElement
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
@property({ attribute: false })
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@@ -20,7 +23,7 @@ export class FrigateCardLiveHA extends LitElement implements FrigateCardMediaPla
|
||||
@property({ attribute: true, type: Boolean })
|
||||
public controls = false;
|
||||
|
||||
protected _playerRef: Ref<Element & FrigateCardMediaPlayer> = createRef();
|
||||
protected _playerRef: Ref<Element & AdvancedCameraCardMediaPlayer> = createRef();
|
||||
|
||||
public async play(): Promise<void> {
|
||||
return this._playerRef.value?.play();
|
||||
@@ -67,7 +70,7 @@ export class FrigateCardLiveHA extends LitElement implements FrigateCardMediaPla
|
||||
return;
|
||||
}
|
||||
|
||||
return html` <frigate-card-ha-camera-stream
|
||||
return html` <advanced-camera-card-ha-camera-stream
|
||||
${ref(this._playerRef)}
|
||||
.hass=${this.hass}
|
||||
.stateObj=${this.cameraConfig?.camera_entity
|
||||
@@ -76,7 +79,7 @@ export class FrigateCardLiveHA extends LitElement implements FrigateCardMediaPla
|
||||
.controls=${this.controls}
|
||||
.muted=${true}
|
||||
>
|
||||
</frigate-card-ha-camera-stream>`;
|
||||
</advanced-camera-card-ha-camera-stream>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
@@ -86,6 +89,6 @@ export class FrigateCardLiveHA extends LitElement implements FrigateCardMediaPla
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-ha': FrigateCardLiveHA;
|
||||
'advanced-camera-card-live-ha': AdvancedCameraCardLiveHA;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,21 @@ import { customElement, property } from 'lit/decorators.js';
|
||||
import { createRef, ref, Ref } from 'lit/directives/ref.js';
|
||||
import { CameraConfig } from '../../../config/types';
|
||||
import basicBlockStyle from '../../../scss/basic-block.scss';
|
||||
import { FrigateCardMediaPlayer, FullscreenElement } from '../../../types.js';
|
||||
import { AdvancedCameraCardMediaPlayer, FullscreenElement } from '../../../types.js';
|
||||
import '../../image-base.js';
|
||||
|
||||
@customElement('frigate-card-live-image')
|
||||
export class FrigateCardLiveImage extends LitElement implements FrigateCardMediaPlayer {
|
||||
@customElement('advanced-camera-card-live-image')
|
||||
export class AdvancedCameraCardLiveImage
|
||||
extends LitElement
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
@property({ attribute: false })
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cameraConfig?: CameraConfig;
|
||||
|
||||
protected _refImage: Ref<Element & FrigateCardMediaPlayer> = createRef();
|
||||
protected _refImage: Ref<Element & AdvancedCameraCardMediaPlayer> = createRef();
|
||||
|
||||
public async play(): Promise<void> {
|
||||
await this._refImage.value?.play();
|
||||
@@ -63,13 +66,13 @@ export class FrigateCardLiveImage extends LitElement implements FrigateCardMedia
|
||||
}
|
||||
|
||||
return html`
|
||||
<frigate-card-image-base
|
||||
<advanced-camera-card-image-base
|
||||
${ref(this._refImage)}
|
||||
.hass=${this.hass}
|
||||
.imageConfig=${this.cameraConfig.image}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
>
|
||||
</frigate-card-image-base>
|
||||
</advanced-camera-card-image-base>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -80,6 +83,6 @@ export class FrigateCardLiveImage extends LitElement implements FrigateCardMedia
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-image': FrigateCardLiveImage;
|
||||
'advanced-camera-card-live-image': AdvancedCameraCardLiveImage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ import { CameraConfig, CardWideConfig } from '../../../config/types.js';
|
||||
import { localize } from '../../../localize/localize.js';
|
||||
import liveJSMPEGStyle from '../../../scss/live-jsmpeg.scss';
|
||||
import {
|
||||
AdvancedCameraCardMediaPlayer,
|
||||
ExtendedHomeAssistant,
|
||||
FrigateCardMediaPlayer,
|
||||
FullscreenElement,
|
||||
Message,
|
||||
} from '../../../types.js';
|
||||
@@ -38,8 +38,11 @@ const JSMPEG_URL_SIGN_EXPIRY_SECONDS = 24 * 60 * 60;
|
||||
// Number of seconds before the expiry to trigger a refresh.
|
||||
const JSMPEG_URL_SIGN_REFRESH_THRESHOLD_SECONDS = 1 * 60 * 60;
|
||||
|
||||
@customElement('frigate-card-live-jsmpeg')
|
||||
export class FrigateCardLiveJSMPEG extends LitElement implements FrigateCardMediaPlayer {
|
||||
@customElement('advanced-camera-card-live-jsmpeg')
|
||||
export class AdvancedCameraCardLiveJSMPEG
|
||||
extends LitElement
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
@property({ attribute: false })
|
||||
public cameraConfig?: CameraConfig;
|
||||
|
||||
@@ -303,6 +306,6 @@ export class FrigateCardLiveJSMPEG extends LitElement implements FrigateCardMedi
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-jsmpeg': FrigateCardLiveJSMPEG;
|
||||
'advanced-camera-card-live-jsmpeg': AdvancedCameraCardLiveJSMPEG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ import { CameraConfig, CardWideConfig } from '../../../config/types.js';
|
||||
import { localize } from '../../../localize/localize.js';
|
||||
import liveWebRTCCardStyle from '../../../scss/live-webrtc-card.scss';
|
||||
import {
|
||||
FrigateCardError,
|
||||
FrigateCardMediaPlayer,
|
||||
AdvancedCameraCardError,
|
||||
AdvancedCameraCardMediaPlayer,
|
||||
FullscreenElement,
|
||||
Message,
|
||||
} from '../../../types.js';
|
||||
@@ -43,10 +43,10 @@ import { VideoRTC } from './go2rtc/video-rtc.js';
|
||||
|
||||
// Create a wrapper for AlexxIT's WebRTC card
|
||||
// - https://github.com/AlexxIT/WebRTC
|
||||
@customElement('frigate-card-live-webrtc-card')
|
||||
export class FrigateCardLiveWebRTCCard
|
||||
@customElement('advanced-camera-card-live-webrtc-card')
|
||||
export class AdvancedCameraCardLiveWebRTCCard
|
||||
extends LitElement
|
||||
implements FrigateCardMediaPlayer
|
||||
implements AdvancedCameraCardMediaPlayer
|
||||
{
|
||||
@property({ attribute: false })
|
||||
public cameraConfig?: CameraConfig;
|
||||
@@ -125,7 +125,7 @@ export class FrigateCardLiveWebRTCCard
|
||||
super.connectedCallback();
|
||||
|
||||
// Reset the player when reconnected to the DOM.
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/996
|
||||
// https://github.com/dermotduffy/advanced-camera-card/issues/996
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
@@ -177,11 +177,11 @@ export class FrigateCardLiveWebRTCCard
|
||||
// hidden. This is incompatible with the card zoom support, since the
|
||||
// video will easily stop if the user zooms in too much. Disable this
|
||||
// feature by default.
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1614
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1614
|
||||
intersection: 0,
|
||||
|
||||
// Frigate card always starts muted (unlike webrtc-card).
|
||||
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1654
|
||||
// Advanced Camera Card always starts muted (unlike webrtc-card).
|
||||
// See: https://github.com/dermotduffy/advanced-camera-card/issues/1654
|
||||
muted: true,
|
||||
|
||||
...this.cameraConfig.webrtc_card,
|
||||
@@ -209,12 +209,12 @@ export class FrigateCardLiveWebRTCCard
|
||||
this._message = {
|
||||
type: 'error',
|
||||
message:
|
||||
e instanceof FrigateCardError
|
||||
e instanceof AdvancedCameraCardError
|
||||
? e.message
|
||||
: localize('error.webrtc_card_reported_error') +
|
||||
': ' +
|
||||
(e as Error).message,
|
||||
context: (e as FrigateCardError).context,
|
||||
context: (e as AdvancedCameraCardError).context,
|
||||
};
|
||||
dispatchLiveErrorEvent(this);
|
||||
return;
|
||||
@@ -275,6 +275,6 @@ export class FrigateCardLiveWebRTCCard
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-live-webrtc-card': FrigateCardLiveWebRTCCard;
|
||||
'advanced-camera-card-live-webrtc-card': AdvancedCameraCardLiveWebRTCCard;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import loadingStyle from '../scss/loading.scss';
|
||||
import { getReleaseVersion } from '../utils/diagnostics';
|
||||
import './icon';
|
||||
|
||||
@customElement('frigate-card-loading')
|
||||
export class FrigateCardLoading extends LitElement {
|
||||
@customElement('advanced-camera-card-loading')
|
||||
export class AdvancedCameraCardLoading extends LitElement {
|
||||
protected render(): TemplateResult {
|
||||
return html`<frigate-card-icon .icon=${{ icon: 'iris' }}></frigate-card-icon
|
||||
return html`<advanced-camera-card-icon
|
||||
.icon=${{ icon: 'iris' }}
|
||||
></advanced-camera-card-icon
|
||||
><span>${getReleaseVersion()}</span>`;
|
||||
}
|
||||
|
||||
@@ -18,6 +20,6 @@ export class FrigateCardLoading extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-loading': FrigateCardLoading;
|
||||
'advanced-camera-card-loading': AdvancedCameraCardLoading;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@ import {
|
||||
import { CardWideConfig } from '../config/types';
|
||||
import { localize } from '../localize/localize';
|
||||
import mediaFilterStyle from '../scss/media-filter.scss';
|
||||
import { FrigateCardDatePicker } from './date-picker';
|
||||
import { AdvancedCameraCardDatePicker } from './date-picker';
|
||||
import './date-picker.js';
|
||||
import { FrigateCardSelect } from './select';
|
||||
import { AdvancedCameraCardSelect } from './select';
|
||||
import './select.js';
|
||||
import { ViewManagerEpoch } from '../card-controller/view/types';
|
||||
|
||||
@customElement('frigate-card-media-filter')
|
||||
class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
@customElement('advanced-camera-card-media-filter')
|
||||
class AdvancedCameraCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
@property({ attribute: false })
|
||||
public hass?: HomeAssistant;
|
||||
|
||||
@@ -42,21 +42,21 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
static elementDefinitions = {
|
||||
'frigate-card-select': FrigateCardSelect,
|
||||
'frigate-card-date-picker': FrigateCardDatePicker,
|
||||
'advanced-camera-card-select': AdvancedCameraCardSelect,
|
||||
'advanced-camera-card-date-picker': AdvancedCameraCardDatePicker,
|
||||
};
|
||||
|
||||
protected _mediaFilterController = new MediaFilterController(this);
|
||||
|
||||
protected _refMediaType: Ref<FrigateCardSelect> = createRef();
|
||||
protected _refCamera: Ref<FrigateCardSelect> = createRef();
|
||||
protected _refWhen: Ref<FrigateCardSelect> = createRef();
|
||||
protected _refWhenFrom: Ref<FrigateCardDatePicker> = createRef();
|
||||
protected _refWhenTo: Ref<FrigateCardDatePicker> = createRef();
|
||||
protected _refWhat: Ref<FrigateCardSelect> = createRef();
|
||||
protected _refWhere: Ref<FrigateCardSelect> = createRef();
|
||||
protected _refFavorite: Ref<FrigateCardSelect> = createRef();
|
||||
protected _refTags: Ref<FrigateCardSelect> = createRef();
|
||||
protected _refMediaType: Ref<AdvancedCameraCardSelect> = createRef();
|
||||
protected _refCamera: Ref<AdvancedCameraCardSelect> = createRef();
|
||||
protected _refWhen: Ref<AdvancedCameraCardSelect> = createRef();
|
||||
protected _refWhenFrom: Ref<AdvancedCameraCardDatePicker> = createRef();
|
||||
protected _refWhenTo: Ref<AdvancedCameraCardDatePicker> = createRef();
|
||||
protected _refWhat: Ref<AdvancedCameraCardSelect> = createRef();
|
||||
protected _refWhere: Ref<AdvancedCameraCardSelect> = createRef();
|
||||
protected _refFavorite: Ref<AdvancedCameraCardSelect> = createRef();
|
||||
protected _refTags: Ref<AdvancedCameraCardSelect> = createRef();
|
||||
|
||||
protected willUpdate(changedProps: PropertyValues): void {
|
||||
if (changedProps.has('viewManagerEpoch')) {
|
||||
@@ -132,48 +132,48 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
const tagsOptions = this._mediaFilterController.getTagsOptions();
|
||||
const whereOptions = this._mediaFilterController.getWhereOptions();
|
||||
|
||||
return html` <frigate-card-select
|
||||
return html` <advanced-camera-card-select
|
||||
${ref(this._refMediaType)}
|
||||
label=${localize('media_filter.media_type')}
|
||||
placeholder=${localize('media_filter.select_media_type')}
|
||||
.options=${this._mediaFilterController.getMediaTypeOptions()}
|
||||
.initialValue=${defaults?.mediaType}
|
||||
@frigate-card:select:change=${() => valueChange()}
|
||||
@advanced-camera-card:select:change=${() => valueChange()}
|
||||
>
|
||||
</frigate-card-select>
|
||||
</advanced-camera-card-select>
|
||||
<div class="when">
|
||||
<frigate-card-select
|
||||
<advanced-camera-card-select
|
||||
${ref(this._refWhen)}
|
||||
.label=${localize('media_filter.when')}
|
||||
placeholder=${localize('media_filter.select_when')}
|
||||
.options=${this._mediaFilterController.getWhenOptions()}
|
||||
.initialValue=${defaults?.when}
|
||||
clearable
|
||||
@frigate-card:select:change=${() => whenChange('selected')}
|
||||
@advanced-camera-card:select:change=${() => whenChange('selected')}
|
||||
>
|
||||
</frigate-card-select>
|
||||
<frigate-card-date-picker
|
||||
</advanced-camera-card-select>
|
||||
<advanced-camera-card-date-picker
|
||||
class="${classMap({
|
||||
selected: !!this._refWhenFrom.value?.value,
|
||||
hidden: this._refWhen.value?.value !== MediaFilterCoreWhen.Custom,
|
||||
})}"
|
||||
${ref(this._refWhenFrom)}
|
||||
.icon=${'mdi:calendar-arrow-right'}
|
||||
@frigate-card:date-picker:change=${() => whenChange('custom')}
|
||||
@advanced-camera-card:date-picker:change=${() => whenChange('custom')}
|
||||
>
|
||||
</frigate-card-date-picker>
|
||||
<frigate-card-date-picker
|
||||
</advanced-camera-card-date-picker>
|
||||
<advanced-camera-card-date-picker
|
||||
class="${classMap({
|
||||
selected: !!this._refWhenTo.value?.value,
|
||||
hidden: this._refWhen.value?.value !== MediaFilterCoreWhen.Custom,
|
||||
})}"
|
||||
${ref(this._refWhenTo)}
|
||||
.icon=${'mdi:calendar-arrow-left'}
|
||||
@frigate-card:date-picker:change=${() => whenChange('custom')}
|
||||
@advanced-camera-card:date-picker:change=${() => whenChange('custom')}
|
||||
>
|
||||
</frigate-card-date-picker>
|
||||
</advanced-camera-card-date-picker>
|
||||
</div>
|
||||
<frigate-card-select
|
||||
<advanced-camera-card-select
|
||||
${ref(this._refCamera)}
|
||||
.label=${localize('media_filter.camera')}
|
||||
placeholder=${localize('media_filter.select_camera')}
|
||||
@@ -181,11 +181,11 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
.initialValue=${defaults?.cameraIDs}
|
||||
clearable
|
||||
multiple
|
||||
@frigate-card:select:change=${() => valueChange()}
|
||||
@advanced-camera-card:select:change=${() => valueChange()}
|
||||
>
|
||||
</frigate-card-select>
|
||||
</advanced-camera-card-select>
|
||||
${controls.events && whatOptions.length
|
||||
? html` <frigate-card-select
|
||||
? html` <advanced-camera-card-select
|
||||
${ref(this._refWhat)}
|
||||
label=${localize('media_filter.what')}
|
||||
placeholder=${localize('media_filter.select_what')}
|
||||
@@ -193,12 +193,12 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
multiple
|
||||
.options=${whatOptions}
|
||||
.initialValue=${defaults?.what}
|
||||
@frigate-card:select:change=${() => valueChange()}
|
||||
@advanced-camera-card:select:change=${() => valueChange()}
|
||||
>
|
||||
</frigate-card-select>`
|
||||
</advanced-camera-card-select>`
|
||||
: ''}
|
||||
${controls.events && tagsOptions.length
|
||||
? html` <frigate-card-select
|
||||
? html` <advanced-camera-card-select
|
||||
${ref(this._refTags)}
|
||||
label=${localize('media_filter.tag')}
|
||||
placeholder=${localize('media_filter.select_tag')}
|
||||
@@ -206,12 +206,12 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
multiple
|
||||
.options=${tagsOptions}
|
||||
.initialValue=${defaults?.tags}
|
||||
@frigate-card:select:change=${() => valueChange()}
|
||||
@advanced-camera-card:select:change=${() => valueChange()}
|
||||
>
|
||||
</frigate-card-select>`
|
||||
</advanced-camera-card-select>`
|
||||
: ''}
|
||||
${controls.events && whereOptions.length
|
||||
? html` <frigate-card-select
|
||||
? html` <advanced-camera-card-select
|
||||
${ref(this._refWhere)}
|
||||
label=${localize('media_filter.where')}
|
||||
placeholder=${localize('media_filter.select_where')}
|
||||
@@ -219,22 +219,22 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
multiple
|
||||
.options=${whereOptions}
|
||||
.initialValue=${defaults?.where}
|
||||
@frigate-card:select:change=${() => valueChange()}
|
||||
@advanced-camera-card:select:change=${() => valueChange()}
|
||||
>
|
||||
</frigate-card-select>`
|
||||
</advanced-camera-card-select>`
|
||||
: ''}
|
||||
${controls.favorites
|
||||
? html`
|
||||
<frigate-card-select
|
||||
<advanced-camera-card-select
|
||||
${ref(this._refFavorite)}
|
||||
label=${localize('media_filter.favorite')}
|
||||
placeholder=${localize('media_filter.select_favorite')}
|
||||
.options=${this._mediaFilterController.getFavoriteOptions()}
|
||||
.initialValue=${defaults?.favorite}
|
||||
clearable
|
||||
@frigate-card:select:change=${() => valueChange()}
|
||||
@advanced-camera-card:select:change=${() => valueChange()}
|
||||
>
|
||||
</frigate-card-select>
|
||||
</advanced-camera-card-select>
|
||||
`
|
||||
: ''}`;
|
||||
}
|
||||
@@ -246,6 +246,6 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-media-filter': FrigateCardMediaFilter;
|
||||
'advanced-camera-card-media-filter': AdvancedCameraCardMediaFilter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ import { MediaGridController } from '../components-lib/media-grid-controller.js'
|
||||
import { ViewDisplayConfig } from '../config/types';
|
||||
import mediaGridStyle from '../scss/media-grid.scss';
|
||||
|
||||
@customElement('frigate-card-media-grid')
|
||||
export class FrigateCardMediaGrid extends LitElement {
|
||||
@customElement('advanced-camera-card-media-grid')
|
||||
export class AdvancedCameraCardMediaGrid extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public selected?: string;
|
||||
|
||||
@@ -68,6 +68,6 @@ export class FrigateCardMediaGrid extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-media-grid': FrigateCardMediaGrid;
|
||||
'advanced-camera-card-media-grid': AdvancedCameraCardMediaGrid;
|
||||
}
|
||||
}
|
||||
|
||||
+24
-22
@@ -6,14 +6,14 @@ import { actionHandler } from '../action-handler-directive.js';
|
||||
import { MenuController } from '../components-lib/menu-controller.js';
|
||||
import type { MenuConfig, MenuItem } from '../config/types.js';
|
||||
import menuStyle from '../scss/menu.scss';
|
||||
import { frigateCardHasAction } from '../utils/action.js';
|
||||
import { hasAction } from '../utils/action.js';
|
||||
import { getEntityTitle } from '../utils/ha/index.js';
|
||||
import { EntityRegistryManager } from '../utils/ha/registry/entity/index.js';
|
||||
import './icon.js';
|
||||
import './submenu.js';
|
||||
|
||||
@customElement('frigate-card-menu')
|
||||
export class FrigateCardMenu extends LitElement {
|
||||
@customElement('advanced-camera-card-menu')
|
||||
export class AdvancedCameraCardMenu extends LitElement {
|
||||
protected _controller = new MenuController(this);
|
||||
|
||||
@property({ attribute: false })
|
||||
@@ -43,37 +43,39 @@ export class FrigateCardMenu extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
if (button.type === 'custom:frigate-card-menu-submenu') {
|
||||
return html` <frigate-card-submenu
|
||||
if (button.type === 'custom:advanced-camera-card-menu-submenu') {
|
||||
return html` <advanced-camera-card-submenu
|
||||
.hass=${this.hass}
|
||||
.submenu=${button}
|
||||
@action=${(ev) => this._controller.actionHandler(ev)}
|
||||
>
|
||||
</frigate-card-submenu>`;
|
||||
} else if (button.type === 'custom:frigate-card-menu-submenu-select') {
|
||||
return html` <frigate-card-submenu-select
|
||||
</advanced-camera-card-submenu>`;
|
||||
} else if (button.type === 'custom:advanced-camera-card-menu-submenu-select') {
|
||||
return html` <advanced-camera-card-submenu-select
|
||||
.hass=${this.hass}
|
||||
.submenuSelect=${button}
|
||||
.entityRegistryManager=${this.entityRegistryManager}
|
||||
@action=${(ev) => this._controller.actionHandler(ev)}
|
||||
>
|
||||
</frigate-card-submenu-select>`;
|
||||
</advanced-camera-card-submenu-select>`;
|
||||
}
|
||||
|
||||
const title =
|
||||
this.hass && button.type === 'custom:frigate-card-menu-state-icon' && !button.title
|
||||
this.hass &&
|
||||
button.type === 'custom:advanced-camera-card-menu-state-icon' &&
|
||||
!button.title
|
||||
? getEntityTitle(this.hass, button.entity)
|
||||
: button.title;
|
||||
|
||||
return html` <ha-icon-button
|
||||
.actionHandler=${actionHandler({
|
||||
hasHold: frigateCardHasAction(button.hold_action),
|
||||
hasDoubleClick: frigateCardHasAction(button.double_tap_action),
|
||||
hasHold: hasAction(button.hold_action),
|
||||
hasDoubleClick: hasAction(button.double_tap_action),
|
||||
})}
|
||||
.label=${title ?? ''}
|
||||
@action=${(ev) => this._controller.actionHandler(ev, button)}
|
||||
>
|
||||
<frigate-card-icon
|
||||
<advanced-camera-card-icon
|
||||
?allow-override-non-active-styles=${true}
|
||||
style="${styleMap(button.style || {})}"
|
||||
.hass=${this.hass}
|
||||
@@ -83,7 +85,7 @@ export class FrigateCardMenu extends LitElement {
|
||||
stateColor: button.state_color,
|
||||
fallback: 'mdi:gesture-tap-button',
|
||||
}}
|
||||
></frigate-card-icon>
|
||||
></advanced-camera-card-icon>
|
||||
</ha-icon-button>`;
|
||||
}
|
||||
|
||||
@@ -108,13 +110,13 @@ export class FrigateCardMenu extends LitElement {
|
||||
|
||||
const generateValue = (suffix: string): string => {
|
||||
return `
|
||||
var(--frigate-card-menu-override-${suffix},
|
||||
var(--frigate-card-menu-position-${position}-alignment-${alignment}-style-${style}-${suffix},
|
||||
var(--frigate-card-menu-position-${position}-alignment-${alignment}-${suffix},
|
||||
var(--frigate-card-menu-position-${position}-${suffix},
|
||||
var(--frigate-card-menu-style-${style}-${suffix},
|
||||
var(--frigate-card-menu-alignment-${alignment}-${suffix},
|
||||
var(--frigate-card-menu-${suffix})))))))`;
|
||||
var(--advanced-camera-card-menu-override-${suffix},
|
||||
var(--advanced-camera-card-menu-position-${position}-alignment-${alignment}-style-${style}-${suffix},
|
||||
var(--advanced-camera-card-menu-position-${position}-alignment-${alignment}-${suffix},
|
||||
var(--advanced-camera-card-menu-position-${position}-${suffix},
|
||||
var(--advanced-camera-card-menu-style-${style}-${suffix},
|
||||
var(--advanced-camera-card-menu-alignment-${alignment}-${suffix},
|
||||
var(--advanced-camera-card-menu-${suffix})))))))`;
|
||||
};
|
||||
|
||||
// By definition `rule` will match the current configuration, the choice is
|
||||
@@ -169,6 +171,6 @@ export class FrigateCardMenu extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-menu': FrigateCardMenu;
|
||||
'advanced-camera-card-menu': AdvancedCameraCardMenu;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@ export function renderMessage(
|
||||
overlay?: boolean;
|
||||
},
|
||||
): TemplateResult {
|
||||
return html` <frigate-card-message
|
||||
return html` <advanced-camera-card-message
|
||||
.message=${message}
|
||||
?overlay=${!!renderOptions?.overlay}
|
||||
></frigate-card-message>`;
|
||||
></advanced-camera-card-message>`;
|
||||
}
|
||||
@customElement('frigate-card-message')
|
||||
export class FrigateCardMessage extends LitElement {
|
||||
@customElement('advanced-camera-card-message')
|
||||
export class AdvancedCameraCardMessage extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public message?: Message;
|
||||
|
||||
@@ -51,7 +51,9 @@ export class FrigateCardMessage extends LitElement {
|
||||
return html` <div class="wrapper">
|
||||
<div class="message padded">
|
||||
<div class="icon">
|
||||
<frigate-card-icon .icon="${{ icon: icon }}"></frigate-card-icon>
|
||||
<advanced-camera-card-icon
|
||||
.icon="${{ icon: icon }}"
|
||||
></advanced-camera-card-icon>
|
||||
</div>
|
||||
<div class="contents">
|
||||
<span class="${classMap(classes)}">${messageTemplate}</span>
|
||||
@@ -70,6 +72,6 @@ export class FrigateCardMessage extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-message': FrigateCardMessage;
|
||||
'advanced-camera-card-message': AdvancedCameraCardMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,17 @@ import { Icon } from '../types.js';
|
||||
import { renderTask } from '../utils/task.js';
|
||||
import { createFetchThumbnailTask } from '../utils/thumbnail.js';
|
||||
|
||||
@customElement('frigate-card-next-previous-control')
|
||||
export class FrigateCardNextPreviousControl extends LitElement {
|
||||
@customElement('advanced-camera-card-next-previous-control')
|
||||
export class AdvancedCameraCardNextPreviousControl extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public side?: 'left' | 'right';
|
||||
|
||||
set controlConfig(controlConfig: NextPreviousControlConfig | undefined) {
|
||||
if (controlConfig?.size) {
|
||||
this.style.setProperty('--frigate-card-next-prev-size', `${controlConfig.size}px`);
|
||||
this.style.setProperty(
|
||||
'--advanced-camera-card-next-prev-size',
|
||||
`${controlConfig.size}px`,
|
||||
);
|
||||
}
|
||||
this._controlConfig = controlConfig;
|
||||
}
|
||||
@@ -74,7 +77,10 @@ export class FrigateCardNextPreviousControl extends LitElement {
|
||||
: { icon: 'mdi:chevron-right' };
|
||||
|
||||
return html` <ha-icon-button class="${classMap(classes)}" .label=${this.label}>
|
||||
<frigate-card-icon .hass=${this.hass} .icon=${icon}></frigate-card-icon>
|
||||
<advanced-camera-card-icon
|
||||
.hass=${this.hass}
|
||||
.icon=${icon}
|
||||
></advanced-camera-card-icon>
|
||||
</ha-icon-button>`;
|
||||
}
|
||||
|
||||
@@ -106,6 +112,6 @@ export class FrigateCardNextPreviousControl extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-next-previous-control': FrigateCardNextPreviousControl;
|
||||
'advanced-camera-card-next-previous-control': AdvancedCameraCardNextPreviousControl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import overlayStyle from '../scss/overlay.scss';
|
||||
|
||||
@customElement('frigate-card-overlay')
|
||||
export class FrigateCardOverlay extends LitElement {
|
||||
@customElement('advanced-camera-card-overlay')
|
||||
export class AdvancedCameraCardOverlay extends LitElement {
|
||||
protected render(): TemplateResult | void {
|
||||
return html`
|
||||
<slot name="top"></slot>
|
||||
@@ -20,6 +20,6 @@ export class FrigateCardOverlay extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'frigate-card-overlay': FrigateCardOverlay;
|
||||
'advanced-camera-card-overlay': AdvancedCameraCardOverlay;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user