fix: Use HA style and coloring for all icons (#1790)

This commit is contained in:
Dermot Duffy
2024-12-23 15:22:27 -08:00
committed by GitHub
parent a9e5889ca7
commit 9d812af9f4
68 changed files with 557 additions and 1366 deletions
+4 -3
View File
@@ -5,6 +5,7 @@ import { localize } from '../localize/localize';
import datePickerStyle from '../scss/date-picker.scss';
import { stopEventFromActivatingCardWideActions } from '../utils/action';
import { dispatchFrigateCardEvent } from '../utils/basic';
import './icon';
export interface DatePickerEvent {
date: Date | null;
@@ -44,16 +45,16 @@ export class FrigateCardDatePicker extends LitElement {
@input=${() => changed()}
@change=${() => changed()}
/>
<ha-icon
<frigate-card-icon
aria-label="${localize('timeline.select_date')}"
title="${localize('timeline.select_date')}"
.icon=${this.icon ?? `mdi:calendar-search`}
.icon=${{ icon: this.icon ?? `mdi:calendar-search` }}
@click=${(ev: Event) => {
stopEventFromActivatingCardWideActions(ev);
this._refInput.value?.showPicker();
}}
>
</ha-icon>`;
</frigate-card-icon>`;
}
static get styles(): CSSResultGroup {
+8 -5
View File
@@ -14,6 +14,7 @@ import drawerInjectStyle from '../scss/drawer-inject.scss';
import drawerStyle from '../scss/drawer.scss';
import { stopEventFromActivatingCardWideActions } from '../utils/action';
import { getChildrenFromElement, isHoverableDevice } from '../utils/basic';
import './icon';
export interface DrawerIcons {
open?: string;
@@ -121,11 +122,13 @@ export class FrigateCardDrawer extends LitElement {
this.open = !this.open;
}}
>
<ha-icon
<frigate-card-icon
class="control"
icon="${this.open
? this.icons?.open ?? 'mdi:menu-open'
: this.icons?.closed ?? 'mdi:menu'}"
.icon="${{
icon: this.open
? this.icons?.open ?? 'mdi:menu-open'
: this.icons?.closed ?? 'mdi:menu',
}}"
@mouseenter=${() => {
// Only open the drawer on mousenter when the device
// supports hover (otherwise iOS may end up passing on
@@ -136,7 +139,7 @@ export class FrigateCardDrawer extends LitElement {
}
}}
>
</ha-icon>
</frigate-card-icon>
</div>
`
: ''}
+54
View File
@@ -0,0 +1,54 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { IconController } from '../components-lib/icon-controller';
import iconStyle from '../scss/icon.scss';
import { Icon } from '../types';
@customElement('frigate-card-icon')
export class FrigateCardIcon extends LitElement {
@property({ attribute: false })
public hass?: HomeAssistant;
@property({ attribute: false })
public icon?: Icon;
private _controller = new IconController();
protected render(): TemplateResult {
const customIconURL = this._controller.getCustomIcon(this.icon);
if (customIconURL) {
return html`<img src="${customIconURL}" />`;
}
if (this.icon?.icon) {
return html`<ha-icon icon="${this.icon.icon}"></ha-icon>`;
}
if (this.hass && this.icon?.entity) {
const stateObj = this._controller.createStateObjectForStateBadge(
this.hass,
this.icon.entity,
);
if (stateObj) {
return html`<state-badge
.stateColor=${this.icon.stateColor ?? true}
.hass=${this.hass}
.stateObj=${stateObj}
></state-badge>`;
}
}
if (this.icon?.fallback) {
return html`<ha-icon icon="${this.icon.fallback}"></ha-icon>`;
}
return html``;
}
static get styles(): CSSResultGroup {
return unsafeCSS(iconStyle);
}
}
declare global {
interface HTMLElementTagNameMap {
'frigate-card-icon': FrigateCardIcon;
}
}
+6 -7
View File
@@ -12,6 +12,7 @@ import { KeyAssignerController } from '../components-lib/key-assigner-controller
import { KeyboardShortcut } from '../config/keyboard-shortcuts';
import keyAssignerStyle from '../scss/key-assigner.scss';
import { localize } from '../localize/localize';
import './icon';
@customElement('frigate-card-key-assigner')
export class FrigateCardKeyAssigner extends LitElement {
@@ -48,15 +49,11 @@ export class FrigateCardKeyAssigner extends LitElement {
this._controller.toggleAssigning();
}}
>
<ha-icon icon="mdi:keyboard-settings"></ha-icon>
<frigate-card-icon .icon=${{ icon: 'mdi:keyboard-settings' }}></frigate-card-icon>
<span class="${classMap({
dotdotdot: this._controller.isAssigning(),
})}">
${
this._controller.isAssigning()
? localize('key_assigner.assigning')
: localize('key_assigner.assign')
}
${this._controller.isAssigning() ? '' : localize('key_assigner.assign')}
</span>
</ha-button>
${
@@ -66,7 +63,9 @@ export class FrigateCardKeyAssigner extends LitElement {
this._controller.setValue(null);
}}
>
<ha-icon icon="mdi:keyboard-off"></ha-icon>
<frigate-card-icon
.icon=${{ icon: 'mdi:keyboard-off' }}
></frigate-card-icon>
<span> ${localize('key_assigner.unassign')} </span>
</ha-button>`
: ''
+5 -4
View File
@@ -11,6 +11,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { guard } from 'lit/directives/guard.js';
import { createRef, Ref, ref } from 'lit/directives/ref.js';
import { CameraEndpoints } from '../../camera-manager/types.js';
import { dispatchLiveErrorEvent } from '../../components-lib/live/utils/dispatch-live-error.js';
import { PartialZoomSettings } from '../../components-lib/zoom/types.js';
import {
CameraConfig,
@@ -26,11 +27,11 @@ import { aspectRatioToString } from '../../utils/basic.js';
import { dispatchMediaUnloadedEvent } from '../../utils/media-info.js';
import { updateElementStyleFromMediaLayoutConfig } from '../../utils/media-layout.js';
import { playMediaMutingIfNecessary } from '../../utils/media.js';
import '../icon.js';
import { renderMessage } from '../message.js';
import '../next-prev-control.js';
import '../ptz.js';
import '../surround.js';
import { dispatchLiveErrorEvent } from '../../components-lib/live/utils/dispatch-live-error.js';
@customElement('frigate-card-live-provider')
export class FrigateCardLiveProvider
@@ -385,10 +386,10 @@ export class FrigateCardLiveProvider
: html``}
`)}
${showImageDuringLoading && !this._isVideoMediaLoaded
? html`<ha-icon
? html`<frigate-card-icon
title=${localize('error.awaiting_live')}
icon="mdi:progress-helper"
></ha-icon>`
.icon=${{ icon: 'mdi:progress-helper' }}
></frigate-card-icon>`
: ''} `;
}
+17 -25
View File
@@ -1,15 +1,15 @@
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js';
import { actionHandler } from '../action-handler-directive.js';
import { MenuController } from '../components-lib/menu-controller.js';
import type { MenuConfig, MenuItem } from '../config/types.js';
import menuStyle from '../scss/menu.scss';
import { frigateCardHasAction } from '../utils/action.js';
import { getCustomIconURL } from '../utils/custom-icons.js';
import { getEntityTitle } from '../utils/ha/index.js';
import { EntityRegistryManager } from '../utils/ha/registry/entity/index.js';
import './icon.js';
import './submenu.js';
@customElement('frigate-card-menu')
@@ -60,38 +60,30 @@ export class FrigateCardMenu extends LitElement {
</frigate-card-submenu-select>`;
}
// =====================================================================================
// For `data-domain` and `data-state`, see: See
// https://github.com/home-assistant/frontend/blob/dev/src/components/entity/state-badge.ts#L54
// =====================================================================================
// Buttons are styled in a few ways (in order of precedence):
//
// - User provided style
// - Color/Brightness styling for the `light` domain (calculated in
// `refreshDynamicStateParameters`)
// - Static styling based on domain (`data-domain`) and state
// (`data-state`). This looks up a CSS style in `menu.scss`.
const buttonState = this._controller.getFreshButtonState(this.hass, button);
const customImageURL = getCustomIconURL(buttonState.icon);
const title =
this.hass && button.type === 'custom:frigate-card-menu-state-icon' && !button.title
? getEntityTitle(this.hass, button.entity)
: button.title;
return html` <ha-icon-button
data-domain=${ifDefined(buttonState.data_domain)}
data-state=${ifDefined(buttonState.data_state)}
class="button"
style="${styleMap(buttonState.style || {})}"
style="${styleMap(button.style || {})}"
.actionHandler=${actionHandler({
hasHold: frigateCardHasAction(button.hold_action),
hasDoubleClick: frigateCardHasAction(button.double_tap_action),
})}
.label=${buttonState.title || ''}
.label=${title ?? ''}
@action=${(ev) => this._controller.actionHandler(ev, button)}
>
${customImageURL
? html`<img src="${customImageURL}" />`
: html`<ha-icon
icon="${buttonState.icon || 'mdi:gesture-tap-button'}"
></ha-icon>`}
<frigate-card-icon
.hass=${this.hass}
.icon=${{
icon: button.icon,
entity: button.entity,
stateColor: button.state_color,
fallback: 'mdi:gesture-tap-button',
}}
></frigate-card-icon>
</ha-icon-button>`;
}
+6 -3
View File
@@ -9,6 +9,7 @@ import { localize } from '../localize/localize.js';
import messageStyle from '../scss/message.scss';
import { FrigateCardError, Message, MessageType } from '../types.js';
import { dispatchFrigateCardEvent } from '../utils/basic.js';
import './icon.js';
@customElement('frigate-card-message')
export class FrigateCardMessage extends LitElement {
@@ -38,7 +39,7 @@ export class FrigateCardMessage extends LitElement {
return html` <div class="wrapper">
<div class="message padded">
<div class="icon">
<ha-icon icon="${icon}"> </ha-icon>
<frigate-card-icon .icon="${{ icon: icon }}"></frigate-card-icon>
</div>
<div class="contents">
<span class="${classMap(classes)}">
@@ -103,9 +104,11 @@ export class FrigateCardProgressIndicator extends LitElement {
protected render(): TemplateResult {
return html` <div class="message vertical">
${this.animated
? html`<ha-circular-progress active="true" size="${this.size}">
? html`<ha-circular-progress indeterminate size="${this.size}">
</ha-circular-progress>`
: html`<ha-icon icon="mdi:timer-sand"></ha-icon>`}
: html`<frigate-card-icon
.icon=${{ icon: 'mdi:timer-sand' }}
></frigate-card-icon>`}
${this.message ? html`<span>${this.message}</span>` : html``}
</div>`;
}
+8 -10
View File
@@ -4,6 +4,7 @@ import { customElement, property, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { NextPreviousControlConfig } from '../config/types.js';
import controlStyle from '../scss/next-previous-control.scss';
import { Icon } from '../types.js';
import { renderTask } from '../utils/task.js';
import { createFetchThumbnailTask } from '../utils/thumbnail.js';
@@ -29,7 +30,7 @@ export class FrigateCardNextPreviousControl extends LitElement {
public thumbnail?: string;
@property({ attribute: false })
public icon?: string;
public icon?: Icon;
@property({ attribute: true, type: Boolean })
public disabled = false;
@@ -67,17 +68,14 @@ export class FrigateCardNextPreviousControl extends LitElement {
if (renderIcon) {
const icon =
!this.thumbnail ||
!this.icon ||
this._controlConfig.style === 'chevrons' ||
this._thumbnailError
? this.side === 'left'
? 'mdi:chevron-left'
: 'mdi:chevron-right'
: this.icon;
this.icon && !this._thumbnailError && this._controlConfig.style !== 'chevrons'
? this.icon
: this.side === 'left'
? { icon: 'mdi:chevron-left' }
: { icon: 'mdi:chevron-right' };
return html` <ha-icon-button class="${classMap(classes)}" .label=${this.label}>
<ha-icon icon=${icon}></ha-icon>
<frigate-card-icon .hass=${this.hass} .icon=${icon}></frigate-card-icon>
</ha-icon-button>`;
}
+4 -3
View File
@@ -17,6 +17,7 @@ import { Actions, PTZControlsConfig } from '../config/types.js';
import { localize } from '../localize/localize.js';
import ptzStyle from '../scss/ptz.scss';
import { frigateCardHasAction } from '../utils/action.js';
import './icon.js';
@customElement('frigate-card-ptz')
export class FrigateCardPTZ extends LitElement {
@@ -67,9 +68,9 @@ export class FrigateCardPTZ extends LitElement {
};
return actions
? html`<ha-icon
? html`<frigate-card-icon
class=${classMap(classes)}
icon=${icon}
.icon=${{ icon: icon }}
.actionHandler=${actionHandler({
hasHold: frigateCardHasAction(actions?.hold_action),
hasDoubleClick: frigateCardHasAction(actions?.double_tap_action),
@@ -77,7 +78,7 @@ export class FrigateCardPTZ extends LitElement {
.title=${localize(`elements.ptz.${name}`)}
@action=${(ev: HASSDomEvent<{ action: string }>) =>
this._controller.handleAction(ev, actions)}
></ha-icon>`
></frigate-card-icon>`
: html``;
};
+7 -15
View File
@@ -13,7 +13,7 @@ import { StatusBarController } from '../components-lib/status-bar-controller';
import { StatusBarConfig, StatusBarItem } from '../config/types';
import statusStyle from '../scss/status.scss';
import { frigateCardHasAction } from '../utils/action';
import { getCustomIconURL } from '../utils/custom-icons.js';
import './icon.js';
@customElement('frigate-card-status-bar')
export class FrigateCardStatusBar extends LitElement {
@@ -68,20 +68,12 @@ export class FrigateCardStatusBar extends LitElement {
${item.string}
</div>`;
} else if (item.type === 'custom:frigate-card-status-bar-icon') {
const customIconURL = getCustomIconURL(item.icon);
return customIconURL
? html`<img
.actionHandler=${handler}
class="${classes}"
src="${customIconURL}"
@action=${(ev) => this._controller.actionHandler(ev, item.actions)}
/>`
: html`<ha-icon
.actionHandler=${handler}
class="${classes}"
icon="${item.icon}"
@action=${(ev) => this._controller.actionHandler(ev, item.actions)}
></ha-icon>`;
return html`<frigate-card-icon
.actionHandler=${handler}
.icon=${{ icon: item.icon }}
class="${classes}"
@action=${(ev) => this._controller.actionHandler(ev, item.actions)}
></frigate-card-icon>`;
} else if (item.type === 'custom:frigate-card-status-bar-image') {
return html`<img
.actionHandler=${handler}
+40 -43
View File
@@ -13,16 +13,21 @@ import { StyleInfo, styleMap } from 'lit/directives/style-map.js';
import { actionHandler } from '../action-handler-directive.js';
import { MenuSubmenu, MenuSubmenuItem, MenuSubmenuSelect } from '../config/types.js';
import submenuStyle from '../scss/submenu.scss';
import { StateParameters } from '../types.js';
import {
frigateCardHasAction,
stopEventFromActivatingCardWideActions,
} from '../utils/action.js';
import { getCustomIconURL } from '../utils/custom-icons.js';
import { isHassDifferent, refreshDynamicStateParameters } from '../utils/ha';
import { getEntityTitle, isHassDifferent } from '../utils/ha';
import { getEntityStateTranslation } from '../utils/ha/entity-state-translation.js';
import { EntityRegistryManager } from '../utils/ha/registry/entity/index.js';
import { domainIcon } from '../utils/icons/domain-icon.js';
import './icon.js';
import { Icon } from '../types.js';
interface ExtendedMenuSubmenu extends MenuSubmenu {
// An internal version of a submenu that allows entity-based submenus (for
// FrigateCardSubmenuSelect).
icon: string | Icon;
}
@customElement('frigate-card-submenu')
export class FrigateCardSubmenu extends LitElement {
@@ -30,47 +35,23 @@ export class FrigateCardSubmenu extends LitElement {
public hass?: HomeAssistant;
@property({ attribute: false })
public submenu?: MenuSubmenu;
public submenu?: ExtendedMenuSubmenu;
protected _renderItem(item: MenuSubmenuItem): TemplateResult | void {
if (!this.hass) {
return;
}
const stateParameters = refreshDynamicStateParameters(this.hass, {
...item,
} as StateParameters);
const getIcon = (stateParameters: StateParameters): TemplateResult => {
if (stateParameters.icon) {
const url = getCustomIconURL(stateParameters.icon);
return url
? html`<img
style="${styleMap(stateParameters.style || {})}"
data-domain=${ifDefined(stateParameters.data_domain)}
data-state=${ifDefined(stateParameters.data_state)}
slot="graphic"
src=${url}
/>`
: html` <ha-icon
style="${styleMap(stateParameters.style || {})}"
data-domain=${ifDefined(stateParameters.data_domain)}
data-state=${ifDefined(stateParameters.data_state)}
slot="graphic"
icon="${stateParameters.icon || ''}"
>
</ha-icon>`;
}
return html``;
};
const title = item.title ?? getEntityTitle(this.hass, item.entity);
return html`
<mwc-list-item
style="${styleMap(stateParameters.style || {})}"
graphic=${ifDefined(stateParameters.icon ? 'icon' : undefined)}
style="${styleMap(item.style || {})}"
graphic=${ifDefined(item.icon || item.entity ? 'icon' : undefined)}
?twoline=${!!item.subtitle}
?selected=${item.selected}
?activated=${item.selected}
?disabled=${item.enabled === false}
aria-label="${stateParameters.title || ''}"
aria-label="${title ?? ''}"
@action=${(ev) => {
// Attach the action config so ascendants have access to it.
ev.detail.config = item;
@@ -80,9 +61,17 @@ export class FrigateCardSubmenu extends LitElement {
hasDoubleClick: frigateCardHasAction(item.double_tap_action),
})}
>
<span>${stateParameters.title || ''}</span>
<span>${title ?? ''}</span>
${item.subtitle ? html`<span slot="secondary">${item.subtitle}</span>` : ''}
${getIcon(stateParameters)}
<frigate-card-icon
slot="graphic"
.hass=${this.hass}
.icon=${{
icon: item.icon,
entity: item.entity,
}}
style="${styleMap(item.style || {})}"
></frigate-card-icon>
</mwc-list-item>
`;
}
@@ -118,7 +107,14 @@ export class FrigateCardSubmenu extends LitElement {
hasDoubleClick: frigateCardHasAction(this.submenu.double_tap_action),
})}
>
<ha-icon icon="${this.submenu.icon}"></ha-icon>
<frigate-card-icon
.hass=${this.hass}
.icon=${typeof this.submenu.icon === 'string'
? {
icon: this.submenu.icon,
}
: this.submenu.icon}
></frigate-card-icon>
</ha-icon-button>
${items.map(this._renderItem.bind(this))}
</ha-button-menu>
@@ -207,18 +203,19 @@ export class FrigateCardSubmenuSelect extends LitElement {
return;
}
const title = getEntityTitle(this.hass, entityID);
const submenu: MenuSubmenu = {
// Default icon. It should be impossible for this to be used, since
// this.submenuSelect will always have an entity, which means
// refreshDynamicStateParameters will always return an icon.
icon: domainIcon('select'),
// Pull out the dynamic properties (like icon, and title) from the state.
...refreshDynamicStateParameters(this.hass, this.submenuSelect as StateParameters),
...(title && { title }),
// Override it with anything explicitly set in the submenuSelect.
...this.submenuSelect,
icon: {
icon: this.submenuSelect.icon,
entity: entityID,
fallback: 'mdi:format-list-bulleted',
},
type: 'custom:frigate-card-menu-submenu',
items: [],
};
+49 -40
View File
@@ -105,10 +105,10 @@ export class FrigateCardThumbnailFeatureThumbnail extends LitElement {
}
protected render(): TemplateResult | void {
const imageOff = html`<ha-icon
icon="mdi:image-off"
const imageOff = html`<frigate-card-icon
.icon=${{ icon: 'mdi:image-off' }}
title=${localize('thumbnail.no_thumbnail')}
></ha-icon> `;
></frigate-card-icon> `;
if (!this._embedThumbnailTask || this._thumbnailError) {
return imageOff;
@@ -150,8 +150,11 @@ export class FrigateCardThumbnailFeatureText extends LitElement {
return;
}
return html`
${this.cameraMetadata?.engineLogo
? html`<img class="background" src="${this.cameraMetadata.engineLogo}" />`
${this.cameraMetadata?.engineIcon
? html`<frigate-card-icon
class="background"
.icon=${{ icon: this.cameraMetadata.engineIcon }}
></frigate-card-icon>`
: ''}
<div class="content">
<div class="title">${format(this.date, 'HH:mm')}</div>
@@ -211,18 +214,18 @@ export class FrigateCardThumbnailDetailsEvent extends LitElement {
<div class="details">
${startTime
? html` <div>
<ha-icon
<frigate-card-icon
title=${localize('event.start')}
.icon=${'mdi:calendar-clock-outline'}
></ha-icon>
.icon=${{ icon: 'mdi:calendar-clock-outline' }}
></frigate-card-icon>
<span title="${startTime}">${startTime}</span>
</div>
${duration || inProgress
? html` <div>
<ha-icon
<frigate-card-icon
title=${localize('event.duration')}
.icon=${'mdi:clock-outline'}
></ha-icon>
.icon=${{ icon: 'mdi:clock-outline' }}
></frigate-card-icon>
${duration ? html`<span title="${duration}">${duration}</span>` : ''}
${inProgress
? html`<span title="${inProgress}">${inProgress}</span>`
@@ -232,31 +235,37 @@ export class FrigateCardThumbnailDetailsEvent extends LitElement {
: ''}
${this.cameraTitle
? html` <div>
<ha-icon title=${localize('event.camera')} .icon=${'mdi:cctv'}></ha-icon>
<frigate-card-icon
title=${localize('event.camera')}
.icon=${{ icon: 'mdi:cctv' }}
></frigate-card-icon>
<span title="${this.cameraTitle}">${this.cameraTitle}</span>
</div>`
: ''}
${where
? html` <div>
<ha-icon
<frigate-card-icon
title=${localize('event.where')}
.icon=${'mdi:map-marker-outline'}
></ha-icon>
.icon=${{ icon: 'mdi:map-marker-outline' }}
></frigate-card-icon>
<span title="${where}">${where}</span>
</div>`
: html``}
${tags
? html` <div>
<ha-icon title=${localize('event.tag')} .icon=${'mdi:tag'}></ha-icon>
<frigate-card-icon
title=${localize('event.tag')}
.icon=${{ icon: 'mdi:tag' }}
></frigate-card-icon>
<span title="${tags}">${tags}</span>
</div>`
: html``}
${seek
? html` <div>
<ha-icon
<frigate-card-icon
title=${localize('event.seek')}
.icon=${'mdi:clock-fast'}
></ha-icon>
.icon=${{ icon: 'mdi:clock-fast' }}
></frigate-card-icon>
<span title="${seek}">${seek}</span>
</div>`
: html``}
@@ -306,18 +315,18 @@ export class FrigateCardThumbnailDetailsRecording extends LitElement {
<div class="details">
${startTime
? html` <div>
<ha-icon
<frigate-card-icon
title=${localize('recording.start')}
.icon=${'mdi:calendar-clock-outline'}
></ha-icon>
.icon=${{ icon: 'mdi:calendar-clock-outline' }}
></frigate-card-icon>
<span title="${startTime}">${startTime}</span>
</div>
${duration || inProgress
? html` <div>
<ha-icon
<frigate-card-icon
title=${localize('recording.duration')}
.icon=${'mdi:clock-outline'}
></ha-icon>
.icon=${{ icon: 'mdi:clock-outline' }}
></frigate-card-icon>
${duration ? html`<span title="${duration}">${duration}</span>` : ''}
${inProgress
? html`<span title="${inProgress}">${inProgress}</span>`
@@ -327,19 +336,19 @@ export class FrigateCardThumbnailDetailsRecording extends LitElement {
: ''}
${seek
? html` <div>
<ha-icon
<frigate-card-icon
title=${localize('event.seek')}
.icon=${'mdi:clock-fast'}
></ha-icon>
.icon=${{ icon: 'mdi:clock-fast' }}
></frigate-card-icon>
<span title="${seek}">${seek}</span>
</div>`
: html``}
${eventCount !== null
? html`<div>
<ha-icon
<frigate-card-icon
title=${localize('recording.events')}
.icon=${'mdi:shield-alert'}
></ha-icon>
.icon=${{ icon: 'mdi:shield-alert' }}
></frigate-card-icon>
<span title="${eventCount}">${eventCount}</span>
</div>`
: ``}
@@ -448,10 +457,10 @@ export class FrigateCardThumbnail extends LitElement {
></frigate-card-thumbnail-feature-text>`
: html``}
${shouldShowFavoriteControl
? html` <ha-icon
? html` <frigate-card-icon
class="${classMap(starClasses)}"
icon=${this.media.isFavorite() ? 'mdi:star' : 'mdi:star-outline'}
title=${localize('thumbnail.retain_indefinitely')}
.icon=${{ icon: this.media.isFavorite() ? 'mdi:star' : 'mdi:star-outline' }}
@click=${async (ev: Event) => {
stopEventFromActivatingCardWideActions(ev);
if (this.hass && this.media) {
@@ -467,7 +476,7 @@ export class FrigateCardThumbnail extends LitElement {
this.requestUpdate();
}
}}
/></ha-icon>`
/></frigate-card-icon>`
: ``}
${this.details && ViewMediaClassifier.isEvent(this.media)
? html`<frigate-card-thumbnail-details-event
@@ -483,9 +492,9 @@ export class FrigateCardThumbnail extends LitElement {
></frigate-card-thumbnail-details-recording>`
: html``}
${shouldShowTimelineControl
? html`<ha-icon
? html`<frigate-card-icon
class="timeline"
icon="mdi:target"
.icon=${{ icon: 'mdi:target' }}
title=${localize('thumbnail.timeline')}
@click=${(ev: Event) => {
stopEventFromActivatingCardWideActions(ev);
@@ -503,12 +512,12 @@ export class FrigateCardThumbnail extends LitElement {
modifiers: [new RemoveContextViewModifier(['timeline'])],
});
}}
></ha-icon>`
></frigate-card-icon>`
: ''}
${shouldShowDownloadControl
? html` <ha-icon
? html` <frigate-card-icon
class="download"
icon=${'mdi:download'}
.icon=${{ icon: 'mdi:download' }}
title=${localize('thumbnail.download')}
@click=${async (ev: Event) => {
stopEventFromActivatingCardWideActions(ev);
@@ -520,7 +529,7 @@ export class FrigateCardThumbnail extends LitElement {
}
}
}}
></ha-icon>`
></frigate-card-icon>`
: ``}
`;
}
+4 -3
View File
@@ -69,6 +69,7 @@ import { MediaQueriesResults } from '../view/media-queries-results';
import { mergeViewContext } from '../view/view';
import './date-picker.js';
import { DatePickerEvent, FrigateCardDatePicker } from './date-picker.js';
import './icon';
import './thumbnail.js';
interface FrigateCardGroupData {
@@ -304,8 +305,8 @@ export class FrigateCardTimelineCore extends LitElement {
>
<div class="timeline-tools">
${this._shouldSupportSeeking()
? html` <ha-icon
.icon=${panIcon}
? html` <frigate-card-icon
.icon=${{ icon: panIcon }}
@click=${() => {
this._panMode =
panMode === 'pan'
@@ -319,7 +320,7 @@ export class FrigateCardTimelineCore extends LitElement {
aria-label="${panTitle}"
title="${panTitle}"
>
</ha-icon>`
</frigate-card-icon>`
: ''}
<frigate-card-date-picker
${ref(this._refDatePicker)}
+5 -2
View File
@@ -402,8 +402,11 @@ export class FrigateCardViewerCarousel extends LitElement {
</frigate-card-ptz>`
: ''}
<div class="seek-warning">
<ha-icon title="${localize('media_viewer.unseekable')}" icon="mdi:clock-remove">
</ha-icon>
<frigate-card-icon
title="${localize('media_viewer.unseekable')}"
.icon=${{ icon: 'mdi:clock-remove' }}
>
</frigate-card-icon>
</div>
`;
}