import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { TROUBLESHOOTING_URL } from '../const.js'; import { localize } from '../localize/localize.js'; import messageStyle from '../scss/message.scss'; import { CardWideConfig, FrigateCardError, Message, MessageType } from '../types.js'; import { dispatchFrigateCardEvent } from '../utils/basic.js'; @customElement('frigate-card-message') export class FrigateCardMessage extends LitElement { @property({ attribute: false }) public message: string | TemplateResult<1> = ''; @property({ attribute: false }) public context?: unknown; @property({ attribute: false }) public icon?: string; @property({ attribute: true, type: Boolean }) public dotdotdot?: boolean; // Render the menu. protected render(): TemplateResult { const icon = this.icon ? this.icon : 'mdi:information-outline'; const classes = { dotdotdot: !!this.dotdotdot, }; return html`
${this.message ? html`${this.message}${this.context && typeof this.context === 'string' ? ': ' + this.context : ''}` : ''} ${this.context && typeof this.context !== 'string' ? html`
${JSON.stringify(this.context, null, 2)}
` : ''}
`; } static get styles(): CSSResultGroup { return unsafeCSS(messageStyle); } } @customElement('frigate-card-error-message') export class FrigateCardErrorMessage extends LitElement { @property({ attribute: false }) public message?: Message; protected render(): TemplateResult | void { if (!this.message) { return; } return html` ${localize('error.troubleshooting')}.`} .icon=${'mdi:alert-circle'} .context=${this.message.context} .dotdotdot=${this.message.dotdotdot} > `; } static get styles(): CSSResultGroup { return unsafeCSS(messageStyle); } } @customElement('frigate-card-progress-indicator') export class FrigateCardProgressIndicator extends LitElement { @property({ attribute: false }) public message: string | TemplateResult = ''; @property({ attribute: false }) public animated = false; protected render(): TemplateResult { return html`
${this.animated ? html` ` : html``} ${this.message ? html`${this.message}` : html``}
`; } static get styles(): CSSResultGroup { return unsafeCSS(messageStyle); } } export function renderMessage(message: Message): TemplateResult { if (message.type === 'error') { return html` `; } else { return html` `; } return html``; } export function renderProgressIndicator(options?: { message?: string; cardWideConfig?: CardWideConfig; }): TemplateResult { return html` `; } /** * Dispatch an event with a message to show to the user. * @param element The element to send the event. * @param message The message to show. * @param options Optional icon and context to include. */ export function dispatchMessageEvent( element: EventTarget, message: string, type: MessageType, options?: { icon?: string; context?: unknown; }, ): void { dispatchFrigateCardEvent(element, 'message', { message: message, type: type, icon: options?.icon, context: options?.context, }); } /** * Dispatch an event with an error message to show to the user. * @param element The element to send the event. * @param message The message to show. * @param options Optional context to include. */ export function dispatchErrorMessageEvent( element: EventTarget, message: string, options?: { context?: unknown; }, ): void { dispatchMessageEvent(element, message, 'error', { context: options?.context, }); } /** * Dispatch an event with an error message to show to the user. * @param element The element to send the event. * @param message The message to show. */ export function dispatchFrigateCardErrorEvent( element: EventTarget, error: FrigateCardError | Error, ): void { dispatchErrorMessageEvent(element, error.message, { ...(error instanceof FrigateCardError && { context: error.context }), }); } declare global { interface HTMLElementTagNameMap { 'frigate-card-progress-indicator': FrigateCardProgressIndicator; 'frigate-card-error-message': FrigateCardErrorMessage; 'frigate-card-message': FrigateCardMessage; } }