import { CSSResultGroup, LitElement, PropertyValues, TemplateResult, html, unsafeCSS, } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { actionHandler } from '../action-handler-directive.js'; import { CameraManager } from '../camera-manager/manager.js'; import { PTZController } from '../components-lib/ptz/ptz-controller.js'; import { PTZControllerActions } from '../components-lib/ptz/types.js'; import { Actions } from '../config/schema/actions/types.js'; import { PTZControlsConfig } from '../config/schema/common/controls/ptz.js'; import { HomeAssistant } from '../ha/types.js'; import { localize } from '../localize/localize.js'; import ptzStyle from '../scss/ptz.scss'; import { Interaction } from '../types.js'; import { hasAction } from '../utils/action.js'; import { prettifyTitle } from '../utils/basic.js'; import './icon.js'; import './submenu'; import { SubmenuInteraction, SubmenuItem } from './submenu/types.js'; @customElement('advanced-camera-card-ptz') export class AdvancedCameraCardPTZ extends LitElement { public hass?: HomeAssistant; @property({ attribute: false }) public config?: PTZControlsConfig; @property({ attribute: false }) public cameraManager?: CameraManager; @property({ attribute: false }) public cameraID?: string; @property({ attribute: false }) public forceVisibility?: boolean; protected _controller = new PTZController(this); protected _actions: PTZControllerActions | null = null; protected willUpdate(changedProps: PropertyValues): void { if (changedProps.has('config')) { this._controller.setConfig(this.config); } if (changedProps.has('cameraManager') || changedProps.has('cameraID')) { this._controller.setCamera(this.cameraManager, this.cameraID); } if (changedProps.has('forceVisibility')) { this._controller.setForceVisibility(this.forceVisibility); } if (changedProps.has('cameraID') || changedProps.has('cameraManager')) { this._actions = this._controller.getPTZActions(); } } protected render(): TemplateResult | void { if (!this._controller.shouldDisplay()) { return; } const renderIcon = ( name: string, icon: string, options?: { actions?: Actions | null; renderWithoutAction?: boolean; }, ): TemplateResult => { const classes = { [name]: true, disabled: !options?.actions && !options?.renderWithoutAction, }; return options?.actions || options?.renderWithoutAction ? html`) => options.actions && this._controller.handleAction(ev, options.actions)} >` : html``; }; const presetSubmenuItems: SubmenuItem[] | null = this._actions?.presets?.length ? this._actions.presets.map((preset) => ({ title: prettifyTitle(preset.preset), icon: 'mdi:cctv', ...preset.actions, hold_action: { action: 'perform-action', perform_action: 'camera.preset_recall', }, })) : null; const config = this._controller.getConfig(); return html`
${!config?.hide_pan_tilt && (this._actions?.left || this._actions?.right || this._actions?.up || this._actions?.down) ? html`
${renderIcon('right', 'mdi:arrow-right', { actions: this._actions?.right })} ${renderIcon('left', 'mdi:arrow-left', { actions: this._actions?.left })} ${renderIcon('up', 'mdi:arrow-up', { actions: this._actions?.up })} ${renderIcon('down', 'mdi:arrow-down', { actions: this._actions?.down })}
` : ''} ${!config?.hide_zoom && (this._actions?.zoom_in || this._actions?.zoom_out) ? html`
${renderIcon('zoom_in', 'mdi:plus', { actions: this._actions.zoom_in })} ${renderIcon('zoom_out', 'mdi:minus', { actions: this._actions.zoom_out })}
` : html``} ${!config?.hide_home && (this._actions?.home || presetSubmenuItems?.length) ? html`
${renderIcon('home', 'mdi:home', { actions: this._actions?.home })} ${presetSubmenuItems?.length ? html`) => this._controller.handleAction(ev)} > ${renderIcon( 'presets', config?.orientation === 'vertical' ? 'mdi:dots-vertical' : 'mdi:dots-horizontal', { renderWithoutAction: true, }, )} ` : ''}
` : ''}
`; } static get styles(): CSSResultGroup { return unsafeCSS(ptzStyle); } } declare global { interface HTMLElementTagNameMap { 'advanced-camera-card-ptz': AdvancedCameraCardPTZ; } }