diff --git a/ext/src/background/ReceiverSelector.ts b/ext/src/background/ReceiverSelector.ts index 4070c3e..ef7bb67 100644 --- a/ext/src/background/ReceiverSelector.ts +++ b/ext/src/background/ReceiverSelector.ts @@ -8,7 +8,6 @@ import { getMediaTypesForPageUrl } from "../lib/utils"; import { ReceiverDevice, - ReceiverSelectionActionType, ReceiverSelectorMediaType, ReceiverSelectorPageInfo } from "../types"; @@ -22,16 +21,10 @@ import type { SenderMediaMessage, SenderMessage } from "../cast/sdk/types"; const POPUP_URL = browser.runtime.getURL("ui/popup/index.html"); -export interface ReceiverSelectionCast { - actionType: ReceiverSelectionActionType.Cast; +export interface ReceiverSelection { receiverDevice: ReceiverDevice; mediaType: ReceiverSelectorMediaType; } -export interface ReceiverSelectionStop { - actionType: ReceiverSelectionActionType.Stop; - receiverDevice: ReceiverDevice; -} -export type ReceiverSelection = ReceiverSelectionCast | ReceiverSelectionStop; export interface ReceiverSelectorReceiverMessage { deviceId: string; @@ -43,24 +36,16 @@ export interface ReceiverSelectorMediaMessage { } interface ReceiverSelectorEvents { - selected: ReceiverSelectionCast; - error: string; + selected: ReceiverSelection; cancelled: void; - stop: ReceiverSelectionStop; + stop: { deviceId: string }; + error: string; close: void; receiverMessage: ReceiverSelectorReceiverMessage; mediaMessage: ReceiverSelectorMediaMessage; } let baseConfig: BaseConfig; -baseConfigStorage - .get("baseConfig") - .then(value => { - baseConfig = value.baseConfig; - }) - .catch(() => { - logger.error("Failed to get Chromecast base config!"); - }); /** * Manages the receiver selector popup window and communication with the @@ -248,39 +233,27 @@ export default class ReceiverSelector extends TypedEventTarget { + let castInstance = castManager.getInstance( + contextTabId, + contextFrameId + ); + /** + * If the current context is running the mirroring app, pretend + * it doesn't exist because it shouldn't be launched like this. + */ + if (castInstance?.appId === (await options.get("mirroringAppId"))) { + castInstance = undefined; + } + + let defaultMediaType = ReceiverSelectorMediaType.Tab; + let availableMediaTypes = ReceiverSelectorMediaType.None; + + let pageUrl: string | undefined; + try { + pageUrl = ( + await browser.webNavigation.getFrame({ + tabId: contextTabId, + frameId: contextFrameId + }) + ).url; + + availableMediaTypes = getMediaTypesForPageUrl(pageUrl); + } catch { + logger.error( + "Failed to locate frame, falling back to default available media types." + ); + } + + // Enable app media type if sender application is present + if (castInstance || selectionOpts?.withMediaSender) { + defaultMediaType = ReceiverSelectorMediaType.App; + availableMediaTypes |= ReceiverSelectorMediaType.App; + } + + const opts = await options.getAll(); + + // Disable mirroring media types if mirroring is not enabled + if (!opts.mirroringEnabled) { + availableMediaTypes &= ~( + ReceiverSelectorMediaType.Tab | ReceiverSelectorMediaType.Screen + ); + } + + // Remove file media type if local media is not enabled + if (!opts.mediaEnabled || !opts.localMediaEnabled) { + availableMediaTypes &= ~ReceiverSelectorMediaType.File; + } + + // Ensure status manager is initialized + await deviceManager.init(); + + let isRequestAppAudioCompatible: Optional; + if (castInstance?.appId) { + if (!baseConfig) { + try { + baseConfig = (await baseConfigStorage.get("baseConfig")) + .baseConfig; + } catch (err) { + throw logger.error("Failed to get Chromecast base config!"); + } + } + + isRequestAppAudioCompatible = getAppTag( + baseConfig, + castInstance.appId + )?.supports_audio_only; + } + return new Promise(async (resolve, reject) => { - let castInstance = castManager.getInstance( - contextTabId, - contextFrameId - ); - - /** - * If the current context is running the mirroring app, pretend - * it doesn't exist because it shouldn't be launched like this. - */ - if (castInstance?.appId === (await options.get("mirroringAppId"))) { - castInstance = undefined; - } - - let defaultMediaType = ReceiverSelectorMediaType.Tab; - let availableMediaTypes = ReceiverSelectorMediaType.None; - - let pageUrl: string | undefined; - try { - pageUrl = ( - await browser.webNavigation.getFrame({ - tabId: contextTabId, - frameId: contextFrameId - }) - ).url; - - availableMediaTypes = getMediaTypesForPageUrl(pageUrl); - } catch { - logger.error( - "Failed to locate frame, falling back to default available media types." - ); - } - - // Enable app media type if sender application is present - if (castInstance || selectionOpts?.withMediaSender) { - defaultMediaType = ReceiverSelectorMediaType.App; - availableMediaTypes |= ReceiverSelectorMediaType.App; - } - - const opts = await options.getAll(); - - // Disable mirroring media types if mirroring is not enabled - if (!opts.mirroringEnabled) { - availableMediaTypes &= ~( - ReceiverSelectorMediaType.Tab | - ReceiverSelectorMediaType.Screen - ); - } - - // Remove file media type if local media is not enabled - if (!opts.mediaEnabled || !opts.localMediaEnabled) { - availableMediaTypes &= ~ReceiverSelectorMediaType.File; - } - // Close an existing open selector - if (ReceiverSelector.shared && ReceiverSelector.shared.isOpen) { - ReceiverSelector.shared.close(); + if (ReceiverSelector.sharedInstance.isOpen) { + await ReceiverSelector.sharedInstance.close(); } - // Get a new selector for each selection - ReceiverSelector.shared = new ReceiverSelector(); + const selector = createSelector(); + ReceiverSelector.sharedInstance = selector; - function onReceiverChange() { - ReceiverSelector.shared.update(deviceManager.getDevices()); - } + // Handle selected return value + const onSelected = (ev: CustomEvent) => + resolve(ev.detail); + selector.addEventListener("selected", onSelected); - deviceManager.addEventListener( - "receiverDeviceUp", - onReceiverChange - ); - deviceManager.addEventListener( - "receiverDeviceDown", - onReceiverChange - ); - deviceManager.addEventListener( - "receiverDeviceUpdated", - onReceiverChange - ); - deviceManager.addEventListener( - "receiverDeviceMediaUpdated", - onReceiverChange + // Handle cancelled return value + const onCancelled = () => resolve(null); + selector.addEventListener("cancelled", onCancelled); + + const onError = (ev: CustomEvent) => reject(ev.detail); + selector.addEventListener("error", onError); + + // Cleanup listeners + selector.addEventListener( + "close", + () => { + selector.removeEventListener("selected", onSelected); + selector.removeEventListener("cancelled", onCancelled); + selector.removeEventListener("error", onError); + }, + { once: true } ); - function onSelectorSelected( - ev: CustomEvent - ) { - logger.info("Selected receiver", ev.detail); - - resolve({ - actionType: ReceiverSelectionActionType.Cast, - receiverDevice: ev.detail.receiverDevice, - mediaType: ev.detail.mediaType - }); - } - function onSelectorStop(ev: CustomEvent) { - logger.info("Stopping receiver app...", ev.detail); - - deviceManager.stopReceiverApp(ev.detail.receiverDevice.id); - - resolve({ - actionType: ReceiverSelectionActionType.Stop, - receiverDevice: ev.detail.receiverDevice - }); - } - function onSelectorCancelled() { - logger.info("Cancelled receiver selection"); - - resolve(null); - } - function onSelectorError(ev: CustomEvent) { - reject(ev.detail); - } - function onReceiverMessage( - ev: CustomEvent - ) { - deviceManager.sendReceiverMessage( - ev.detail.deviceId, - ev.detail.message - ); - } - function onMediaMessage( - ev: CustomEvent - ) { - deviceManager.sendMediaMessage( - ev.detail.deviceId, - ev.detail.message - ); - } - - ReceiverSelector.shared.addEventListener( - "selected", - onSelectorSelected - ); - ReceiverSelector.shared.addEventListener("stop", onSelectorStop); - ReceiverSelector.shared.addEventListener( - "cancelled", - onSelectorCancelled - ); - ReceiverSelector.shared.addEventListener("error", onSelectorError); - ReceiverSelector.shared.addEventListener( - "receiverMessage", - onReceiverMessage - ); - ReceiverSelector.shared.addEventListener( - "mediaMessage", - onMediaMessage - ); - ReceiverSelector.shared.addEventListener("close", removeListeners); - - function removeListeners() { - ReceiverSelector.shared.removeEventListener( - "selected", - onSelectorSelected - ); - ReceiverSelector.shared.removeEventListener( - "stop", - onSelectorStop - ); - ReceiverSelector.shared.removeEventListener( - "cancelled", - onSelectorCancelled - ); - ReceiverSelector.shared.removeEventListener( - "error", - onSelectorError - ); - ReceiverSelector.shared.removeEventListener( - "receiverMessage", - onReceiverMessage - ); - ReceiverSelector.shared.removeEventListener( - "mediaMessage", - onMediaMessage - ); - ReceiverSelector.shared.removeEventListener( - "close", - removeListeners - ); - - deviceManager.removeEventListener( - "receiverDeviceUp", - onReceiverChange - ); - deviceManager.removeEventListener( - "receiverDeviceDown", - onReceiverChange - ); - deviceManager.removeEventListener( - "receiverDeviceUpdated", - onReceiverChange - ); - deviceManager.removeEventListener( - "receiverDeviceMediaUpdated", - onReceiverChange - ); - } - - // Ensure status manager is initialized - await deviceManager.init(); - - let isRequestAppAudioCompatible: Optional; - if (castInstance?.appId) { - const appTag = getAppTag(baseConfig, castInstance.appId); - isRequestAppAudioCompatible = appTag?.supports_audio_only; - } - - ReceiverSelector.shared.open({ + selector.open({ receiverDevices: deviceManager.getDevices(), defaultMediaType, availableMediaTypes, @@ -579,3 +443,74 @@ export default class ReceiverSelector extends TypedEventTarget) => { + const castInstance = castManager.getInstanceByDeviceId( + ev.detail.deviceId + ); + if (!castInstance) return; + + castInstance.contentPort.postMessage({ + subject: "cast:receiverStoppedAction", + data: { deviceId: ev.detail.deviceId } + }); + }; + selector.addEventListener("stop", onStop); + + // Forward receiver messages + const onReceiverMessage = ( + ev: CustomEvent + ) => + deviceManager.sendReceiverMessage( + ev.detail.deviceId, + ev.detail.message + ); + selector.addEventListener("receiverMessage", onReceiverMessage); + + // Forward media messages + const onMediaMessage = (ev: CustomEvent) => + deviceManager.sendMediaMessage(ev.detail.deviceId, ev.detail.message); + selector.addEventListener("mediaMessage", onMediaMessage); + + // Update selector data whenever devices change/update + const onDeviceChange = () => selector.update(deviceManager.getDevices()); + + deviceManager.addEventListener("deviceUp", onDeviceChange); + deviceManager.addEventListener("deviceDown", onDeviceChange); + deviceManager.addEventListener("deviceUpdated", onDeviceChange); + deviceManager.addEventListener("deviceMediaUpdated", onDeviceChange); + + // Cleanup listeners + selector.addEventListener( + "close", + () => { + deviceManager.removeEventListener("deviceUp", onDeviceChange); + deviceManager.removeEventListener("deviceDown", onDeviceChange); + deviceManager.removeEventListener("deviceUpdated", onDeviceChange); + deviceManager.removeEventListener( + "deviceMediaUpdated", + onDeviceChange + ); + + selector.removeEventListener("stop", onStop); + selector.removeEventListener("receiverMessage", onReceiverMessage); + selector.removeEventListener("mediaMessage", onMediaMessage); + }, + { once: true } + ); + + return selector; +} diff --git a/ext/src/background/castManager.ts b/ext/src/background/castManager.ts index 2e2e65b..a93705a 100644 --- a/ext/src/background/castManager.ts +++ b/ext/src/background/castManager.ts @@ -6,10 +6,7 @@ import messaging, { Message, Port } from "../messaging"; import options from "../lib/options"; import { stringify } from "../lib/utils"; -import { - ReceiverSelectionActionType, - ReceiverSelectorMediaType -} from "../types"; +import { ReceiverSelectorMediaType } from "../types"; import deviceManager from "./deviceManager"; import ReceiverSelector, { ReceiverSelection } from "./ReceiverSelector"; @@ -22,6 +19,12 @@ export interface CastInstance { contentTabId?: number; contentFrameId?: number; appId?: string; + session?: CastSession; +} + +interface CastSession { + sessionId: string; + deviceId: string; } /** Keeps track of cast API instances and provides bridge messaging. */ @@ -37,7 +40,7 @@ export default new (class { }); // Forward receiver eventes to cast instances - deviceManager.addEventListener("receiverDeviceUp", ev => { + deviceManager.addEventListener("deviceUp", ev => { for (const instance of this.activeInstances) { instance.contentPort.postMessage({ subject: "cast:receiverDeviceUp", @@ -45,7 +48,7 @@ export default new (class { }); } }); - deviceManager.addEventListener("receiverDeviceDown", ev => { + deviceManager.addEventListener("deviceDown", ev => { for (const instance of this.activeInstances) { instance.contentPort.postMessage({ subject: "cast:receiverDeviceDown", @@ -71,6 +74,12 @@ export default new (class { } } + public getInstanceByDeviceId(deviceId: string) { + for (const instance of this.activeInstances) { + if (instance.session?.deviceId === deviceId) return instance; + } + } + /** * Creates a cast instance with a given port and connects messaging * correctly depending on the type of port. @@ -106,7 +115,7 @@ export default new (class { // bridge -> content instance.bridgePort.onMessage.addListener(message => { - contentPort.postMessage(message); + this.handleBridgeMessage(instance, message); }); // content -> (any) @@ -160,7 +169,7 @@ export default new (class { }; // bridge -> content const onBridgePortMessage = (message: Message) => { - contentPort.postMessage(message); + this.handleBridgeMessage(instance, message); }; const onDisconnect = () => { @@ -182,6 +191,23 @@ export default new (class { return instance; } + private async handleBridgeMessage( + instance: CastInstance, + message: Message + ) { + // Intercept messages to store relevant info + switch (message.subject) { + case "cast:sessionCreated": + instance.session = { + deviceId: message.data.receiverId, + sessionId: message.data.sessionId + }; + break; + } + + instance.contentPort.postMessage(message); + } + /** * Handle content messages from the cast instance. These will either * be handled here in the background script or forwarded to the @@ -238,48 +264,29 @@ export default new (class { break; } - switch (selection.actionType) { - case ReceiverSelectionActionType.Cast: { - /** - * If the media type returned from the - * selector has been changed, we need to - * cancel the current sender and switch it - * out for the right one. - */ - if ( - selection.mediaType !== - ReceiverSelectorMediaType.App - ) { - instance.contentPort.postMessage({ - subject: "cast:selectReceiver/cancelled" - }); + /** + * If the media type returned from the selector has + * been changed, we need to cancel the current + * sender and switch it out for the right one. + */ + if (selection.mediaType !== ReceiverSelectorMediaType.App) { + instance.contentPort.postMessage({ + subject: "cast:selectReceiver/cancelled" + }); - this.loadSender({ - tabId: instance.contentTabId, - frameId: instance.contentFrameId, - selection - }); + this.loadSender({ + tabId: instance.contentTabId, + frameId: instance.contentFrameId, + selection + }); - break; - } - - instance.contentPort.postMessage({ - subject: "cast:selectReceiver/selected", - data: selection - }); - - break; - } - - case ReceiverSelectionActionType.Stop: { - instance.contentPort.postMessage({ - subject: "cast:selectReceiver/stopped", - data: selection - }); - - break; - } + break; } + + instance.contentPort.postMessage({ + subject: "cast:selectReceiver/selected", + data: selection + }); } catch (err) { // TODO: Report errors properly instance.contentPort.postMessage({ @@ -295,7 +302,7 @@ export default new (class { * same one that caused the session creation. */ case "main:closeReceiverSelector": { - const selector = ReceiverSelector.shared; + const selector = ReceiverSelector.sharedInstance; const shouldClose = await options.get( "receiverSelectorWaitForConnection" ); @@ -323,10 +330,6 @@ export default new (class { return; } - if (opts.selection.actionType !== ReceiverSelectionActionType.Cast) { - return; - } - switch (opts.selection.mediaType) { case ReceiverSelectorMediaType.App: { const instance = this.getInstance(opts.tabId, opts.frameId); diff --git a/ext/src/background/deviceManager.ts b/ext/src/background/deviceManager.ts index 380e6e5..a3f27e7 100644 --- a/ext/src/background/deviceManager.ts +++ b/ext/src/background/deviceManager.ts @@ -16,13 +16,13 @@ import type { import { PlayerState } from "../cast/sdk/media/enums"; interface EventMap { - receiverDeviceUp: { deviceInfo: ReceiverDevice }; - receiverDeviceDown: { deviceId: string }; - receiverDeviceUpdated: { + deviceUp: { deviceInfo: ReceiverDevice }; + deviceDown: { deviceId: string }; + deviceUpdated: { deviceId: string; status: ReceiverStatus; }; - receiverDeviceMediaUpdated: { + deviceMediaUpdated: { deviceId: string; status: MediaStatus; }; @@ -139,7 +139,7 @@ export default new (class extends TypedEventTarget { this.receiverDevices.set(deviceId, deviceInfo); this.dispatchEvent( - new CustomEvent("receiverDeviceUp", { + new CustomEvent("deviceUp", { detail: { deviceInfo } }) ); @@ -154,7 +154,7 @@ export default new (class extends TypedEventTarget { this.receiverDevices.delete(deviceId); } this.dispatchEvent( - new CustomEvent("receiverDeviceDown", { + new CustomEvent("deviceDown", { detail: { deviceId: deviceId } }) ); @@ -176,7 +176,7 @@ export default new (class extends TypedEventTarget { device.status = status; this.dispatchEvent( - new CustomEvent("receiverDeviceUpdated", { + new CustomEvent("deviceUpdated", { detail: { deviceId, status: device.status @@ -202,7 +202,7 @@ export default new (class extends TypedEventTarget { } this.dispatchEvent( - new CustomEvent("receiverDeviceMediaUpdated", { + new CustomEvent("deviceMediaUpdated", { detail: { deviceId, status: device.mediaStatus @@ -218,7 +218,7 @@ export default new (class extends TypedEventTarget { private onBridgeDisconnect = () => { // Notify listeners of device availablility for (const [, receiverDevice] of this.receiverDevices) { - const event = new CustomEvent("receiverDeviceDown", { + const event = new CustomEvent("deviceDown", { detail: { deviceId: receiverDevice.id } }); diff --git a/ext/src/background/menus.ts b/ext/src/background/menus.ts index 825c2c2..3248f8a 100644 --- a/ext/src/background/menus.ts +++ b/ext/src/background/menus.ts @@ -4,10 +4,7 @@ import logger from "../lib/logger"; import options from "../lib/options"; import { stringify } from "../lib/utils"; -import { - ReceiverSelectionActionType, - ReceiverSelectorMediaType -} from "../types"; +import { ReceiverSelectorMediaType } from "../types"; import ReceiverSelector, { ReceiverSelection } from "./ReceiverSelector"; import castManager from "./castManager"; @@ -167,12 +164,7 @@ async function onMenuClicked( return; } // Invalid selection result - if ( - !selection || - selection.actionType !== ReceiverSelectionActionType.Cast - ) { - return; - } + if (!selection) return; if (castMenuClicked) { castManager.loadSender({ diff --git a/ext/src/cast/sdk/index.ts b/ext/src/cast/sdk/index.ts index a926925..cadc5f0 100644 --- a/ext/src/cast/sdk/index.ts +++ b/ext/src/cast/sdk/index.ts @@ -316,26 +316,6 @@ export default class { break; } - case "cast:selectReceiver/stopped": { - const { receiverDevice } = message.data; - - logger.info("Stopped receiver"); - - if (this.#sessionRequest) { - this.#sessionRequest = undefined; - - for (const listener of this.#receiverActionListeners) { - listener( - // TODO: Use existing receiver object? - createReceiver(receiverDevice), - ReceiverAction.STOP - ); - } - } - - break; - } - // Popup closed before session established case "cast:selectReceiver/cancelled": { if (this.#sessionRequest) { @@ -349,6 +329,17 @@ export default class { break; } + case "cast:receiverStoppedAction": { + const device = this.#receiverDevices.get(message.data.deviceId); + if (!device) break; + + for (const actionListener of this.#receiverActionListeners) { + actionListener(createReceiver(device), ReceiverAction.STOP); + } + + break; + } + // Session request initiated via receiver selector case "cast:launchApp": { if (this.#sessionRequest) { diff --git a/ext/src/cast/sdk/types.ts b/ext/src/cast/sdk/types.ts index 9265215..0c6ca49 100644 --- a/ext/src/cast/sdk/types.ts +++ b/ext/src/cast/sdk/types.ts @@ -92,7 +92,7 @@ interface ReqBase { // NS: urn:x-cast:com.google.cast.receiver export type SenderMessage = | (ReqBase & { type: "LAUNCH"; appId: string }) - | (ReqBase & { type: "STOP"; sessionId: string }) + | (ReqBase & { type: "STOP"; sessionId?: string }) | (ReqBase & { type: "GET_STATUS" }) | (ReqBase & { type: "GET_APP_AVAILABILITY"; appId: string[] }) | (ReqBase & { type: "SET_VOLUME"; volume: Partial }); diff --git a/ext/src/lib/TypedEventTarget.ts b/ext/src/lib/TypedEventTarget.ts index 6086fbb..b075c18 100644 --- a/ext/src/lib/TypedEventTarget.ts +++ b/ext/src/lib/TypedEventTarget.ts @@ -11,19 +11,21 @@ export class TypedEventTarget extends EventTarget { // @ts-ignore public addEventListener( type: K, - listener: (ev: CustomEvent) => void + listener: (ev: CustomEvent) => void, + options?: boolean | AddEventListenerOptions ): void { // @ts-ignore - super.addEventListener(type as string, listener); + super.addEventListener(type as string, listener, options); } // @ts-ignore public removeEventListener( type: K, - listener: (ev: CustomEvent) => void + listener: (ev: CustomEvent) => void, + options?: boolean | EventListenerOptions ): void { // @ts-ignore - super.removeEventListener(type as string, listener); + super.removeEventListener(type, listener, options); } public dispatchEvent(ev: CustomEvent): boolean { diff --git a/ext/src/messaging.ts b/ext/src/messaging.ts index c427a96..f584daa 100644 --- a/ext/src/messaging.ts +++ b/ext/src/messaging.ts @@ -5,8 +5,6 @@ import type { BridgeInfo } from "./lib/bridge"; import type { ReceiverSelection, - ReceiverSelectionCast, - ReceiverSelectionStop, ReceiverSelectorMediaMessage, ReceiverSelectorReceiverMessage } from "./background/receiverSelector"; @@ -57,16 +55,16 @@ type ExtMessageDefinitions = { "popup:close": undefined; "receiverSelector:selected": ReceiverSelection; - "receiverSelector:stop": ReceiverSelection; + "receiverSelector:stop": { deviceId: string }; "receiverSelector:receiverMessage": ReceiverSelectorReceiverMessage; "receiverSelector:mediaMessage": ReceiverSelectorMediaMessage; "main:selectReceiver": { sessionRequest: SessionRequest; }; - "cast:selectReceiver/selected": ReceiverSelectionCast; - "cast:selectReceiver/stopped": ReceiverSelectionStop; + "cast:selectReceiver/selected": ReceiverSelection; "cast:selectReceiver/cancelled": undefined; + "cast:receiverStoppedAction": { deviceId: string }; "main:closeReceiverSelector": undefined; @@ -74,7 +72,7 @@ type ExtMessageDefinitions = { "cast:initialized": BridgeInfo; "cast:receiverDeviceUp": { receiverDevice: ReceiverDevice }; - "cast:receiverDeviceDown": { receiverDeviceId: ReceiverDevice["id"] }; + "cast:receiverDeviceDown": { receiverDeviceId: string }; "cast:launchApp": { receiverDevice: ReceiverDevice }; }; diff --git a/ext/src/types.ts b/ext/src/types.ts index d40eb14..a2bfe67 100644 --- a/ext/src/types.ts +++ b/ext/src/types.ts @@ -30,11 +30,6 @@ export enum ReceiverSelectorMediaType { Screen = 4, File = 8 } -export enum ReceiverSelectionActionType { - Cast = 1, - Stop = 2 -} - /** Info about sender page context. */ export interface ReceiverSelectorPageInfo { url: string; diff --git a/ext/src/ui/popup/Popup.svelte b/ext/src/ui/popup/Popup.svelte index 0758018..ef7542b 100644 --- a/ext/src/ui/popup/Popup.svelte +++ b/ext/src/ui/popup/Popup.svelte @@ -8,7 +8,6 @@ import { ReceiverDevice, ReceiverDeviceCapabilities, - ReceiverSelectionActionType, ReceiverSelectorMediaType, ReceiverSelectorPageInfo } from "../../types"; @@ -347,7 +346,6 @@ subject: "receiverSelector:selected", data: { receiverDevice, - actionType: ReceiverSelectionActionType.Cast, mediaType } }); @@ -355,12 +353,17 @@ function onReceiverStop(receiverDevice: ReceiverDevice) { port?.postMessage({ - subject: "receiverSelector:stop", + subject: "receiverSelector:receiverMessage", data: { - receiverDevice, - actionType: ReceiverSelectionActionType.Stop + deviceId: receiverDevice.id, + message: { requestId: 0, type: "STOP" } } }); + + port?.postMessage({ + subject: "receiverSelector:stop", + data: { deviceId: receiverDevice.id } + }); }