diff --git a/src/components/ha-hls-player.ts b/src/components/ha-hls-player.ts index 0be5f97535..70a91b7e5e 100644 --- a/src/components/ha-hls-player.ts +++ b/src/components/ha-hls-player.ts @@ -165,7 +165,7 @@ class HaHLSPlayer extends LitElement { window.addEventListener("resize", this._resizeExoPlayer); this.updateComplete.then(() => nextRender()).then(this._resizeExoPlayer); this._videoEl.style.visibility = "hidden"; - await this.hass!.auth.external!.sendMessage({ + await this.hass!.auth.external!.fireMessage({ type: "exoplayer/play_hls", payload: { url: new URL(url, window.location.href).toString(), diff --git a/src/external_app/external_app_entrypoint.ts b/src/external_app/external_app_entrypoint.ts index 46d5a39dee..0f059a11ae 100644 --- a/src/external_app/external_app_entrypoint.ts +++ b/src/external_app/external_app_entrypoint.ts @@ -7,7 +7,7 @@ This is the entry point for providing external app stuff from app entrypoint. import { fireEvent } from "../common/dom/fire_event"; import { HomeAssistantMain } from "../layouts/home-assistant-main"; -import type { EMExternalMessageCommands } from "./external_messaging"; +import type { EMIncomingMessageCommands } from "./external_messaging"; export const attachExternalToApp = (hassMainEl: HomeAssistantMain) => { window.addEventListener("haptic", (ev) => @@ -24,7 +24,7 @@ export const attachExternalToApp = (hassMainEl: HomeAssistantMain) => { const handleExternalMessage = ( hassMainEl: HomeAssistantMain, - msg: EMExternalMessageCommands + msg: EMIncomingMessageCommands ): boolean => { const bus = hassMainEl.hass.auth.external!; diff --git a/src/external_app/external_messaging.ts b/src/external_app/external_messaging.ts index fdab1ab2eb..2bf8fa34fb 100644 --- a/src/external_app/external_messaging.ts +++ b/src/external_app/external_messaging.ts @@ -8,7 +8,6 @@ interface CommandInFlight { export interface EMMessage { id?: number; type: string; - payload?: unknown; } interface EMError { @@ -30,34 +29,120 @@ interface EMMessageResultError { error: EMError; } -interface EMExternalMessageRestart { +interface EMOutgoingMessageConfigGet extends EMMessage { + type: "config/get"; +} + +interface EMOutgoingMessageMatterCommission extends EMMessage { + type: "matter/commission"; +} + +type EMOutgoingMessageWithAnswer = { + "config/get": { + request: EMOutgoingMessageConfigGet; + response: ExternalConfig; + }; + "matter/commission": { + request: EMOutgoingMessageMatterCommission; + response: { + code: string; + }; + }; +}; + +interface EMOutgoingMessageExoplayerPlayHLS extends EMMessage { + type: "exoplayer/play_hls"; + payload: { + url: string; + muted: boolean; + }; +} +interface EMOutgoingMessageExoplayerResize extends EMMessage { + type: "exoplayer/resize"; + payload: { + left: number; + top: number; + right: number; + bottom: number; + }; +} + +interface EMOutgoingMessageExoplayerStop extends EMMessage { + type: "exoplayer/stop"; +} + +interface EMOutgoingMessageThemeUpdate extends EMMessage { + type: "theme-update"; +} + +interface EMOutgoingMessageHaptic extends EMMessage { + type: "haptic"; + payload: { hapticType: string }; +} + +interface EMOutgoingMessageConnectionStatus extends EMMessage { + type: "connection-status"; + payload: { event: string }; +} + +interface EMOutgoingMessageAppConfiguration extends EMMessage { + type: "config_screen/show"; +} + +interface EMOutgoingMessageTagWrite extends EMMessage { + type: "tag/write"; + payload: { + name: string | null; + tag: string; + }; +} + +interface EMOutgoingMessageSidebarShow extends EMMessage { + type: "sidebar/show"; +} + +type EMOutgoingMessageWithoutAnswer = + | EMOutgoingMessageHaptic + | EMOutgoingMessageConnectionStatus + | EMOutgoingMessageAppConfiguration + | EMOutgoingMessageTagWrite + | EMOutgoingMessageSidebarShow + | EMOutgoingMessageExoplayerPlayHLS + | EMOutgoingMessageExoplayerResize + | EMOutgoingMessageExoplayerStop + | EMOutgoingMessageThemeUpdate + | EMMessageResultSuccess + | EMMessageResultError; + +interface EMIncomingMessageRestart { id: number; type: "command"; command: "restart"; } -interface EMExternMessageShowNotifications { +interface EMIncomingMessageShowNotifications { id: number; type: "command"; command: "notifications/show"; } -export type EMExternalMessageCommands = - | EMExternalMessageRestart - | EMExternMessageShowNotifications; +export type EMIncomingMessageCommands = + | EMIncomingMessageRestart + | EMIncomingMessageShowNotifications; -type ExternalMessage = +type EMIncomingMessage = | EMMessageResultSuccess | EMMessageResultError - | EMExternalMessageCommands; + | EMIncomingMessageCommands; -type ExternalMessageHandler = (msg: EMExternalMessageCommands) => boolean; +type EMIncomingMessageHandler = (msg: EMIncomingMessageCommands) => boolean; export interface ExternalConfig { hasSettingsScreen: boolean; hasSidebar: boolean; canWriteTag: boolean; hasExoPlayer: boolean; + canCommissionMatter: boolean; } export class ExternalMessaging { @@ -67,7 +152,7 @@ export class ExternalMessaging { public msgId = 0; - private _commandHandler?: ExternalMessageHandler; + private _commandHandler?: EMIncomingMessageHandler; public async attach() { window[CALLBACK_EXTERNAL_BUS] = (msg) => this.receiveMessage(msg); @@ -77,12 +162,12 @@ export class ExternalMessaging { payload: { event: ev.detail }, }) ); - this.config = await this.sendMessage({ + this.config = await this.sendMessage<"config/get">({ type: "config/get", }); } - public addCommandHandler(handler: ExternalMessageHandler) { + public addCommandHandler(handler: EMIncomingMessageHandler) { this._commandHandler = handler; } @@ -90,31 +175,33 @@ export class ExternalMessaging { * Send message to external app that expects a response. * @param msg message to send */ - public sendMessage(msg: EMMessage): Promise { + public sendMessage( + msg: EMOutgoingMessageWithAnswer[T]["request"] + ): Promise { const msgId = ++this.msgId; msg.id = msgId; - this.fireMessage(msg); + this._sendExternal(msg); - return new Promise((resolve, reject) => { - this.commands[msgId] = { resolve, reject }; - }); + return new Promise( + (resolve, reject) => { + this.commands[msgId] = { resolve, reject }; + } + ); } /** * Send message to external app without expecting a response. * @param msg message to send */ - public fireMessage( - msg: EMMessage | EMMessageResultSuccess | EMMessageResultError - ) { + public fireMessage(msg: EMOutgoingMessageWithoutAnswer) { if (!msg.id) { msg.id = ++this.msgId; } this._sendExternal(msg); } - public receiveMessage(msg: ExternalMessage) { + public receiveMessage(msg: EMIncomingMessage) { if (__DEV__) { // eslint-disable-next-line no-console console.log("Receiving message from external app", msg);