refactor: Retire the use of unmaintained custom-card-helpers (#1956)

- Closes #1295
This commit is contained in:
Dermot Duffy
2025-03-09 16:02:33 -07:00
committed by GitHub
parent c65ee3f0f2
commit a79ffa6edc
116 changed files with 933 additions and 545 deletions
-1
View File
@@ -19,7 +19,6 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@cycjimmy/jsmpeg-player": "^6.0.5", "@cycjimmy/jsmpeg-player": "^6.0.5",
"@dermotduffy/custom-card-helpers": "^1.9.1",
"@dermotduffy/panzoom": "^4.5.1", "@dermotduffy/panzoom": "^4.5.1",
"@egjs/hammerjs": "^2.0.17", "@egjs/hammerjs": "^2.0.17",
"@graphiteds/core": "^1.9.21", "@graphiteds/core": "^1.9.21",
+8 -11
View File
@@ -1,8 +1,3 @@
import type {
ActionHandlerDetail,
ActionHandlerOptions,
} from '@dermotduffy/custom-card-helpers';
import { fireEvent } from '@dermotduffy/custom-card-helpers';
import { noChange } from 'lit'; import { noChange } from 'lit';
import { import {
AttributePart, AttributePart,
@@ -10,6 +5,8 @@ import {
DirectiveParameters, DirectiveParameters,
directive, directive,
} from 'lit/directive.js'; } from 'lit/directive.js';
import { fireHASSEvent } from './ha/fire-hass-event.js';
import { ActionHandlerDetail, ActionHandlerOptions } from './ha/types.js';
import { stopEventFromActivatingCardWideActions } from './utils/action.js'; import { stopEventFromActivatingCardWideActions } from './utils/action.js';
import { Timer } from './utils/timer.js'; import { Timer } from './utils/timer.js';
@@ -88,7 +85,7 @@ class ActionHandler extends HTMLElement implements ActionHandlerInterface {
// mousedown events (on Android). // mousedown events (on Android).
if (!this.started) { if (!this.started) {
this.started = true; this.started = true;
fireEvent(element, 'action', { action: 'start_tap' }); fireHASSEvent(element, 'action', { action: 'start_tap' });
} }
}; };
@@ -98,7 +95,7 @@ class ActionHandler extends HTMLElement implements ActionHandlerInterface {
if (this.started) { if (this.started) {
this.started = false; this.started = false;
fireEvent(element, 'action', { action: 'end_tap' }); fireHASSEvent(element, 'action', { action: 'end_tap' });
} }
}; };
@@ -122,21 +119,21 @@ class ActionHandler extends HTMLElement implements ActionHandlerInterface {
endTap(ev); endTap(ev);
if (options?.hasHold && this.held) { if (options?.hasHold && this.held) {
fireEvent(element, 'action', { action: 'hold' }); fireHASSEvent(element, 'action', { action: 'hold' });
} else if (options?.hasDoubleClick) { } else if (options?.hasDoubleClick) {
if ( if (
(ev.type === 'click' && (ev as MouseEvent).detail < 2) || (ev.type === 'click' && (ev as MouseEvent).detail < 2) ||
!this.doubleClickTimer.isRunning() !this.doubleClickTimer.isRunning()
) { ) {
this.doubleClickTimer.start(0.25, () => this.doubleClickTimer.start(0.25, () =>
fireEvent(element, 'action', { action: 'tap' }), fireHASSEvent(element, 'action', { action: 'tap' }),
); );
} else { } else {
this.doubleClickTimer.stop(); this.doubleClickTimer.stop();
fireEvent(element, 'action', { action: 'double_tap' }); fireHASSEvent(element, 'action', { action: 'double_tap' });
} }
} else { } else {
fireEvent(element, 'action', { action: 'tap' }); fireHASSEvent(element, 'action', { action: 'tap' });
} }
}; };
+1 -1
View File
@@ -1,4 +1,4 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { EntityRegistryManager } from '../../utils/ha/registry/entity'; import { EntityRegistryManager } from '../../utils/ha/registry/entity';
import { Entity } from '../../utils/ha/registry/entity/types'; import { Entity } from '../../utils/ha/registry/entity/types';
@@ -1,6 +1,6 @@
import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher'; import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher';
import { CameraConfig } from '../../config/types'; import { CameraConfig } from '../../config/types';
import { ExtendedHomeAssistant } from '../../types'; import { HomeAssistant } from '../../ha/types';
import { canonicalizeHAURL } from '../../utils/ha'; import { canonicalizeHAURL } from '../../utils/ha';
import { BrowseMediaManager } from '../../utils/ha/browse-media/browse-media-manager'; import { BrowseMediaManager } from '../../utils/ha/browse-media/browse-media-manager';
import { BROWSE_MEDIA_CACHE_SECONDS } from '../../utils/ha/browse-media/types'; import { BROWSE_MEDIA_CACHE_SECONDS } from '../../utils/ha/browse-media/types';
@@ -63,7 +63,7 @@ export class BrowseMediaCameraManagerEngine
} }
public async getMediaDownloadPath( public async getMediaDownloadPath(
hass: ExtendedHomeAssistant, hass: HomeAssistant,
_cameraConfig: CameraConfig, _cameraConfig: CameraConfig,
media: ViewMedia, media: ViewMedia,
): Promise<CameraEndpoint | null> { ): Promise<CameraEndpoint | null> {
+1 -1
View File
@@ -1,6 +1,6 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { StateWatcherSubscriptionInterface } from '../card-controller/hass/state-watcher'; import { StateWatcherSubscriptionInterface } from '../card-controller/hass/state-watcher';
import { CameraConfig } from '../config/types'; import { CameraConfig } from '../config/types';
import { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import { BrowseMediaManager } from '../utils/ha/browse-media/browse-media-manager'; import { BrowseMediaManager } from '../utils/ha/browse-media/browse-media-manager';
import { EntityRegistryManager } from '../utils/ha/registry/entity'; import { EntityRegistryManager } from '../utils/ha/registry/entity';
+2 -3
View File
@@ -1,7 +1,6 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { PTZAction } from '../config/ptz'; import { PTZAction } from '../config/ptz';
import { ActionPhase, CameraConfig } from '../config/types'; import { ActionPhase, CameraConfig } from '../config/types';
import { ExtendedHomeAssistant } from '../types'; import { HomeAssistant } from '../ha/types';
import { ViewMedia } from '../view/media'; import { ViewMedia } from '../view/media';
import { Camera } from './camera'; import { Camera } from './camera';
import { CameraManagerReadOnlyConfigStore } from './store'; import { CameraManagerReadOnlyConfigStore } from './store';
@@ -89,7 +88,7 @@ export interface CameraManagerEngine {
): ViewMedia[] | null; ): ViewMedia[] | null;
getMediaDownloadPath( getMediaDownloadPath(
hass: ExtendedHomeAssistant, hass: HomeAssistant,
cameraConfig: CameraConfig, cameraConfig: CameraConfig,
media: ViewMedia, media: ViewMedia,
): Promise<CameraEndpoint | null>; ): Promise<CameraEndpoint | null>;
+1 -1
View File
@@ -1,7 +1,7 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import uniq from 'lodash-es/uniq'; import uniq from 'lodash-es/uniq';
import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher'; import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher';
import { CameraConfig } from '../../config/types'; import { CameraConfig } from '../../config/types';
import { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { PTZCapabilities, PTZMovementType } from '../../types'; import { PTZCapabilities, PTZMovementType } from '../../types';
import { errorToConsole } from '../../utils/basic'; import { errorToConsole } from '../../utils/basic';
+2 -3
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { add, endOfHour, format, fromUnixTime, startOfHour } from 'date-fns'; import { add, endOfHour, format, fromUnixTime, startOfHour } from 'date-fns';
import isEqual from 'lodash-es/isEqual'; import isEqual from 'lodash-es/isEqual';
import orderBy from 'lodash-es/orderBy'; import orderBy from 'lodash-es/orderBy';
@@ -7,7 +6,7 @@ import uniqWith from 'lodash-es/uniqWith';
import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher'; import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher';
import { PTZAction } from '../../config/ptz'; import { PTZAction } from '../../config/ptz';
import { ActionPhase, CameraConfig } from '../../config/types'; import { ActionPhase, CameraConfig } from '../../config/types';
import { ExtendedHomeAssistant } from '../../types'; import { HomeAssistant } from '../../ha/types';
import { import {
allPromises, allPromises,
formatDate, formatDate,
@@ -157,7 +156,7 @@ export class FrigateCameraManagerEngine
} }
public async getMediaDownloadPath( public async getMediaDownloadPath(
_hass: ExtendedHomeAssistant, _hass: HomeAssistant,
cameraConfig: CameraConfig, cameraConfig: CameraConfig,
media: ViewMedia, media: ViewMedia,
): Promise<CameraEndpoint | null> { ): Promise<CameraEndpoint | null> {
+1 -1
View File
@@ -1,4 +1,4 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../ha/types';
import { FrigateEventChange, frigateEventChangeSchema } from './types'; import { FrigateEventChange, frigateEventChangeSchema } from './types';
export interface FrigateEventWatcherRequest { export interface FrigateEventWatcherRequest {
+1 -1
View File
@@ -1,4 +1,4 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { AdvancedCameraCardError } from '../../types'; import { AdvancedCameraCardError } from '../../types';
import { homeAssistantWSRequest } from '../../utils/ha/ws-request'; import { homeAssistantWSRequest } from '../../utils/ha/ws-request';
+2 -3
View File
@@ -1,10 +1,9 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher'; import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/state-watcher';
import { PTZAction } from '../../config/ptz'; import { PTZAction } from '../../config/ptz';
import { ActionPhase, CameraConfig } from '../../config/types'; import { ActionPhase, CameraConfig } from '../../config/types';
import { ExtendedHomeAssistant } from '../../types'; import { HomeAssistant } from '../../ha/types';
import { getEntityTitle } from '../../utils/ha'; import { getEntityTitle } from '../../utils/ha';
import { ViewMedia } from '../../view/media'; import { ViewMedia } from '../../view/media';
import { Camera } from '../camera'; import { Camera } from '../camera';
@@ -153,7 +152,7 @@ export class GenericCameraManagerEngine implements CameraManagerEngine {
} }
public async getMediaDownloadPath( public async getMediaDownloadPath(
_hass: ExtendedHomeAssistant, _hass: HomeAssistant,
_cameraConfig: CameraConfig, _cameraConfig: CameraConfig,
_media: ViewMedia, _media: ViewMedia,
): Promise<CameraEndpoint | null> { ): Promise<CameraEndpoint | null> {
@@ -1,7 +1,7 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { add, endOfDay, parse, startOfDay } from 'date-fns'; import { add, endOfDay, parse, startOfDay } from 'date-fns';
import orderBy from 'lodash-es/orderBy'; import orderBy from 'lodash-es/orderBy';
import { CameraConfig } from '../../config/types'; import { CameraConfig } from '../../config/types';
import { HomeAssistant } from '../../ha/types';
import { allPromises, formatDate, isValidDate } from '../../utils/basic'; import { allPromises, formatDate, isValidDate } from '../../utils/basic';
import { import {
BrowseMediaStep, BrowseMediaStep,
+1 -1
View File
@@ -1,4 +1,4 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { EntityRegistryManager } from '../../utils/ha/registry/entity'; import { EntityRegistryManager } from '../../utils/ha/registry/entity';
import { BrowseMediaCamera } from '../browse-media/camera'; import { BrowseMediaCamera } from '../browse-media/camera';
+1 -1
View File
@@ -1,7 +1,7 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { add, endOfDay, parse, startOfDay } from 'date-fns'; import { add, endOfDay, parse, startOfDay } from 'date-fns';
import { orderBy } from 'lodash-es'; import { orderBy } from 'lodash-es';
import { CameraConfig } from '../../config/types'; import { CameraConfig } from '../../config/types';
import { HomeAssistant } from '../../ha/types';
import { allPromises, formatDate, isValidDate } from '../../utils/basic'; import { allPromises, formatDate, isValidDate } from '../../utils/basic';
import { sortMediaByStartDate } from '../../utils/ha/browse-media/browse-media-manager'; import { sortMediaByStartDate } from '../../utils/ha/browse-media/browse-media-manager';
import { import {
@@ -87,7 +87,8 @@ export class ActionsManager {
*/ */
public handleCustomActionEvent = (ev: Event): void => { public handleCustomActionEvent = (ev: Event): void => {
if (!('detail' in ev)) { if (!('detail' in ev)) {
// The event may not be a CustomEvent object, see: // The event may or may not be a CustomEvent object. For example, whilst
// this card doesn't use custom-card-helpers, embedded elements may:
// https://github.com/custom-cards/custom-card-helpers/blob/master/src/fire-event.ts#L70 // https://github.com/custom-cards/custom-card-helpers/blob/master/src/fire-event.ts#L70
return; return;
} }
@@ -1,4 +1,5 @@
import { ActionConfig, handleActionConfig } from '@dermotduffy/custom-card-helpers'; import { handleActionConfig } from '../../../ha/handle-action';
import { ActionConfig } from '../../../ha/types';
import { CardActionsAPI } from '../../types'; import { CardActionsAPI } from '../../types';
import { BaseAction } from './base'; import { BaseAction } from './base';
+1 -1
View File
@@ -1,6 +1,6 @@
import { ActionConfig } from '@dermotduffy/custom-card-helpers';
import { ActionContext } from 'action'; import { ActionContext } from 'action';
import { ActionType, INTERNAL_CALLBACK_ACTION } from '../../config/types'; import { ActionType, INTERNAL_CALLBACK_ACTION } from '../../config/types';
import { ActionConfig } from '../../ha/types';
import { convertActionToCardCustomAction } from '../../utils/action'; import { convertActionToCardCustomAction } from '../../utils/action';
import { CameraSelectAction } from './actions/camera-select'; import { CameraSelectAction } from './actions/camera-select';
import { CameraUIAction } from './actions/camera-ui'; import { CameraUIAction } from './actions/camera-ui';
@@ -1,11 +1,11 @@
import { dispatchAdvancedCameraCardEvent } from '../../../utils/basic'; import { fireAdvancedCameraCardEvent } from '../../../utils/fire-advanced-camera-card-event';
import { ActionExecutionRequest } from '../types'; import { ActionExecutionRequest } from '../types';
export const dispatchActionExecutionRequest = ( export const dispatchActionExecutionRequest = (
element: HTMLElement, element: HTMLElement,
request: ActionExecutionRequest, request: ActionExecutionRequest,
) => { ) => {
dispatchAdvancedCameraCardEvent(element, 'action:execution-request', request); fireAdvancedCameraCardEvent(element, 'action:execution-request', request);
}; };
export interface ActionExecutionRequestEventTarget extends EventTarget { export interface ActionExecutionRequestEventTarget extends EventTarget {
+1 -1
View File
@@ -1,8 +1,8 @@
import { LovelaceCardEditor } from '@dermotduffy/custom-card-helpers';
import { ReactiveController } from 'lit'; import { ReactiveController } from 'lit';
import { CameraManager } from '../camera-manager/manager'; import { CameraManager } from '../camera-manager/manager';
import { ConditionStateManager } from '../conditions/state-manager'; import { ConditionStateManager } from '../conditions/state-manager';
import { AdvancedCameraCardConfig } from '../config/types'; import { AdvancedCameraCardConfig } from '../config/types';
import { LovelaceCardEditor } from '../ha/types';
import { import {
createDeviceRegistryCache, createDeviceRegistryCache,
DeviceRegistryManager, DeviceRegistryManager,
+4 -4
View File
@@ -1,11 +1,11 @@
import { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { ExtendedHomeAssistant } from '../../types';
import { hasHAConnectionStateChanged } from '../../utils/ha'; import { hasHAConnectionStateChanged } from '../../utils/ha';
import { CardHASSAPI } from '../types'; import { CardHASSAPI } from '../types';
import { StateWatcher, StateWatcherSubscriptionInterface } from './state-watcher'; import { StateWatcher, StateWatcherSubscriptionInterface } from './state-watcher';
export class HASSManager { export class HASSManager {
protected _hass: ExtendedHomeAssistant | null = null; protected _hass: HomeAssistant | null = null;
protected _api: CardHASSAPI; protected _api: CardHASSAPI;
protected _stateWatcher: StateWatcher = new StateWatcher(); protected _stateWatcher: StateWatcher = new StateWatcher();
@@ -13,7 +13,7 @@ export class HASSManager {
this._api = api; this._api = api;
} }
public getHASS(): ExtendedHomeAssistant | null { public getHASS(): HomeAssistant | null {
return this._hass; return this._hass;
} }
@@ -25,7 +25,7 @@ export class HASSManager {
return this._stateWatcher; return this._stateWatcher;
} }
public setHASS(hass?: ExtendedHomeAssistant | null): void { public setHASS(hass?: HomeAssistant | null): void {
if (hasHAConnectionStateChanged(this._hass, hass)) { if (hasHAConnectionStateChanged(this._hass, hass)) {
if (!hass?.connected) { if (!hass?.connected) {
this._api.getMessageManager().setMessageIfHigherPriority({ this._api.getMessageManager().setMessageIfHigherPriority({
+1 -1
View File
@@ -1,4 +1,4 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../ha/types';
import { getHassDifferences, HassStateDifference } from '../../utils/ha'; import { getHassDifferences, HassStateDifference } from '../../utils/ha';
type StateWatcherCallback = (difference: HassStateDifference) => void; type StateWatcherCallback = (difference: HassStateDifference) => void;
+2 -2
View File
@@ -1,7 +1,7 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { HASS, renderTemplate } from 'ha-nunjucks/dist'; import { HASS, renderTemplate } from 'ha-nunjucks/dist';
import { ConditionsTriggerData, ConditionState } from '../../conditions/types'; import { ConditionState, ConditionsTriggerData } from '../../conditions/types';
import { ActionType } from '../../config/types'; import { ActionType } from '../../config/types';
import { HomeAssistant } from '../../ha/types';
interface TemplateContextInternal { interface TemplateContextInternal {
camera?: string; camera?: string;
+4 -4
View File
@@ -1,4 +1,3 @@
import { HomeAssistant, LovelaceCardEditor } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit'; import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
import { customElement } from 'lit/decorators.js'; import { customElement } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
@@ -30,9 +29,10 @@ import {
StatusBarItem, StatusBarItem,
} from './config/types'; } from './config/types';
import { REPO_URL } from './const.js'; import { REPO_URL } from './const.js';
import { HomeAssistant, LovelaceCardEditor } from './ha/types.js';
import { localize } from './localize/localize.js'; import { localize } from './localize/localize.js';
import cardStyle from './scss/card.scss'; import cardStyle from './scss/card.scss';
import { ExtendedHomeAssistant, MediaLoadedInfo, Message } from './types.js'; import { MediaLoadedInfo, Message } from './types.js';
import { hasAction } from './utils/action.js'; import { hasAction } from './utils/action.js';
import { getReleaseVersion } from './utils/diagnostics'; import { getReleaseVersion } from './utils/diagnostics';
@@ -110,11 +110,11 @@ class AdvancedCameraCard extends LitElement {
return this._controller.getConfigManager().getConfig(); return this._controller.getConfigManager().getConfig();
} }
get _hass(): ExtendedHomeAssistant | null { get _hass(): HomeAssistant | null {
return this._controller.getHASSManager().getHASS(); return this._controller.getHASSManager().getHASS();
} }
set hass(hass: ExtendedHomeAssistant) { set hass(hass: HomeAssistant) {
this._controller.getHASSManager().setHASS(hass); this._controller.getHASSManager().setHASS(hass);
// Manually set hass in the menu, elements and image. This is to allow these // Manually set hass in the menu, elements and image. This is to allow these
+1 -1
View File
@@ -1,8 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { HassEntity } from 'home-assistant-js-websocket'; import { HassEntity } from 'home-assistant-js-websocket';
import frigateSVG from '../camera-manager/frigate/assets/frigate.svg'; import frigateSVG from '../camera-manager/frigate/assets/frigate.svg';
import motioneyeSVG from '../camera-manager/motioneye/assets/motioneye.svg'; import motioneyeSVG from '../camera-manager/motioneye/assets/motioneye.svg';
import reolinkSVG from '../camera-manager/reolink/assets/reolink.svg'; import reolinkSVG from '../camera-manager/reolink/assets/reolink.svg';
import { HomeAssistant } from '../ha/types';
import irisSVG from '../images/iris.svg'; import irisSVG from '../images/iris.svg';
import { Icon } from '../types'; import { Icon } from '../types';
@@ -1,5 +1,5 @@
import { dispatchAdvancedCameraCardEvent } from '../../../utils/basic'; import { fireAdvancedCameraCardEvent } from '../../../utils/fire-advanced-camera-card-event';
export function dispatchLiveErrorEvent(element: EventTarget): void { export function dispatchLiveErrorEvent(element: EventTarget): void {
dispatchAdvancedCameraCardEvent(element, 'live:error'); fireAdvancedCameraCardEvent(element, 'live:error');
} }
+4 -7
View File
@@ -3,11 +3,8 @@ import throttle from 'lodash-es/throttle';
import Masonry from 'masonry-layout'; import Masonry from 'masonry-layout';
import { ViewDisplayConfig } from '../config/types'; import { ViewDisplayConfig } from '../config/types';
import { MediaLoadedInfo } from '../types'; import { MediaLoadedInfo } from '../types';
import { import { getChildrenFromElement, setOrRemoveAttribute } from '../utils/basic';
dispatchAdvancedCameraCardEvent, import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event';
getChildrenFromElement,
setOrRemoveAttribute,
} from '../utils/basic';
import { import {
AdvancedCameraCardMediaLoadedEventTarget, AdvancedCameraCardMediaLoadedEventTarget,
dispatchExistingMediaLoadedInfoAsEvent, dispatchExistingMediaLoadedInfoAsEvent,
@@ -137,7 +134,7 @@ export class MediaGridController {
} }
this._selected = id; this._selected = id;
dispatchAdvancedCameraCardEvent(this._host, 'media-grid:selected', { selected: id }); fireAdvancedCameraCardEvent(this._host, 'media-grid:selected', { selected: id });
const mediaLoadedInfo = this._mediaLoadedInfoMap.get(id); const mediaLoadedInfo = this._mediaLoadedInfoMap.get(id);
if (mediaLoadedInfo) { if (mediaLoadedInfo) {
@@ -155,7 +152,7 @@ export class MediaGridController {
public unselectAll() { public unselectAll() {
if (this._selected !== null) { if (this._selected !== null) {
dispatchMediaUnloadedEvent(this._host); dispatchMediaUnloadedEvent(this._host);
dispatchAdvancedCameraCardEvent(this._host, 'media-grid:unselected'); fireAdvancedCameraCardEvent(this._host, 'media-grid:unselected');
} }
this._selected = null; this._selected = null;
this._updateSelectedStylesOnElements(); this._updateSelectedStylesOnElements();
+1 -1
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { StyleInfo } from 'lit/directives/style-map'; import { StyleInfo } from 'lit/directives/style-map';
import { CameraManager } from '../camera-manager/manager'; import { CameraManager } from '../camera-manager/manager';
import { FullscreenManager } from '../card-controller/fullscreen/fullscreen-manager'; import { FullscreenManager } from '../card-controller/fullscreen/fullscreen-manager';
@@ -11,6 +10,7 @@ import {
MenuItem, MenuItem,
VIEWS_USER_SPECIFIED, VIEWS_USER_SPECIFIED,
} from '../config/types'; } from '../config/types';
import { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import { MediaLoadedInfo } from '../types'; import { MediaLoadedInfo } from '../types';
import { import {
+2 -2
View File
@@ -1,5 +1,5 @@
import { AdvancedCameraCardError, Message } from '../../types'; import { AdvancedCameraCardError, Message } from '../../types';
import { dispatchAdvancedCameraCardEvent } from '../../utils/basic'; import { fireAdvancedCameraCardEvent } from '../../utils/fire-advanced-camera-card-event';
// Facilitates correct typing of event handlers. // Facilitates correct typing of event handlers.
export interface AdvancedCameraCardMessageEventTarget extends EventTarget { export interface AdvancedCameraCardMessageEventTarget extends EventTarget {
@@ -44,7 +44,7 @@ export const dispatchAdvancedCameraCardErrorEvent = (
error: unknown, error: unknown,
): void => { ): void => {
if (error instanceof Error) { if (error instanceof Error) {
dispatchAdvancedCameraCardEvent<Message>(element, 'message', { fireAdvancedCameraCardEvent<Message>(element, 'message', {
message: error.message, message: error.message,
type: 'error', type: 'error',
...(error instanceof AdvancedCameraCardError && { context: error.context }), ...(error instanceof AdvancedCameraCardError && { context: error.context }),
+8 -8
View File
@@ -1,11 +1,11 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { CameraManager } from '../../camera-manager/manager.js';
import { CameraManager } from '../../camera-manager/manager'; import { dispatchActionExecutionRequest } from '../../card-controller/actions/utils/execution-request.js';
import { dispatchActionExecutionRequest } from '../../card-controller/actions/utils/execution-request'; import { SubmenuInteraction } from '../../components/submenu/types.js';
import { PTZAction } from '../../config/ptz'; import { PTZAction } from '../../config/ptz.js';
import { Actions, ActionsConfig, PTZControlsConfig } from '../../config/types'; import { Actions, ActionsConfig, PTZControlsConfig } from '../../config/types.js';
import { Interaction } from '../../types'; import { HomeAssistant } from '../../ha/types.js';
import { createPTZMultiAction, getActionConfigGivenAction } from '../../utils/action'; import { Interaction } from '../../types.js';
import { SubmenuInteraction } from '../../components/submenu/types'; import { createPTZMultiAction, getActionConfigGivenAction } from '../../utils/action.js';
import { PTZControllerActions } from './types'; import { PTZControllerActions } from './types';
export class PTZController { export class PTZController {
+1 -2
View File
@@ -1,4 +1,3 @@
import { HASSDomEvent } from '@dermotduffy/custom-card-helpers';
import { LitElement } from 'lit'; import { LitElement } from 'lit';
import isEqual from 'lodash-es/isEqual'; import isEqual from 'lodash-es/isEqual';
import orderBy from 'lodash-es/orderBy'; import orderBy from 'lodash-es/orderBy';
@@ -76,7 +75,7 @@ export class StatusBarController {
} }
public actionHandler( public actionHandler(
ev: HASSDomEvent<{ action: string; config?: ActionsConfig }>, ev: CustomEvent<{ action: string; config?: ActionsConfig }>,
config?: ActionsConfig, config?: ActionsConfig,
): void { ): void {
// These interactions should only be handled by the status bar, as nothing // These interactions should only be handled by the status bar, as nothing
+6 -9
View File
@@ -1,11 +1,8 @@
import Panzoom, { PanzoomEventDetail, PanzoomObject } from '@dermotduffy/panzoom'; import Panzoom, { PanzoomEventDetail, PanzoomObject } from '@dermotduffy/panzoom';
import round from 'lodash-es/round'; import round from 'lodash-es/round';
import throttle from 'lodash-es/throttle'; import throttle from 'lodash-es/throttle';
import { import { arefloatsApproximatelyEqual, isHoverableDevice } from '../../utils/basic';
arefloatsApproximatelyEqual, import { fireAdvancedCameraCardEvent } from '../../utils/fire-advanced-camera-card-event';
dispatchAdvancedCameraCardEvent,
isHoverableDevice,
} from '../../utils/basic';
import { import {
PartialZoomSettings, PartialZoomSettings,
ZOOM_DEFAULT_PAN_X, ZOOM_DEFAULT_PAN_X,
@@ -76,7 +73,7 @@ export class ZoomController {
// Even though the click is stopped,the card still needs to gain focus so // 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 // that keyboard shortcuts will work immediately after the card is clicked
// upon. // upon.
dispatchAdvancedCameraCardEvent(this._element, 'focus'); fireAdvancedCameraCardEvent(this._element, 'focus');
} }
this._allowClick = true; this._allowClick = true;
}; };
@@ -211,11 +208,11 @@ export class ZoomController {
if (unzoomed && this._zoomed) { if (unzoomed && this._zoomed) {
this._zoomed = false; this._zoomed = false;
this._setTouchAction(true); this._setTouchAction(true);
dispatchAdvancedCameraCardEvent(this._element, 'zoom:unzoomed'); fireAdvancedCameraCardEvent(this._element, 'zoom:unzoomed');
} else if (!unzoomed && !this._zoomed) { } else if (!unzoomed && !this._zoomed) {
this._zoomed = true; this._zoomed = true;
this._setTouchAction(false); this._setTouchAction(false);
dispatchAdvancedCameraCardEvent(this._element, 'zoom:zoomed'); fireAdvancedCameraCardEvent(this._element, 'zoom:zoomed');
} }
const converted = this._convertXYPanToPercent(pz.x, pz.y, pz.scale); const converted = this._convertXYPanToPercent(pz.x, pz.y, pz.scale);
@@ -229,7 +226,7 @@ export class ZoomController {
unzoomed: unzoomed, unzoomed: unzoomed,
}; };
dispatchAdvancedCameraCardEvent(this._element, 'zoom:change', observed); fireAdvancedCameraCardEvent(this._element, 'zoom:change', observed);
} }
protected _isZoomEqual(a: PartialZoomSettings, b: PartialZoomSettings): boolean { protected _isZoomEqual(a: PartialZoomSettings, b: PartialZoomSettings): boolean {
+2 -2
View File
@@ -4,7 +4,7 @@ import { createRef, ref, Ref } from 'lit/directives/ref.js';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import datePickerStyle from '../scss/date-picker.scss'; import datePickerStyle from '../scss/date-picker.scss';
import { stopEventFromActivatingCardWideActions } from '../utils/action'; import { stopEventFromActivatingCardWideActions } from '../utils/action';
import { dispatchAdvancedCameraCardEvent } from '../utils/basic'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event';
import './icon'; import './icon';
export interface DatePickerEvent { export interface DatePickerEvent {
@@ -32,7 +32,7 @@ export class AdvancedCameraCardDatePicker extends LitElement {
const changed = () => { const changed = () => {
const value = this._refInput.value?.value; const value = this._refInput.value?.value;
dispatchAdvancedCameraCardEvent<DatePickerEvent>(this, 'date-picker:change', { fireAdvancedCameraCardEvent<DatePickerEvent>(this, 'date-picker:change', {
date: value ? new Date(value) : null, date: value ? new Date(value) : null,
}); });
}; };
+1 -1
View File
@@ -1,8 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { until } from 'lit/directives/until.js'; import { until } from 'lit/directives/until.js';
import { RawAdvancedCameraCardConfig } from '../config/types'; import { RawAdvancedCameraCardConfig } from '../config/types';
import { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import basicBlockStyle from '../scss/basic-block.scss'; import basicBlockStyle from '../scss/basic-block.scss';
import { getDiagnostics } from '../utils/diagnostics'; import { getDiagnostics } from '../utils/diagnostics';
+8 -7
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { import {
CSSResultGroup, CSSResultGroup,
html, html,
@@ -8,9 +7,9 @@ import {
unsafeCSS, unsafeCSS,
} from 'lit'; } from 'lit';
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property, state } from 'lit/decorators.js';
import { dispatchAdvancedCameraCardErrorEvent } from '../components-lib/message/dispatch.js';
import { ConditionsManager } from '../conditions/conditions-manager.js'; import { ConditionsManager } from '../conditions/conditions-manager.js';
import { getConditionStateManagerViaEvent } from '../conditions/state-manager-via-event.js'; import { getConditionStateManagerViaEvent } from '../conditions/state-manager-via-event.js';
import { dispatchAdvancedCameraCardErrorEvent } from '../components-lib/message/dispatch.js';
import { import {
AdvancedCameraCardConditional, AdvancedCameraCardConditional,
MenuIcon, MenuIcon,
@@ -24,10 +23,12 @@ import {
StatusBarItem, StatusBarItem,
StatusBarString, StatusBarString,
} from '../config/types.js'; } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import elementsStyle from '../scss/elements.scss'; import elementsStyle from '../scss/elements.scss';
import { AdvancedCameraCardError } from '../types.js'; import { AdvancedCameraCardError } from '../types.js';
import { dispatchAdvancedCameraCardEvent, errorToConsole } from '../utils/basic.js'; import { errorToConsole } from '../utils/basic.js';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js';
/* A note on picture element rendering: /* A note on picture element rendering:
* *
@@ -169,7 +170,7 @@ export class AdvancedCameraCardElements extends LitElement {
protected _menuRemoveHandler = (ev: Event): void => { protected _menuRemoveHandler = (ev: Event): void => {
// Re-dispatch event from this element (instead of the disconnected one, as // Re-dispatch event from this element (instead of the disconnected one, as
// there is no parent of the disconnected element). // there is no parent of the disconnected element).
dispatchAdvancedCameraCardEvent<MenuItem>( fireAdvancedCameraCardEvent<MenuItem>(
this, this,
'menu:remove', 'menu:remove',
(ev as CustomEvent).detail, (ev as CustomEvent).detail,
@@ -179,7 +180,7 @@ export class AdvancedCameraCardElements extends LitElement {
protected _statusBarRemoveHandler = (ev: Event): void => { protected _statusBarRemoveHandler = (ev: Event): void => {
// Re-dispatch event from this element (instead of the disconnected one, as // Re-dispatch event from this element (instead of the disconnected one, as
// there is no parent of the disconnected element). // there is no parent of the disconnected element).
dispatchAdvancedCameraCardEvent<StatusBarItem>( fireAdvancedCameraCardEvent<StatusBarItem>(
this, this,
'status-bar:remove', 'status-bar:remove',
(ev as CustomEvent).detail, (ev as CustomEvent).detail,
@@ -346,7 +347,7 @@ export class AdvancedCameraCardElementsBaseItem<ConfigType> extends LitElement {
connectedCallback(): void { connectedCallback(): void {
super.connectedCallback(); super.connectedCallback();
if (this._config) { if (this._config) {
dispatchAdvancedCameraCardEvent<ConfigType>( fireAdvancedCameraCardEvent<ConfigType>(
this, this,
`${this._eventCategory}:add`, `${this._eventCategory}:add`,
this._config, this._config,
@@ -356,7 +357,7 @@ export class AdvancedCameraCardElementsBaseItem<ConfigType> extends LitElement {
disconnectedCallback(): void { disconnectedCallback(): void {
if (this._config) { if (this._config) {
dispatchAdvancedCameraCardEvent<ConfigType>( fireAdvancedCameraCardEvent<ConfigType>(
this, this,
`${this._eventCategory}:remove`, `${this._eventCategory}:remove`,
this._config, this._config,
+3 -3
View File
@@ -14,10 +14,10 @@ import { CameraManager, ExtendedMediaQueryResult } from '../camera-manager/manag
import { EventQuery, MediaQuery, RecordingQuery } from '../camera-manager/types'; import { EventQuery, MediaQuery, RecordingQuery } from '../camera-manager/types';
import { ViewManagerEpoch } from '../card-controller/view/types.js'; import { ViewManagerEpoch } from '../card-controller/view/types.js';
import { CardWideConfig, configDefaults, GalleryConfig } from '../config/types'; import { CardWideConfig, configDefaults, GalleryConfig } from '../config/types';
import { HomeAssistant } from '../ha/types.js';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import galleryCoreStyle from '../scss/gallery-core.scss'; import galleryCoreStyle from '../scss/gallery-core.scss';
import galleryStyle from '../scss/gallery.scss'; import galleryStyle from '../scss/gallery.scss';
import { ExtendedHomeAssistant } from '../types.js';
import { stopEventFromActivatingCardWideActions } from '../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
import { errorToConsole, sleep } from '../utils/basic'; import { errorToConsole, sleep } from '../utils/basic';
import { scrollIntoView } from '../utils/scroll.js'; import { scrollIntoView } from '../utils/scroll.js';
@@ -44,7 +44,7 @@ const MIN_GALLERY_EXTENSION_SECONDS = 0.5;
@customElement('advanced-camera-card-gallery') @customElement('advanced-camera-card-gallery')
export class AdvancedCameraCardGallery extends LitElement { export class AdvancedCameraCardGallery extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
@@ -112,7 +112,7 @@ export class AdvancedCameraCardGallery extends LitElement {
@customElement('advanced-camera-card-gallery-core') @customElement('advanced-camera-card-gallery-core')
export class AdvancedCameraCardGalleryCore extends LitElement { export class AdvancedCameraCardGalleryCore extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+1 -1
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { import {
CSSResultGroup, CSSResultGroup,
html, html,
@@ -9,6 +8,7 @@ import {
} from 'lit'; } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { IconController } from '../components-lib/icon-controller'; import { IconController } from '../components-lib/icon-controller';
import { HomeAssistant } from '../ha/types';
import iconStyle from '../scss/icon.scss'; import iconStyle from '../scss/icon.scss';
import { Icon } from '../types'; import { Icon } from '../types';
+1 -1
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { HassEntity } from 'home-assistant-js-websocket'; import { HassEntity } from 'home-assistant-js-websocket';
import { import {
CSSResultGroup, CSSResultGroup,
@@ -17,6 +16,7 @@ import { getCameraEntityFromConfig } from '../camera-manager/utils/camera-entity
import { CachedValueController } from '../components-lib/cached-value-controller.js'; import { CachedValueController } from '../components-lib/cached-value-controller.js';
import { UpdatingImageMediaPlayerController } from '../components-lib/media-player/updating-image.js'; import { UpdatingImageMediaPlayerController } from '../components-lib/media-player/updating-image.js';
import { CameraConfig, ImageMode, ImageViewConfig } from '../config/types.js'; import { CameraConfig, ImageMode, ImageViewConfig } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import defaultImage from '../images/iris-screensaver.jpg'; import defaultImage from '../images/iris-screensaver.jpg';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import imageUpdatingPlayerStyle from '../scss/image-updating-player.scss'; import imageUpdatingPlayerStyle from '../scss/image-updating-player.scss';
+1 -1
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { import {
CSSResultGroup, CSSResultGroup,
html, html,
@@ -23,6 +22,7 @@ import { updateElementStyleFromMediaLayoutConfig } from '../utils/media-layout.j
import './image-updating-player'; import './image-updating-player';
import { resolveImageMode } from './image-updating-player'; import { resolveImageMode } from './image-updating-player';
import './zoomer.js'; import './zoomer.js';
import { HomeAssistant } from '../ha/types';
@customElement('advanced-camera-card-image') @customElement('advanced-camera-card-image')
export class AdvancedCameraCardImage extends LitElement implements MediaPlayer { export class AdvancedCameraCardImage extends LitElement implements MediaPlayer {
+2 -2
View File
@@ -23,8 +23,8 @@ import {
LiveConfig, LiveConfig,
TransitionEffect, TransitionEffect,
} from '../../config/types.js'; } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import liveCarouselStyle from '../../scss/live-carousel.scss'; import liveCarouselStyle from '../../scss/live-carousel.scss';
import { ExtendedHomeAssistant } from '../../types.js';
import { stopEventFromActivatingCardWideActions } from '../../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../../utils/action.js';
import { CarouselSelected } from '../../utils/embla/carousel-controller.js'; import { CarouselSelected } from '../../utils/embla/carousel-controller.js';
import { AutoLazyLoad } from '../../utils/embla/plugins/auto-lazy-load/auto-lazy-load.js'; import { AutoLazyLoad } from '../../utils/embla/plugins/auto-lazy-load/auto-lazy-load.js';
@@ -56,7 +56,7 @@ interface CameraNeighbors {
@customElement('advanced-camera-card-live-carousel') @customElement('advanced-camera-card-live-carousel')
export class AdvancedCameraCardLiveCarousel extends LitElement { export class AdvancedCameraCardLiveCarousel extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+2 -2
View File
@@ -13,14 +13,14 @@ import { MicrophoneState } from '../../card-controller/types.js';
import { ViewManagerEpoch } from '../../card-controller/view/types.js'; import { ViewManagerEpoch } from '../../card-controller/view/types.js';
import { MediaGridSelected } from '../../components-lib/media-grid-controller.js'; import { MediaGridSelected } from '../../components-lib/media-grid-controller.js';
import { CardWideConfig, LiveConfig } from '../../config/types.js'; import { CardWideConfig, LiveConfig } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import liveGridStyle from '../../scss/live-grid.scss'; import liveGridStyle from '../../scss/live-grid.scss';
import { ExtendedHomeAssistant } from '../../types.js';
import './carousel.js'; import './carousel.js';
@customElement('advanced-camera-card-live-grid') @customElement('advanced-camera-card-live-grid')
export class AdvancedCameraCardLiveGrid extends LitElement { export class AdvancedCameraCardLiveGrid extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+2 -2
View File
@@ -5,14 +5,14 @@ import { MicrophoneState } from '../../card-controller/types.js';
import { ViewManagerEpoch } from '../../card-controller/view/types.js'; import { ViewManagerEpoch } from '../../card-controller/view/types.js';
import { LiveController } from '../../components-lib/live/live-controller.js'; import { LiveController } from '../../components-lib/live/live-controller.js';
import { CardWideConfig, LiveConfig } from '../../config/types.js'; import { CardWideConfig, LiveConfig } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import basicBlockStyle from '../../scss/basic-block.scss'; import basicBlockStyle from '../../scss/basic-block.scss';
import { ExtendedHomeAssistant } from '../../types.js';
import './grid.js'; import './grid.js';
@customElement('advanced-camera-card-live') @customElement('advanced-camera-card-live')
export class AdvancedCameraCardLive extends LitElement { export class AdvancedCameraCardLive extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+3 -7
View File
@@ -22,14 +22,10 @@ import {
LiveProvider, LiveProvider,
} from '../../config/types.js'; } from '../../config/types.js';
import { STREAM_TROUBLESHOOTING_URL } from '../../const.js'; import { STREAM_TROUBLESHOOTING_URL } from '../../const.js';
import { HomeAssistant } from '../../ha/types.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import liveProviderStyle from '../../scss/live-provider.scss'; import liveProviderStyle from '../../scss/live-provider.scss';
import { import { MediaPlayer, MediaPlayerController, MediaPlayerElement } from '../../types.js';
ExtendedHomeAssistant,
MediaPlayer,
MediaPlayerController,
MediaPlayerElement,
} from '../../types.js';
import { aspectRatioToString } from '../../utils/basic.js'; import { aspectRatioToString } from '../../utils/basic.js';
import { dispatchMediaUnloadedEvent } from '../../utils/media-info.js'; import { dispatchMediaUnloadedEvent } from '../../utils/media-info.js';
import { updateElementStyleFromMediaLayoutConfig } from '../../utils/media-layout.js'; import { updateElementStyleFromMediaLayoutConfig } from '../../utils/media-layout.js';
@@ -42,7 +38,7 @@ import '../surround.js';
@customElement('advanced-camera-card-live-provider') @customElement('advanced-camera-card-live-provider')
export class AdvancedCameraCardLiveProvider extends LitElement implements MediaPlayer { export class AdvancedCameraCardLiveProvider extends LitElement implements MediaPlayer {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public cameraConfig?: CameraConfig; public cameraConfig?: CameraConfig;
@@ -12,14 +12,10 @@ import { MicrophoneState } from '../../../../card-controller/types.js';
import { dispatchLiveErrorEvent } from '../../../../components-lib/live/utils/dispatch-live-error.js'; import { dispatchLiveErrorEvent } from '../../../../components-lib/live/utils/dispatch-live-error.js';
import { VideoMediaPlayerController } from '../../../../components-lib/media-player/video.js'; import { VideoMediaPlayerController } from '../../../../components-lib/media-player/video.js';
import { CameraConfig, MicrophoneConfig } from '../../../../config/types.js'; import { CameraConfig, MicrophoneConfig } from '../../../../config/types.js';
import { HomeAssistant } from '../../../../ha/types.js';
import { localize } from '../../../../localize/localize.js'; import { localize } from '../../../../localize/localize.js';
import liveGo2RTCStyle from '../../../../scss/live-go2rtc.scss'; import liveGo2RTCStyle from '../../../../scss/live-go2rtc.scss';
import { import { MediaPlayer, MediaPlayerController, Message } from '../../../../types.js';
ExtendedHomeAssistant,
MediaPlayer,
MediaPlayerController,
Message,
} from '../../../../types.js';
import { convertEndpointAddressToSignedWebsocket } from '../../../../utils/endpoint.js'; import { convertEndpointAddressToSignedWebsocket } from '../../../../utils/endpoint.js';
import { renderMessage } from '../../../message.js'; import { renderMessage } from '../../../message.js';
import { VideoRTC } from './video-rtc.js'; import { VideoRTC } from './video-rtc.js';
@@ -36,7 +32,7 @@ const GO2RTC_URL_SIGN_EXPIRY_SECONDS = 24 * 60 * 60;
@customElement('advanced-camera-card-live-go2rtc') @customElement('advanced-camera-card-live-go2rtc')
export class AdvancedCameraCardGo2RTC extends LitElement implements MediaPlayer { export class AdvancedCameraCardGo2RTC extends LitElement implements MediaPlayer {
// Not an reactive property to avoid resetting the video. // Not an reactive property to avoid resetting the video.
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public cameraConfig?: CameraConfig; public cameraConfig?: CameraConfig;
+1 -1
View File
@@ -1,8 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { createRef, Ref, ref } from 'lit/directives/ref.js'; import { createRef, Ref, ref } from 'lit/directives/ref.js';
import { CameraConfig } from '../../../config/types'; import { CameraConfig } from '../../../config/types';
import { HomeAssistant } from '../../../ha/types';
import '../../../patches/ha-camera-stream'; import '../../../patches/ha-camera-stream';
import '../../../patches/ha-hls-player.js'; import '../../../patches/ha-hls-player.js';
import '../../../patches/ha-web-rtc-player.js'; import '../../../patches/ha-web-rtc-player.js';
+1 -1
View File
@@ -1,8 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { createRef, ref, Ref } from 'lit/directives/ref.js'; import { createRef, ref, Ref } from 'lit/directives/ref.js';
import { CameraConfig } from '../../../config/types'; import { CameraConfig } from '../../../config/types';
import { HomeAssistant } from '../../../ha/types';
import basicBlockStyle from '../../../scss/basic-block.scss'; import basicBlockStyle from '../../../scss/basic-block.scss';
import { import {
MediaPlayer, MediaPlayer,
+3 -7
View File
@@ -13,14 +13,10 @@ import { CameraEndpoints } from '../../../camera-manager/types.js';
import { dispatchLiveErrorEvent } from '../../../components-lib/live/utils/dispatch-live-error.js'; import { dispatchLiveErrorEvent } from '../../../components-lib/live/utils/dispatch-live-error.js';
import { JSMPEGMediaPlayerController } from '../../../components-lib/media-player/jsmpeg.js'; import { JSMPEGMediaPlayerController } from '../../../components-lib/media-player/jsmpeg.js';
import { CameraConfig, CardWideConfig } from '../../../config/types.js'; import { CameraConfig, CardWideConfig } from '../../../config/types.js';
import { HomeAssistant } from '../../../ha/types.js';
import { localize } from '../../../localize/localize.js'; import { localize } from '../../../localize/localize.js';
import liveJSMPEGStyle from '../../../scss/live-jsmpeg.scss'; import liveJSMPEGStyle from '../../../scss/live-jsmpeg.scss';
import { import { MediaPlayer, MediaPlayerController, Message } from '../../../types.js';
ExtendedHomeAssistant,
MediaPlayer,
MediaPlayerController,
Message,
} from '../../../types.js';
import { convertEndpointAddressToSignedWebsocket } from '../../../utils/endpoint.js'; import { convertEndpointAddressToSignedWebsocket } from '../../../utils/endpoint.js';
import { import {
dispatchMediaLoadedEvent, dispatchMediaLoadedEvent,
@@ -41,7 +37,7 @@ const JSMPEG_URL_SIGN_REFRESH_THRESHOLD_SECONDS = 1 * 60 * 60;
@customElement('advanced-camera-card-live-jsmpeg') @customElement('advanced-camera-card-live-jsmpeg')
export class AdvancedCameraCardLiveJSMPEG extends LitElement implements MediaPlayer { export class AdvancedCameraCardLiveJSMPEG extends LitElement implements MediaPlayer {
protected hass?: ExtendedHomeAssistant; protected hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public cameraConfig?: CameraConfig; public cameraConfig?: CameraConfig;
+1 -1
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { Task } from '@lit-labs/task'; import { Task } from '@lit-labs/task';
import { import {
CSSResultGroup, CSSResultGroup,
@@ -14,6 +13,7 @@ import { dispatchLiveErrorEvent } from '../../../components-lib/live/utils/dispa
import { getTechnologyForVideoRTC } from '../../../components-lib/live/utils/get-technology-for-video-rtc.js'; import { getTechnologyForVideoRTC } from '../../../components-lib/live/utils/get-technology-for-video-rtc.js';
import { VideoMediaPlayerController } from '../../../components-lib/media-player/video.js'; import { VideoMediaPlayerController } from '../../../components-lib/media-player/video.js';
import { CameraConfig, CardWideConfig } from '../../../config/types.js'; import { CameraConfig, CardWideConfig } from '../../../config/types.js';
import { HomeAssistant } from '../../../ha/types.js';
import { localize } from '../../../localize/localize.js'; import { localize } from '../../../localize/localize.js';
import liveWebRTCCardStyle from '../../../scss/live-webrtc-card.scss'; import liveWebRTCCardStyle from '../../../scss/live-webrtc-card.scss';
import { import {
+2 -2
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin'; import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin';
import { import {
CSSResultGroup, CSSResultGroup,
@@ -12,6 +11,7 @@ import { customElement, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import { createRef, ref, Ref } from 'lit/directives/ref.js'; import { createRef, ref, Ref } from 'lit/directives/ref.js';
import { CameraManager } from '../camera-manager/manager'; import { CameraManager } from '../camera-manager/manager';
import { ViewManagerEpoch } from '../card-controller/view/types';
import { import {
MediaFilterController, MediaFilterController,
MediaFilterCoreFavoriteSelection, MediaFilterCoreFavoriteSelection,
@@ -19,13 +19,13 @@ import {
MediaFilterMediaType, MediaFilterMediaType,
} from '../components-lib/media-filter-controller'; } from '../components-lib/media-filter-controller';
import { CardWideConfig } from '../config/types'; import { CardWideConfig } from '../config/types';
import { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import mediaFilterStyle from '../scss/media-filter.scss'; import mediaFilterStyle from '../scss/media-filter.scss';
import { AdvancedCameraCardDatePicker } from './date-picker'; import { AdvancedCameraCardDatePicker } from './date-picker';
import './date-picker.js'; import './date-picker.js';
import { AdvancedCameraCardSelect } from './select'; import { AdvancedCameraCardSelect } from './select';
import './select.js'; import './select.js';
import { ViewManagerEpoch } from '../card-controller/view/types';
@customElement('advanced-camera-card-media-filter') @customElement('advanced-camera-card-media-filter')
class AdvancedCameraCardMediaFilter extends ScopedRegistryHost(LitElement) { class AdvancedCameraCardMediaFilter extends ScopedRegistryHost(LitElement) {
+1 -1
View File
@@ -1,10 +1,10 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit'; import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js';
import { actionHandler } from '../action-handler-directive.js'; import { actionHandler } from '../action-handler-directive.js';
import { MenuController } from '../components-lib/menu-controller.js'; import { MenuController } from '../components-lib/menu-controller.js';
import type { MenuConfig, MenuItem } from '../config/types.js'; import type { MenuConfig, MenuItem } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import menuStyle from '../scss/menu.scss'; import menuStyle from '../scss/menu.scss';
import { hasAction } from '../utils/action.js'; import { hasAction } from '../utils/action.js';
import { getEntityTitle } from '../utils/ha/index.js'; import { getEntityTitle } from '../utils/ha/index.js';
+1 -1
View File
@@ -1,8 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit'; import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import { NextPreviousControlConfig } from '../config/types.js'; import { NextPreviousControlConfig } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import controlStyle from '../scss/next-previous-control.scss'; import controlStyle from '../scss/next-previous-control.scss';
import { Icon } from '../types.js'; import { Icon } from '../types.js';
import { renderTask } from '../utils/task.js'; import { renderTask } from '../utils/task.js';
+1 -1
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { import {
CSSResultGroup, CSSResultGroup,
LitElement, LitElement,
@@ -14,6 +13,7 @@ import { CameraManager } from '../camera-manager/manager.js';
import { PTZController } from '../components-lib/ptz/ptz-controller.js'; import { PTZController } from '../components-lib/ptz/ptz-controller.js';
import { PTZControllerActions } from '../components-lib/ptz/types.js'; import { PTZControllerActions } from '../components-lib/ptz/types.js';
import { Actions, PTZControlsConfig } from '../config/types.js'; import { Actions, PTZControlsConfig } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import ptzStyle from '../scss/ptz.scss'; import ptzStyle from '../scss/ptz.scss';
import { Interaction } from '../types.js'; import { Interaction } from '../types.js';
+3 -2
View File
@@ -9,7 +9,8 @@ import {
import { property } from 'lit/decorators.js'; import { property } from 'lit/decorators.js';
import { createRef, ref, Ref } from 'lit/directives/ref.js'; import { createRef, ref, Ref } from 'lit/directives/ref.js';
import selectStyle from '../scss/select.scss'; import selectStyle from '../scss/select.scss';
import { contentsChanged, dispatchAdvancedCameraCardEvent } from '../utils/basic'; import { contentsChanged } from '../utils/basic';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event';
import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin'; import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin';
import { grSelectElements } from '../scoped-elements/gr-select'; import { grSelectElements } from '../scoped-elements/gr-select';
import isEqual from 'lodash-es/isEqual'; import isEqual from 'lodash-es/isEqual';
@@ -73,7 +74,7 @@ export class AdvancedCameraCardSelect extends ScopedRegistryHost(LitElement) {
// (even when the user has not interacted with the control). Do not // (even when the user has not interacted with the control). Do not
// dispatch events for this. // dispatch events for this.
if (!initialValueSet) { if (!initialValueSet) {
dispatchAdvancedCameraCardEvent(this, 'select:change', value); fireAdvancedCameraCardEvent(this, 'select:change', value);
} }
} }
} }
+1 -1
View File
@@ -1,9 +1,9 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js';
import { actionHandler } from '../../action-handler-directive.js'; import { actionHandler } from '../../action-handler-directive.js';
import { HomeAssistant } from '../../ha/types.js';
import submenuStyle from '../../scss/submenu.scss'; import submenuStyle from '../../scss/submenu.scss';
import { import {
hasAction, hasAction,
+1 -1
View File
@@ -1,4 +1,3 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { import {
CSSResultGroup, CSSResultGroup,
html, html,
@@ -10,6 +9,7 @@ import {
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property, state } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js';
import { MenuSubmenu, MenuSubmenuItem, MenuSubmenuSelect } from '../../config/types.js'; import { MenuSubmenu, MenuSubmenuItem, MenuSubmenuSelect } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import menuButtonStyle from '../../scss/menu-button.scss'; import menuButtonStyle from '../../scss/menu-button.scss';
import { getEntityTitle, isHassDifferent } from '../../utils/ha'; import { getEntityTitle, isHassDifferent } from '../../utils/ha';
import { getEntityStateTranslation } from '../../utils/ha/entity-state-translation.js'; import { getEntityStateTranslation } from '../../utils/ha/entity-state-translation.js';
+2 -1
View File
@@ -1,9 +1,10 @@
import { hasAction, HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js';
import { actionHandler } from '../../action-handler-directive.js'; import { actionHandler } from '../../action-handler-directive.js';
import { MenuSubmenu } from '../../config/types.js'; import { MenuSubmenu } from '../../config/types.js';
import { hasAction } from '../../ha/has-action.js';
import { HomeAssistant } from '../../ha/types.js';
import menuButtonStyle from '../../scss/menu-button.scss'; import menuButtonStyle from '../../scss/menu-button.scss';
import '../icon.js'; import '../icon.js';
import './index.js'; import './index.js';
+5 -4
View File
@@ -15,16 +15,17 @@ import {
MiniTimelineControlConfig, MiniTimelineControlConfig,
ThumbnailsControlConfig, ThumbnailsControlConfig,
} from '../config/types.js'; } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import basicBlockStyle from '../scss/basic-block.scss'; import basicBlockStyle from '../scss/basic-block.scss';
import { ExtendedHomeAssistant } from '../types.js'; import { contentsChanged } from '../utils/basic.js';
import { contentsChanged, dispatchAdvancedCameraCardEvent } from '../utils/basic.js'; import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js';
import './surround-basic.js'; import './surround-basic.js';
import { ThumbnailCarouselTap } from './thumbnail-carousel.js'; import { ThumbnailCarouselTap } from './thumbnail-carousel.js';
@customElement('advanced-camera-card-surround') @customElement('advanced-camera-card-surround')
export class AdvancedCameraCardSurround extends LitElement { export class AdvancedCameraCardSurround extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
@@ -112,7 +113,7 @@ export class AdvancedCameraCardSurround extends LitElement {
// from the origin of the inbound event, so it can be handled by // from the origin of the inbound event, so it can be handled by
// <advanced-camera-card-surround> . // <advanced-camera-card-surround> .
if (this.thumbnailConfig && this._hasDrawer()) { if (this.thumbnailConfig && this._hasDrawer()) {
dispatchAdvancedCameraCardEvent(ev.composedPath()[0], 'drawer:' + action, { fireAdvancedCameraCardEvent(ev.composedPath()[0], 'drawer:' + action, {
drawer: this.thumbnailConfig.mode, drawer: this.thumbnailConfig.mode,
}); });
} }
+4 -4
View File
@@ -11,11 +11,11 @@ import { classMap } from 'lit/directives/class-map.js';
import { CameraManager } from '../camera-manager/manager.js'; import { CameraManager } from '../camera-manager/manager.js';
import { ViewManagerEpoch } from '../card-controller/view/types.js'; import { ViewManagerEpoch } from '../card-controller/view/types.js';
import { ThumbnailsControlConfig } from '../config/types.js'; import { ThumbnailsControlConfig } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss'; import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
import { ExtendedHomeAssistant } from '../types.js';
import { stopEventFromActivatingCardWideActions } from '../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
import { dispatchAdvancedCameraCardEvent } from '../utils/basic.js';
import { CarouselDirection } from '../utils/embla/carousel-controller.js'; import { CarouselDirection } from '../utils/embla/carousel-controller.js';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event.js';
import { MediaQueriesResults } from '../view/media-queries-results'; import { MediaQueriesResults } from '../view/media-queries-results';
import './carousel.js'; import './carousel.js';
import './thumbnail.js'; import './thumbnail.js';
@@ -27,7 +27,7 @@ export interface ThumbnailCarouselTap {
@customElement('advanced-camera-card-thumbnail-carousel') @customElement('advanced-camera-card-thumbnail-carousel')
export class AdvancedCameraCardThumbnailCarousel extends LitElement { export class AdvancedCameraCardThumbnailCarousel extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
@@ -111,7 +111,7 @@ export class AdvancedCameraCardThumbnailCarousel extends LitElement {
@click=${(ev: Event) => { @click=${(ev: Event) => {
const view = this.viewManagerEpoch?.manager.getView(); const view = this.viewManagerEpoch?.manager.getView();
if (view && view.queryResults) { if (view && view.queryResults) {
dispatchAdvancedCameraCardEvent<ThumbnailCarouselTap>( fireAdvancedCameraCardEvent<ThumbnailCarouselTap>(
this, this,
'thumbnail-carousel:tap', 'thumbnail-carousel:tap',
{ {
+3 -3
View File
@@ -15,12 +15,12 @@ import { CameraManagerCameraMetadata } from '../camera-manager/types.js';
import { RemoveContextViewModifier } from '../card-controller/view/modifiers/remove-context.js'; import { RemoveContextViewModifier } from '../card-controller/view/modifiers/remove-context.js';
import { ViewManagerEpoch } from '../card-controller/view/types.js'; import { ViewManagerEpoch } from '../card-controller/view/types.js';
import { dispatchAdvancedCameraCardErrorEvent } from '../components-lib/message/dispatch.js'; import { dispatchAdvancedCameraCardErrorEvent } from '../components-lib/message/dispatch.js';
import { HomeAssistant } from '../ha/types.js';
import { localize } from '../localize/localize.js'; import { localize } from '../localize/localize.js';
import thumbnailDetailsStyle from '../scss/thumbnail-details.scss'; import thumbnailDetailsStyle from '../scss/thumbnail-details.scss';
import thumbnailFeatureTextStyle from '../scss/thumbnail-feature-text.scss'; import thumbnailFeatureTextStyle from '../scss/thumbnail-feature-text.scss';
import thumbnailFeatureThumbnailStyle from '../scss/thumbnail-feature-thumbnail.scss'; import thumbnailFeatureThumbnailStyle from '../scss/thumbnail-feature-thumbnail.scss';
import thumbnailStyle from '../scss/thumbnail.scss'; import thumbnailStyle from '../scss/thumbnail.scss';
import type { ExtendedHomeAssistant } from '../types.js';
import { stopEventFromActivatingCardWideActions } from '../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
import { import {
errorToConsole, errorToConsole,
@@ -43,7 +43,7 @@ export class AdvancedCameraCardThumbnailFeatureThumbnail extends LitElement {
public thumbnail?: string; public thumbnail?: string;
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@state() @state()
protected _thumbnailError = false; protected _thumbnailError = false;
@@ -368,7 +368,7 @@ export class AdvancedCameraCardThumbnail extends LitElement {
// a re-render. The HomeAssistant object may be required for thumbnail signing // a re-render. The HomeAssistant object may be required for thumbnail signing
// (after initial signing the thumbnail is stored in a data URL, so the // (after initial signing the thumbnail is stored in a data URL, so the
// signing will not expire). // signing will not expire).
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
// Performance: During timeline scrubbing, the view will be updated // Performance: During timeline scrubbing, the view will be updated
// continuously. As it is not needed for the thumbnail rendering itself, it // continuously. As it is not needed for the thumbnail rendering itself, it
+5 -5
View File
@@ -46,19 +46,19 @@ import {
TimelinePanMode, TimelinePanMode,
configDefaults, configDefaults,
} from '../config/types'; } from '../config/types';
import { HomeAssistant } from '../ha/types';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import timelineCoreStyle from '../scss/timeline-core.scss'; import timelineCoreStyle from '../scss/timeline-core.scss';
import { ExtendedHomeAssistant } from '../types';
import { stopEventFromActivatingCardWideActions } from '../utils/action'; import { stopEventFromActivatingCardWideActions } from '../utils/action';
import { import {
contentsChanged, contentsChanged,
dispatchAdvancedCameraCardEvent,
formatDateAndTime, formatDateAndTime,
isHoverableDevice, isHoverableDevice,
isTruthy, isTruthy,
setOrRemoveAttribute, setOrRemoveAttribute,
} from '../utils/basic'; } from '../utils/basic';
import { findBestMediaIndex } from '../utils/find-best-media-index'; import { findBestMediaIndex } from '../utils/find-best-media-index';
import { fireAdvancedCameraCardEvent } from '../utils/fire-advanced-camera-card-event';
import { ViewMedia } from '../view/media'; import { ViewMedia } from '../view/media';
import { ViewMediaClassifier } from '../view/media-classifier'; import { ViewMediaClassifier } from '../view/media-classifier';
import { import {
@@ -108,7 +108,7 @@ interface ExtendedTimeline extends Timeline {
// note below on why this is necessary. // note below on why this is necessary.
interface ThumbnailDataRequest { interface ThumbnailDataRequest {
item: IdType; item: IdType;
hass?: ExtendedHomeAssistant; hass?: HomeAssistant;
cameraManager?: CameraManager; cameraManager?: CameraManager;
cameraConfig?: CameraConfig; cameraConfig?: CameraConfig;
media?: ViewMedia; media?: ViewMedia;
@@ -187,7 +187,7 @@ export class AdvancedCameraCardTimelineThumbnail extends LitElement {
@customElement('advanced-camera-card-timeline-core') @customElement('advanced-camera-card-timeline-core')
export class AdvancedCameraCardTimelineCore extends LitElement { export class AdvancedCameraCardTimelineCore extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
@@ -632,7 +632,7 @@ export class AdvancedCameraCardTimelineCore extends LitElement {
} }
} }
dispatchAdvancedCameraCardEvent(this, `thumbnails:${drawerAction}`); fireAdvancedCameraCardEvent(this, `thumbnails:${drawerAction}`);
this._ignoreClick = false; this._ignoreClick = false;
} }
+2 -2
View File
@@ -3,15 +3,15 @@ import { customElement, property } from 'lit/decorators.js';
import { CameraManager } from '../camera-manager/manager'; import { CameraManager } from '../camera-manager/manager';
import { ViewManagerEpoch } from '../card-controller/view/types'; import { ViewManagerEpoch } from '../card-controller/view/types';
import { CardWideConfig, TimelineConfig } from '../config/types'; import { CardWideConfig, TimelineConfig } from '../config/types';
import { HomeAssistant } from '../ha/types';
import basicBlockStyle from '../scss/basic-block.scss'; import basicBlockStyle from '../scss/basic-block.scss';
import { ExtendedHomeAssistant } from '../types';
import './surround.js'; import './surround.js';
import './timeline-core.js'; import './timeline-core.js';
@customElement('advanced-camera-card-timeline') @customElement('advanced-camera-card-timeline')
export class AdvancedCameraCardTimeline extends LitElement { export class AdvancedCameraCardTimeline extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+3 -6
View File
@@ -19,14 +19,11 @@ import {
TransitionEffect, TransitionEffect,
ViewerConfig, ViewerConfig,
} from '../../config/types.js'; } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import viewerCarouselStyle from '../../scss/viewer-carousel.scss'; import viewerCarouselStyle from '../../scss/viewer-carousel.scss';
import { import { MediaLoadedInfo, MediaPlayerController } from '../../types.js';
ExtendedHomeAssistant,
MediaLoadedInfo,
MediaPlayerController,
} from '../../types.js';
import { stopEventFromActivatingCardWideActions } from '../../utils/action.js'; import { stopEventFromActivatingCardWideActions } from '../../utils/action.js';
import { contentsChanged, setOrRemoveAttribute } from '../../utils/basic.js'; import { contentsChanged, setOrRemoveAttribute } from '../../utils/basic.js';
import { CarouselSelected } from '../../utils/embla/carousel-controller.js'; import { CarouselSelected } from '../../utils/embla/carousel-controller.js';
@@ -59,7 +56,7 @@ const ADVANCED_CAMERA_CARD_VIEWER_PROVIDER = 'advanced-camera-card-viewer-provid
@customElement('advanced-camera-card-viewer-carousel') @customElement('advanced-camera-card-viewer-carousel')
export class AdvancedCameraCardViewerCarousel extends LitElement { export class AdvancedCameraCardViewerCarousel extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+2 -2
View File
@@ -12,16 +12,16 @@ import { CameraManager } from '../../camera-manager/manager.js';
import { ViewManagerEpoch } from '../../card-controller/view/types.js'; import { ViewManagerEpoch } from '../../card-controller/view/types.js';
import { MediaGridSelected } from '../../components-lib/media-grid-controller.js'; import { MediaGridSelected } from '../../components-lib/media-grid-controller.js';
import { CardWideConfig, ViewerConfig } from '../../config/types.js'; import { CardWideConfig, ViewerConfig } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import basicBlockStyle from '../../scss/basic-block.scss'; import basicBlockStyle from '../../scss/basic-block.scss';
import { ExtendedHomeAssistant } from '../../types.js';
import { ResolvedMediaCache } from '../../utils/ha/resolved-media.js'; import { ResolvedMediaCache } from '../../utils/ha/resolved-media.js';
import './carousel'; import './carousel';
@customElement('advanced-camera-card-viewer-grid') @customElement('advanced-camera-card-viewer-grid')
export class AdvancedCameraCardViewerGrid extends LitElement { export class AdvancedCameraCardViewerGrid extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+2 -2
View File
@@ -3,10 +3,10 @@ import { customElement, property } from 'lit/decorators.js';
import { CameraManager } from '../../camera-manager/manager.js'; import { CameraManager } from '../../camera-manager/manager.js';
import { ViewManagerEpoch } from '../../card-controller/view/types.js'; import { ViewManagerEpoch } from '../../card-controller/view/types.js';
import { CardWideConfig, ViewerConfig } from '../../config/types.js'; import { CardWideConfig, ViewerConfig } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import viewerStyle from '../../scss/viewer.scss'; import viewerStyle from '../../scss/viewer.scss';
import { ExtendedHomeAssistant } from '../../types.js';
import { ResolvedMediaCache } from '../../utils/ha/resolved-media.js'; import { ResolvedMediaCache } from '../../utils/ha/resolved-media.js';
import { renderMessage } from '../message.js'; import { renderMessage } from '../message.js';
import './grid'; import './grid';
@@ -24,7 +24,7 @@ declare module 'view' {
@customElement('advanced-camera-card-viewer') @customElement('advanced-camera-card-viewer')
export class AdvancedCameraCardViewer extends LitElement { export class AdvancedCameraCardViewer extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+2 -2
View File
@@ -14,10 +14,10 @@ import { ViewManagerEpoch } from '../../card-controller/view/types.js';
import { ZoomSettingsObserved } from '../../components-lib/zoom/types.js'; import { ZoomSettingsObserved } from '../../components-lib/zoom/types.js';
import { handleZoomSettingsObservedEvent } from '../../components-lib/zoom/zoom-view-context.js'; import { handleZoomSettingsObservedEvent } from '../../components-lib/zoom/zoom-view-context.js';
import { CardWideConfig, ViewerConfig } from '../../config/types.js'; import { CardWideConfig, ViewerConfig } from '../../config/types.js';
import { HomeAssistant } from '../../ha/types.js';
import '../../patches/ha-hls-player.js'; import '../../patches/ha-hls-player.js';
import viewerProviderStyle from '../../scss/viewer-provider.scss'; import viewerProviderStyle from '../../scss/viewer-provider.scss';
import { import {
ExtendedHomeAssistant,
MediaPlayer, MediaPlayer,
MediaPlayerController, MediaPlayerController,
MediaPlayerElement, MediaPlayerElement,
@@ -46,7 +46,7 @@ import '../video-player.js';
@customElement('advanced-camera-card-viewer-provider') @customElement('advanced-camera-card-viewer-provider')
export class AdvancedCameraCardViewerProvider extends LitElement implements MediaPlayer { export class AdvancedCameraCardViewerProvider extends LitElement implements MediaPlayer {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+2 -2
View File
@@ -16,8 +16,8 @@ import {
CardWideConfig, CardWideConfig,
RawAdvancedCameraCardConfig, RawAdvancedCameraCardConfig,
} from '../config/types.js'; } from '../config/types.js';
import { HomeAssistant } from '../ha/types.js';
import viewsStyle from '../scss/views.scss'; import viewsStyle from '../scss/views.scss';
import { ExtendedHomeAssistant } from '../types.js';
import { DeviceRegistryManager } from '../utils/ha/registry/device/index.js'; import { DeviceRegistryManager } from '../utils/ha/registry/device/index.js';
import { ResolvedMediaCache } from '../utils/ha/resolved-media.js'; import { ResolvedMediaCache } from '../utils/ha/resolved-media.js';
import './surround.js'; import './surround.js';
@@ -29,7 +29,7 @@ import './diagnostics.js';
@customElement('advanced-camera-card-views') @customElement('advanced-camera-card-views')
export class AdvancedCameraCardViews extends LitElement { export class AdvancedCameraCardViews extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: HomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
public viewManagerEpoch?: ViewManagerEpoch; public viewManagerEpoch?: ViewManagerEpoch;
+3 -3
View File
@@ -1,8 +1,8 @@
import { CurrentUser } from '@dermotduffy/custom-card-helpers';
import { HassEntities } from 'home-assistant-js-websocket'; import { HassEntities } from 'home-assistant-js-websocket';
import { AdvancedCameraCardConfig, ViewDisplayMode } from '../config/types';
import { MediaLoadedInfo } from '../types';
import { KeysState, MicrophoneState } from '../card-controller/types'; import { KeysState, MicrophoneState } from '../card-controller/types';
import { AdvancedCameraCardConfig, ViewDisplayMode } from '../config/types';
import { CurrentUser } from '../ha/types';
import { MediaLoadedInfo } from '../types';
export interface ConditionState { export interface ConditionState {
camera?: string; camera?: string;
+4 -4
View File
@@ -1,3 +1,6 @@
import { HassServiceTarget } from 'home-assistant-js-websocket';
import { z } from 'zod';
import { MEDIA_CHUNK_SIZE_DEFAULT, MEDIA_CHUNK_SIZE_MAX } from '../const.js';
import { import {
CallServiceActionConfig, CallServiceActionConfig,
ConfirmationRestrictionConfig, ConfirmationRestrictionConfig,
@@ -7,10 +10,7 @@ import {
PerformActionActionConfig, PerformActionActionConfig,
ToggleActionConfig, ToggleActionConfig,
UrlActionConfig, UrlActionConfig,
} from '@dermotduffy/custom-card-helpers'; } from '../ha/types.js';
import { HassServiceTarget } from 'home-assistant-js-websocket';
import { z } from 'zod';
import { MEDIA_CHUNK_SIZE_DEFAULT, MEDIA_CHUNK_SIZE_MAX } from '../const.js';
import { capabilityKeys } from '../types.js'; import { capabilityKeys } from '../types.js';
import { deepRemoveDefaults } from '../utils/zod.js'; import { deepRemoveDefaults } from '../utils/zod.js';
import { import {
+3 -6
View File
@@ -1,8 +1,3 @@
import {
fireEvent,
HomeAssistant,
LovelaceCardEditor,
} from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
@@ -238,6 +233,8 @@ import {
CONF_VIEW_TRIGGERS_UNTRIGGER_SECONDS, CONF_VIEW_TRIGGERS_UNTRIGGER_SECONDS,
MEDIA_CHUNK_SIZE_MAX, MEDIA_CHUNK_SIZE_MAX,
} from './const.js'; } from './const.js';
import { fireHASSEvent } from './ha/fire-hass-event.js';
import { HomeAssistant, LovelaceCardEditor } from './ha/types.js';
import { localize } from './localize/localize.js'; import { localize } from './localize/localize.js';
import editorStyle from './scss/editor.scss'; import editorStyle from './scss/editor.scss';
import { arrayMove, prettifyTitle } from './utils/basic.js'; import { arrayMove, prettifyTitle } from './utils/basic.js';
@@ -2510,7 +2507,7 @@ export class AdvancedCameraCardEditor extends LitElement implements LovelaceCard
protected _updateConfig(config: RawAdvancedCameraCardConfig): void { protected _updateConfig(config: RawAdvancedCameraCardConfig): void {
this._config = config; this._config = config;
fireEvent(this, 'config-changed', { config: this._config }); fireHASSEvent(this, 'config-changed', { config: this._config });
} }
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Custom cards for Home Assistant
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+7
View File
@@ -0,0 +1,7 @@
# Background
Some of these functions are inspired by or modified from the unmaintained
https://github.com/custom-cards/custom-card-helpers .
This directory is intended to contain usage agnostic Home Assistant
functionality.
+3
View File
@@ -0,0 +1,3 @@
export const computeDomain = (entityId: string): string => {
return entityId.substring(0, entityId.indexOf('.'));
};
+2
View File
@@ -0,0 +1,2 @@
export const STATES_OFF = ['closed', 'locked', 'off'];
export const STATES_ON = ['open', 'unlocked', 'on'];
+25
View File
@@ -0,0 +1,25 @@
import { ValidHassDomEvent } from './types';
/**
* Fire an event has per Home Assistant frontend specifications. All events
* fired by this method has expected content/behavior based on type.
*/
export const fireHASSEvent = <HassEvent extends ValidHassDomEvent>(
target: EventTarget,
type: HassEvent,
detail?: HASSDomEvents[HassEvent],
options?: {
bubbles?: boolean;
cancelable?: boolean;
composed?: boolean;
},
) => {
target.dispatchEvent(
new CustomEvent<HASSDomEvents[HassEvent]>(type, {
bubbles: options?.bubbles ?? true,
composed: options?.composed ?? true,
cancelable: options?.cancelable ?? false,
detail: detail,
}),
);
};
+90
View File
@@ -0,0 +1,90 @@
import { fireHASSEvent } from './fire-hass-event.js';
import { forwardHaptic } from './haptic.js';
import { navigate } from './navigate.js';
import { toggleEntity } from './toggle-entity.js';
import { ActionConfig, HomeAssistant } from './types.js';
export const handleActionConfig = (
node: HTMLElement,
hass: HomeAssistant,
config: {
entity?: string;
camera_image?: string;
hold_action?: ActionConfig;
tap_action?: ActionConfig;
double_tap_action?: ActionConfig;
},
actionConfig: ActionConfig | undefined,
): void => {
if (!actionConfig) {
actionConfig = {
action: 'more-info',
};
}
if (
actionConfig.confirmation &&
(!actionConfig.confirmation.exemptions ||
!actionConfig.confirmation.exemptions.some((e) => e.user === hass!.user!.id))
) {
forwardHaptic('warning');
if (
!confirm(
actionConfig.confirmation.text ||
`Are you sure you want to ${actionConfig.action}?`,
)
) {
return;
}
}
switch (actionConfig.action) {
case 'more-info':
if (config.entity || config.camera_image) {
fireHASSEvent(node, 'hass-more-info', {
entityId: config.entity ? config.entity : config.camera_image!,
});
}
break;
case 'navigate':
if (actionConfig.navigation_path) {
navigate(node, actionConfig.navigation_path);
}
break;
case 'url':
if (actionConfig.url_path) {
window.open(actionConfig.url_path);
}
break;
case 'toggle':
if (config.entity) {
toggleEntity(hass, config.entity!);
forwardHaptic('success');
}
break;
case 'perform-action': {
if (!actionConfig.perform_action) {
forwardHaptic('failure');
return;
}
const [domain, service] = actionConfig.perform_action.split('.', 2);
hass.callService(domain, service, actionConfig.data, actionConfig.target);
forwardHaptic('success');
break;
}
case 'call-service': {
if (!actionConfig.service) {
forwardHaptic('failure');
return;
}
const [domain, service] = actionConfig.service.split('.', 2);
hass.callService(domain, service, actionConfig.data, actionConfig.target);
forwardHaptic('success');
break;
}
case 'fire-dom-event': {
fireHASSEvent(node, 'll-custom', actionConfig);
}
}
};
+30
View File
@@ -0,0 +1,30 @@
/**
* Broadcast haptic feedback requests
*/
import { fireHASSEvent } from './fire-hass-event';
// Allowed types are from iOS HIG.
// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics
// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible.
export type HapticType =
| 'success'
| 'warning'
| 'failure'
| 'light'
| 'medium'
| 'heavy'
| 'selection';
declare global {
interface HASSDomEvents {
haptic: HapticType;
}
interface GlobalEventHandlersEventMap {
haptic: CustomEvent<HapticType>;
}
}
export const forwardHaptic = (hapticType: HapticType) => {
fireHASSEvent(window, 'haptic', hapticType);
};
+5
View File
@@ -0,0 +1,5 @@
import { ActionConfig } from './types.js';
export function hasAction(config?: ActionConfig): boolean {
return config !== undefined && config.action !== 'none';
}
+20
View File
@@ -0,0 +1,20 @@
import { fireHASSEvent } from './fire-hass-event.js';
declare global {
interface HASSDomEvents {
'location-changed': {
replace: boolean;
};
}
}
export const navigate = (_node: unknown, path: string, replace: boolean = false) => {
if (replace) {
history.replaceState(null, '', path);
} else {
history.pushState(null, '', path);
}
fireHASSEvent(window, 'location-changed', {
replace,
});
};
+8
View File
@@ -0,0 +1,8 @@
import { STATES_OFF } from './const.js';
import { turnOnOffEntity } from './turn-on-off-entity.js';
import { HomeAssistant } from './types.js';
export const toggleEntity = (hass: HomeAssistant, entityId: string): Promise<void> => {
const turnOn = STATES_OFF.includes(hass.states[entityId].state);
return turnOnOffEntity(hass, entityId, turnOn);
};
+25
View File
@@ -0,0 +1,25 @@
import { HomeAssistant } from './types.js';
import { computeDomain } from './compute-domain.js';
export const turnOnOffEntity = (
hass: HomeAssistant,
entityId: string,
turnOn = true,
): Promise<void> => {
const stateDomain = computeDomain(entityId);
const serviceDomain = stateDomain === 'group' ? 'homeassistant' : stateDomain;
let service;
switch (stateDomain) {
case 'lock':
service = turnOn ? 'unlock' : 'lock';
break;
case 'cover':
service = turnOn ? 'open_cover' : 'close_cover';
break;
default:
service = turnOn ? 'turn_on' : 'turn_off';
}
return hass.callService(serviceDomain, service, { entity_id: entityId });
};
+316
View File
@@ -0,0 +1,316 @@
import {
Auth,
Connection,
HassConfig,
HassEntities,
HassServices,
HassServiceTarget,
MessageBase,
} from 'home-assistant-js-websocket';
import { HapticType } from './haptic.js';
interface ToggleMenuActionConfig extends BaseActionConfig {
action: 'toggle-menu';
}
export interface ToggleActionConfig extends BaseActionConfig {
action: 'toggle';
}
export interface CallServiceActionConfig extends BaseActionConfig {
action: 'call-service';
service: string;
data?: {
entity_id?: string | [string];
[key: string]: unknown;
};
target?: HassServiceTarget;
repeat?: number;
haptic?: HapticType;
}
export interface PerformActionActionConfig extends BaseActionConfig {
action: 'perform-action';
perform_action: string;
data?: {
entity_id?: string | [string];
[key: string]: unknown;
};
target?: HassServiceTarget;
repeat?: number;
haptic?: HapticType;
}
export interface NavigateActionConfig extends BaseActionConfig {
action: 'navigate';
navigation_path: string;
}
export interface UrlActionConfig extends BaseActionConfig {
action: 'url';
url_path: string;
}
export interface MoreInfoActionConfig extends BaseActionConfig {
action: 'more-info';
entity?: string;
}
export interface NoActionConfig extends BaseActionConfig {
action: 'none';
}
interface CustomActionConfig extends BaseActionConfig {
action: 'fire-dom-event';
}
/**
* `repeat` and `haptic` are specifically for use in custom cards like the Button-Card
*/
interface BaseActionConfig {
confirmation?: ConfirmationRestrictionConfig;
repeat?: number;
haptic?: HapticType;
}
export interface ConfirmationRestrictionConfig {
text?: string;
exemptions?: RestrictionConfig[];
}
interface RestrictionConfig {
user: string;
}
export declare type ActionConfig =
| ToggleActionConfig
| CallServiceActionConfig
| PerformActionActionConfig
| NavigateActionConfig
| UrlActionConfig
| MoreInfoActionConfig
| NoActionConfig
| CustomActionConfig
| ToggleMenuActionConfig;
declare global {
interface HASSDomEvents {
'value-changed': {
value: unknown;
};
'config-changed': {
config: unknown;
};
'hass-more-info': {
entityId: string | undefined;
};
'll-rebuild': object;
'll-custom': object;
'location-changed': {
replace: boolean;
};
'show-dialog': object;
undefined: unknown;
action: {
action: string;
};
}
}
export type ValidHassDomEvent = keyof HASSDomEvents;
declare type LocalizeFunc = (key: string, ...args: unknown[]) => string;
interface Credential {
auth_provider_type: string;
auth_provider_id: string;
}
interface MFAModule {
id: string;
name: string;
enabled: boolean;
}
export interface CurrentUser {
id: string;
is_owner: boolean;
is_admin: boolean;
name: string;
credentials: Credential[];
mfa_modules: MFAModule[];
}
interface Theme {
'primary-color': string;
'text-primary-color': string;
'accent-color': string;
}
interface Themes {
darkMode?: boolean;
default_theme: string;
themes: {
[key: string]: Theme;
};
}
interface Panel {
component_name: string;
config: {
[key: string]: unknown;
} | null;
icon: string | null;
title: string | null;
url_path: string;
}
interface Panels {
[name: string]: Panel;
}
interface Resources {
[language: string]: {
[key: string]: string;
};
}
interface Translation {
nativeName: string;
isRTL: boolean;
fingerprints: {
[fragment: string]: string;
};
}
export interface ServiceCallRequest {
domain: string;
service: string;
serviceData?: Record<string, unknown>;
target?: HassServiceTarget;
}
export interface HomeAssistant {
auth: Auth;
connection: Connection;
connected: boolean;
states: HassEntities;
services: HassServices;
config: HassConfig;
themes: Themes;
selectedTheme?: string | null;
panels: Panels;
panelUrl: string;
language: string;
locale: FrontendLocaleData;
selectedLanguage: string | null;
resources: Resources;
localize: LocalizeFunc;
translationMetadata: {
fragments: string[];
translations: {
[lang: string]: Translation;
};
};
dockedSidebar: boolean;
moreInfoEntityId: string;
user: CurrentUser;
callService: (
domain: ServiceCallRequest['domain'],
service: ServiceCallRequest['service'],
serviceData?: ServiceCallRequest['serviceData'],
target?: ServiceCallRequest['target'],
) => Promise<void>;
callApi: <T>(
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
path: string,
parameters?: {
[key: string]: unknown;
},
) => Promise<T>;
fetchWithAuth: (
path: string,
init?: {
[key: string]: unknown;
},
) => Promise<Response>;
hassUrl(path?): string;
sendWS: (msg: MessageBase) => Promise<void>;
callWS: <T>(msg: MessageBase) => Promise<T>;
}
declare enum NumberFormat {
language = 'language',
system = 'system',
comma_decimal = 'comma_decimal',
decimal_comma = 'decimal_comma',
space_comma = 'space_comma',
none = 'none',
}
declare enum TimeFormat {
language = 'language',
system = 'system',
am_pm = '12',
twenty_four = '24',
}
interface FrontendLocaleData {
language: string;
number_format: NumberFormat;
time_format: TimeFormat;
}
export interface LovelaceCardConfig {
index?: number;
view_index?: number;
type: string;
[key: string]: unknown;
}
export interface LovelaceCard extends HTMLElement {
hass?: HomeAssistant;
isPanel?: boolean;
editMode?: boolean;
getCardSize(): number | Promise<number>;
setConfig(config: LovelaceCardConfig): void;
}
export interface LovelaceCardEditor extends HTMLElement {
hass?: HomeAssistant;
lovelace?: LovelaceConfig;
setConfig(config: LovelaceCardConfig): void;
}
interface LovelaceConfig {
title?: string;
views: LovelaceViewConfig[];
background?: string;
}
interface LovelaceViewConfig {
index?: number;
title?: string;
badges?: Array<string | LovelaceBadgeConfig>;
cards?: LovelaceCardConfig[];
path?: string;
icon?: string;
theme?: string;
panel?: boolean;
background?: string;
visible?: boolean | ShowViewConfig[];
}
interface ShowViewConfig {
user?: string;
}
interface LovelaceBadgeConfig {
type?: string;
[key: string]: unknown;
}
export interface ActionHandlerDetail {
action: string;
}
export interface ActionHandlerOptions {
hasHold?: boolean;
hasDoubleClick?: boolean;
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../ha/types';
import * as en from './languages/en.json'; import * as en from './languages/en.json';
const DEFAULT_LANG = 'en' as const; const DEFAULT_LANG = 'en' as const;
+1 -14
View File
@@ -1,11 +1,5 @@
import {
HomeAssistant,
LovelaceCard,
LovelaceCardConfig,
LovelaceCardEditor,
Themes,
} from '@dermotduffy/custom-card-helpers';
import { z } from 'zod'; import { z } from 'zod';
import { LovelaceCard, LovelaceCardConfig, LovelaceCardEditor } from './ha/types';
export type ClipsOrSnapshots = 'clips' | 'snapshots'; export type ClipsOrSnapshots = 'clips' | 'snapshots';
export type ClipsOrSnapshotsOrAll = 'clips' | 'snapshots' | 'all'; export type ClipsOrSnapshotsOrAll = 'clips' | 'snapshots' | 'all';
@@ -19,13 +13,6 @@ export class AdvancedCameraCardError extends Error {
} }
} }
export interface ExtendedHomeAssistant extends HomeAssistant {
hassUrl(path?): string;
themes: Themes & {
darkMode?: boolean;
};
}
export interface MediaLoadedCapabilities { export interface MediaLoadedCapabilities {
supports2WayAudio?: boolean; supports2WayAudio?: boolean;
supportsPause?: boolean; supportsPause?: boolean;
+2 -5
View File
@@ -1,8 +1,3 @@
import {
ActionConfig,
ServiceCallRequest,
hasAction as customCardHasAction,
} from '@dermotduffy/custom-card-helpers';
import { CardActionsAPI } from '../card-controller/types.js'; import { CardActionsAPI } from '../card-controller/types.js';
import { ZoomSettingsBase } from '../components-lib/zoom/types.js'; import { ZoomSettingsBase } from '../components-lib/zoom/types.js';
import { PTZAction } from '../config/ptz.js'; import { PTZAction } from '../config/ptz.js';
@@ -29,6 +24,8 @@ import {
ViewActionConfig, ViewActionConfig,
internalAdvancedCameraCardCustomActionSchema, internalAdvancedCameraCardCustomActionSchema,
} from '../config/types.js'; } from '../config/types.js';
import { hasAction as customCardHasAction } from '../ha/has-action.js';
import { ActionConfig, ServiceCallRequest } from '../ha/types.js';
import { arrayify } from './basic.js'; import { arrayify } from './basic.js';
/** /**
-20
View File
@@ -13,26 +13,6 @@ import { AdvancedCameraCardError } from '../types';
export type ModifyInterface<T, R> = Omit<T, keyof R> & R; export type ModifyInterface<T, R> = Omit<T, keyof R> & R;
/**
* Dispatch an Advanced Camera Card event.
* @param target The target from which send the event.
* @param name The name of the Advanced Camera Card event to send.
* @param detail An optional detail object to attach.
*/
export function dispatchAdvancedCameraCardEvent<T>(
target: EventTarget,
name: string,
detail?: T,
): void {
target.dispatchEvent(
new CustomEvent<T>(`advanced-camera-card:${name}`, {
bubbles: true,
composed: true,
detail: detail,
}),
);
}
/** /**
* Prettify a title by converting '_' to spaces and capitalizing words. * Prettify a title by converting '_' to spaces and capitalizing words.
* @param input The input string. * @param input The input string.
+1 -1
View File
@@ -1,6 +1,6 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import pkg from '../../package.json'; import pkg from '../../package.json';
import { RawAdvancedCameraCardConfig } from '../config/types'; import { RawAdvancedCameraCardConfig } from '../config/types';
import { HomeAssistant } from '../ha/types';
import { getLanguage } from '../localize/localize'; import { getLanguage } from '../localize/localize';
import { getIntegrationManifest } from './ha/integration'; import { getIntegrationManifest } from './ha/integration';
import { IntegrationManifest } from './ha/integration/types'; import { IntegrationManifest } from './ha/integration/types';
+8 -7
View File
@@ -1,10 +1,11 @@
import { format } from 'date-fns'; import { format } from 'date-fns';
import { CameraManager } from '../camera-manager/manager'; import { CameraManager } from '../camera-manager/manager.js';
import { localize } from '../localize/localize'; import { HomeAssistant } from '../ha/types.js';
import { AdvancedCameraCardError, ExtendedHomeAssistant } from '../types'; import { localize } from '../localize/localize.js';
import { ViewMedia } from '../view/media'; import { AdvancedCameraCardError } from '../types.js';
import { errorToConsole } from './basic'; import { ViewMedia } from '../view/media.js';
import { homeAssistantSignPath } from './ha'; import { errorToConsole } from './basic.js';
import { homeAssistantSignPath } from './ha/index.js';
export const downloadURL = (url: string, filename = 'download'): void => { export const downloadURL = (url: string, filename = 'download'): void => {
// The download attribute only works on the same origin. // The download attribute only works on the same origin.
@@ -27,7 +28,7 @@ export const downloadURL = (url: string, filename = 'download'): void => {
}; };
export const downloadMedia = async ( export const downloadMedia = async (
hass: ExtendedHomeAssistant, hass: HomeAssistant,
cameraManager: CameraManager, cameraManager: CameraManager,
media: ViewMedia, media: ViewMedia,
): Promise<void> => { ): Promise<void> => {
+4 -3
View File
@@ -3,7 +3,8 @@ import { WheelGesturesPlugin } from 'embla-carousel-wheel-gestures';
import { CreatePluginType, LoosePluginType } from 'embla-carousel/components/Plugins'; import { CreatePluginType, LoosePluginType } from 'embla-carousel/components/Plugins';
import isEqual from 'lodash-es/isEqual'; import isEqual from 'lodash-es/isEqual';
import { TransitionEffect } from '../../config/types'; import { TransitionEffect } from '../../config/types';
import { dispatchAdvancedCameraCardEvent, getChildrenFromElement } from '../basic.js'; import { getChildrenFromElement } from '../basic.js';
import { fireAdvancedCameraCardEvent } from '../fire-advanced-camera-card-event';
import { TextDirection } from '../text-direction'; import { TextDirection } from '../text-direction';
export interface CarouselSelected { export interface CarouselSelected {
@@ -99,7 +100,7 @@ export class CarouselController {
// this is used. // this is used.
const newSlide = this.getSlide(index); const newSlide = this.getSlide(index);
if (newSlide) { if (newSlide) {
dispatchAdvancedCameraCardEvent<CarouselSelected>( fireAdvancedCameraCardEvent<CarouselSelected>(
this._parent, this._parent,
'carousel:force-select', 'carousel:force-select',
{ {
@@ -172,7 +173,7 @@ export class CarouselController {
const selectSlide = (): void => { const selectSlide = (): void => {
const carouselSelected = getCarouselSelectedObject(); const carouselSelected = getCarouselSelectedObject();
if (carouselSelected) { if (carouselSelected) {
dispatchAdvancedCameraCardEvent<CarouselSelected>( fireAdvancedCameraCardEvent<CarouselSelected>(
this._parent, this._parent,
'carousel:select', 'carousel:select',
carouselSelected, carouselSelected,
+2 -2
View File
@@ -1,10 +1,10 @@
import { CameraEndpoint } from '../camera-manager/types'; import { CameraEndpoint } from '../camera-manager/types';
import { ExtendedHomeAssistant } from '../types'; import { HomeAssistant } from '../ha/types';
import { errorToConsole } from './basic'; import { errorToConsole } from './basic';
import { homeAssistantSignPath } from './ha'; import { homeAssistantSignPath } from './ha';
export const convertEndpointAddressToSignedWebsocket = async ( export const convertEndpointAddressToSignedWebsocket = async (
hass: ExtendedHomeAssistant, hass: HomeAssistant,
endpoint: CameraEndpoint, endpoint: CameraEndpoint,
expires?: number, expires?: number,
): Promise<string | null> => { ): Promise<string | null> => {
@@ -0,0 +1,25 @@
/**
* Dispatch an Advanced Camera Card event.
* @param target The target from which send the event.
* @param type The type of the Advanced Camera Card event to send.
* @param detail An optional detail object to attach.
*/
export function fireAdvancedCameraCardEvent<T>(
target: EventTarget,
type: string,
detail?: T,
options?: {
bubbles?: boolean;
cancelable?: boolean;
composed?: boolean;
},
): void {
target.dispatchEvent(
new CustomEvent<T>(`advanced-camera-card:${type}`, {
bubbles: options?.bubbles ?? true,
composed: options?.composed ?? true,
cancelable: options?.cancelable ?? false,
detail: detail,
}),
);
}
@@ -1,9 +1,9 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { add } from 'date-fns'; import { add } from 'date-fns';
import chunk from 'lodash-es/chunk'; import chunk from 'lodash-es/chunk';
import orderBy from 'lodash-es/orderBy'; import orderBy from 'lodash-es/orderBy';
import { BrowseMediaMetadata } from '../../../camera-manager/browse-media/types'; import { BrowseMediaMetadata } from '../../../camera-manager/browse-media/types';
import { MemoryRequestCache } from '../../../camera-manager/cache'; import { MemoryRequestCache } from '../../../camera-manager/cache';
import { HomeAssistant } from '../../../ha/types';
import { allPromises } from '../../basic'; import { allPromises } from '../../basic';
import { homeAssistantWSRequest } from '../ws-request'; import { homeAssistantWSRequest } from '../ws-request';
import { import {
+3 -2
View File
@@ -1,6 +1,7 @@
import { computeDomain, HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { HassEntity } from 'home-assistant-js-websocket'; import { HassEntity } from 'home-assistant-js-websocket';
import { Entity } from './registry/entity/types'; import { computeDomain } from '../../ha/compute-domain.js';
import { HomeAssistant } from '../../ha/types.js';
import { Entity } from './registry/entity/types.js';
/** /**
* Get the translation of an entity state. Inspired by: * Get the translation of an entity state. Inspired by:
+7 -13
View File
@@ -1,8 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { HassEntity } from 'home-assistant-js-websocket'; import { HassEntity } from 'home-assistant-js-websocket';
import { STATES_ON } from '../../ha/const.js';
import { HomeAssistant } from '../../ha/types.js';
import { import {
CardHelpers, CardHelpers,
ExtendedHomeAssistant,
LovelaceCardWithEditor, LovelaceCardWithEditor,
SignedPath, SignedPath,
signedPathSchema, signedPathSchema,
@@ -18,7 +18,7 @@ import { homeAssistantWSRequest } from './ws-request.js';
* @returns The signed URL, or null if the response was malformed. * @returns The signed URL, or null if the response was malformed.
*/ */
export async function homeAssistantSignPath( export async function homeAssistantSignPath(
hass: ExtendedHomeAssistant, hass: HomeAssistant,
path: string, path: string,
expires?: number, expires?: number,
): Promise<string | null> { ): Promise<string | null> {
@@ -183,7 +183,7 @@ export const sideLoadHomeAssistantElements = async (): Promise<boolean> => {
* @returns `true` if triggered, `false` otherwise. * @returns `true` if triggered, `false` otherwise.
*/ */
export const isTriggeredState = (state?: string): boolean => { export const isTriggeredState = (state?: string): boolean => {
return !!state && ['on', 'open'].includes(state); return !!state && STATES_ON.includes(state);
}; };
/** /**
@@ -224,15 +224,9 @@ export function isHARelativeURL(url?: string): boolean {
* location will be the Chromecast receiver, not HA). * location will be the Chromecast receiver, not HA).
* @param url The media URL * @param url The media URL
*/ */
export function canonicalizeHAURL(hass: ExtendedHomeAssistant, url: string): string; export function canonicalizeHAURL(hass: HomeAssistant, url: string): string;
export function canonicalizeHAURL( export function canonicalizeHAURL(hass: HomeAssistant, url?: string): string | null;
hass: ExtendedHomeAssistant, export function canonicalizeHAURL(hass: HomeAssistant, url?: string): string | null {
url?: string,
): string | null;
export function canonicalizeHAURL(
hass: ExtendedHomeAssistant,
url?: string,
): string | null {
if (isHARelativeURL(url)) { if (isHARelativeURL(url)) {
return hass.hassUrl(url); return hass.hassUrl(url);
} }
+3 -3
View File
@@ -1,6 +1,6 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../../ha/types.js';
import { homeAssistantWSRequest } from '../ws-request'; import { homeAssistantWSRequest } from '../ws-request.js';
import { IntegrationManifest, integrationManifestSchema } from './types'; import { IntegrationManifest, integrationManifestSchema } from './types.js';
export const getIntegrationManifest = async ( export const getIntegrationManifest = async (
hass: HomeAssistant, hass: HomeAssistant,
+2 -2
View File
@@ -1,6 +1,6 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../../../ha/types';
import { homeAssistantWSRequest } from '../../ws-request';
import { errorToConsole } from '../../../basic'; import { errorToConsole } from '../../../basic';
import { homeAssistantWSRequest } from '../../ws-request';
import { RegistryCache } from '../cache'; import { RegistryCache } from '../cache';
import { Device, DeviceList, deviceListSchema } from './types'; import { Device, DeviceList, deviceListSchema } from './types';
+4 -4
View File
@@ -1,7 +1,7 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../../../../ha/types.js';
import { homeAssistantWSRequest } from '../../ws-request'; import { errorToConsole } from '../../../basic.js';
import { errorToConsole } from '../../../basic'; import { homeAssistantWSRequest } from '../../ws-request.js';
import { RegistryCache } from '../cache'; import { RegistryCache } from '../cache.js';
import { Entity, EntityList, entityListSchema, entitySchema } from './types.js'; import { Entity, EntityList, entityListSchema, entitySchema } from './types.js';
export const createEntityRegistryCache = (): RegistryCache<Entity> => { export const createEntityRegistryCache = (): RegistryCache<Entity> => {
+2 -2
View File
@@ -1,8 +1,8 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import QuickLRU from 'quick-lru'; import QuickLRU from 'quick-lru';
import { homeAssistantWSRequest } from './ws-request'; import { HomeAssistant } from '../../ha/types';
import { ResolvedMedia, resolvedMediaSchema } from '../../types.js'; import { ResolvedMedia, resolvedMediaSchema } from '../../types.js';
import { errorToConsole } from '../basic'; import { errorToConsole } from '../basic';
import { homeAssistantWSRequest } from './ws-request';
// It's important the cache size be at least as large as the largest likely // It's important the cache size be at least as large as the largest likely
// media query or media items will from a given query will be evicted for other // media query or media items will from a given query will be evicted for other
+2 -3
View File
@@ -1,6 +1,5 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CameraProxyConfig } from '../../camera-manager/types'; import { CameraProxyConfig } from '../../camera-manager/types';
import { ExtendedHomeAssistant } from '../../types'; import { HomeAssistant } from '../../ha/types';
export const HASS_WEB_PROXY_DOMAIN = 'hass_web_proxy'; export const HASS_WEB_PROXY_DOMAIN = 'hass_web_proxy';
@@ -29,7 +28,7 @@ export const shouldUseWebProxy = (
* @returns The signed URL, or null if the response was malformed. * @returns The signed URL, or null if the response was malformed.
*/ */
export async function addDynamicProxyURL( export async function addDynamicProxyURL(
hass: ExtendedHomeAssistant, hass: HomeAssistant,
url_pattern: string, url_pattern: string,
options?: { options?: {
urlID?: string; urlID?: string;
+1 -1
View File
@@ -1,6 +1,6 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { MessageBase } from 'home-assistant-js-websocket'; import { MessageBase } from 'home-assistant-js-websocket';
import { ZodSchema } from 'zod'; import { ZodSchema } from 'zod';
import { HomeAssistant } from '../../ha/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { AdvancedCameraCardError } from '../../types'; import { AdvancedCameraCardError } from '../../types';
import { getParseErrorKeys } from '../zod'; import { getParseErrorKeys } from '../zod';
+8 -12
View File
@@ -4,7 +4,7 @@ import {
MediaPlayerController, MediaPlayerController,
MediaTechnology, MediaTechnology,
} from '../types.js'; } from '../types.js';
import { dispatchAdvancedCameraCardEvent } from './basic.js'; import { fireAdvancedCameraCardEvent } from './fire-advanced-camera-card-event.js';
const MEDIA_INFO_HEIGHT_CUTOFF = 50; const MEDIA_INFO_HEIGHT_CUTOFF = 50;
const MEDIA_INFO_WIDTH_CUTOFF = MEDIA_INFO_HEIGHT_CUTOFF; const MEDIA_INFO_WIDTH_CUTOFF = MEDIA_INFO_HEIGHT_CUTOFF;
@@ -75,17 +75,13 @@ export function dispatchMediaLoadedEvent(
/** /**
* Dispatch a pre-existing MediaLoadedInfo object as an event. * Dispatch a pre-existing MediaLoadedInfo object as an event.
* @param element The element to send the event. * @param element The element to send the event.
* @param MediaLoadedInfo The MediaLoadedInfo object to send. * @param mediaLoadedInfo The MediaLoadedInfo object to send.
*/ */
export function dispatchExistingMediaLoadedInfoAsEvent( export function dispatchExistingMediaLoadedInfoAsEvent(
target: EventTarget, target: EventTarget,
MediaLoadedInfo: MediaLoadedInfo, mediaLoadedInfo: MediaLoadedInfo,
): void { ): void {
dispatchAdvancedCameraCardEvent<MediaLoadedInfo>( fireAdvancedCameraCardEvent<MediaLoadedInfo>(target, 'media:loaded', mediaLoadedInfo);
target,
'media:loaded',
MediaLoadedInfo,
);
} }
/** /**
@@ -93,19 +89,19 @@ export function dispatchExistingMediaLoadedInfoAsEvent(
* @param element The element to send the event. * @param element The element to send the event.
*/ */
export function dispatchMediaUnloadedEvent(element: HTMLElement): void { export function dispatchMediaUnloadedEvent(element: HTMLElement): void {
dispatchAdvancedCameraCardEvent(element, 'media:unloaded'); fireAdvancedCameraCardEvent(element, 'media:unloaded');
} }
export function dispatchMediaVolumeChangeEvent(target: HTMLElement): void { export function dispatchMediaVolumeChangeEvent(target: HTMLElement): void {
dispatchAdvancedCameraCardEvent(target, 'media:volumechange'); fireAdvancedCameraCardEvent(target, 'media:volumechange');
} }
export function dispatchMediaPlayEvent(target: HTMLElement): void { export function dispatchMediaPlayEvent(target: HTMLElement): void {
dispatchAdvancedCameraCardEvent(target, 'media:play'); fireAdvancedCameraCardEvent(target, 'media:play');
} }
export function dispatchMediaPauseEvent(target: HTMLElement): void { export function dispatchMediaPauseEvent(target: HTMLElement): void {
dispatchAdvancedCameraCardEvent(target, 'media:pause'); fireAdvancedCameraCardEvent(target, 'media:pause');
} }
/** /**
+1 -1
View File
@@ -1,6 +1,6 @@
import { Task } from '@lit-labs/task'; import { Task } from '@lit-labs/task';
import { ReactiveControllerHost } from '@lit/reactive-element'; import { ReactiveControllerHost } from '@lit/reactive-element';
import { HomeAssistant } from '@dermotduffy/custom-card-helpers'; import { HomeAssistant } from '../ha/types';
// See: https://github.com/sindresorhus/is-absolute-url // See: https://github.com/sindresorhus/is-absolute-url
// Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 // Scheme: https://tools.ietf.org/html/rfc3986#section-3.1

Some files were not shown because too many files have changed in this diff Show More