mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-11 18:19:58 +00:00
Move selectorManager getSelection to ReceiverSelector static method
This commit is contained in:
@@ -3,9 +3,9 @@
|
|||||||
import logger from "../lib/logger";
|
import logger from "../lib/logger";
|
||||||
import messaging, { Port, Message } from "../messaging";
|
import messaging, { Port, Message } from "../messaging";
|
||||||
import options from "../lib/options";
|
import options from "../lib/options";
|
||||||
|
|
||||||
import { TypedEventTarget } from "../lib/TypedEventTarget";
|
import { TypedEventTarget } from "../lib/TypedEventTarget";
|
||||||
import { SenderMediaMessage, SenderMessage } from "../cast/sdk/types";
|
import { getMediaTypesForPageUrl } from "../lib/utils";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ReceiverDevice,
|
ReceiverDevice,
|
||||||
ReceiverSelectionActionType,
|
ReceiverSelectionActionType,
|
||||||
@@ -13,6 +13,13 @@ import {
|
|||||||
ReceiverSelectorPageInfo
|
ReceiverSelectorPageInfo
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
|
import deviceManager from "./deviceManager";
|
||||||
|
import castManager from "./castManager";
|
||||||
|
|
||||||
|
import { BaseConfig, baseConfigStorage, getAppTag } from "../cast/googleApi";
|
||||||
|
import type { SessionRequest } from "../cast/sdk/classes";
|
||||||
|
import type { SenderMediaMessage, SenderMessage } from "../cast/sdk/types";
|
||||||
|
|
||||||
const POPUP_URL = browser.runtime.getURL("ui/popup/index.html");
|
const POPUP_URL = browser.runtime.getURL("ui/popup/index.html");
|
||||||
|
|
||||||
export interface ReceiverSelectionCast {
|
export interface ReceiverSelectionCast {
|
||||||
@@ -45,6 +52,16 @@ interface ReceiverSelectorEvents {
|
|||||||
mediaMessage: ReceiverSelectorMediaMessage;
|
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
|
* Manages the receiver selector popup window and communication with the
|
||||||
* extension page hosted within.
|
* extension page hosted within.
|
||||||
@@ -316,4 +333,249 @@ export default class ReceiverSelector extends TypedEventTarget<ReceiverSelectorE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static shared = new ReceiverSelector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a receiver selector with the specified default/available media
|
||||||
|
* types.
|
||||||
|
*
|
||||||
|
* Returns a promise that:
|
||||||
|
* - Resolves to a ReceiverSelection object if selection is
|
||||||
|
* successful.
|
||||||
|
* - Resolves to null if the selection is cancelled.
|
||||||
|
* - Rejects if the selection fails.
|
||||||
|
*/
|
||||||
|
static getSelection(
|
||||||
|
contextTabId: number,
|
||||||
|
contextFrameId = 0,
|
||||||
|
selectionOpts?: {
|
||||||
|
sessionRequest?: SessionRequest;
|
||||||
|
withMediaSender?: boolean;
|
||||||
|
}
|
||||||
|
): Promise<ReceiverSelection | null> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a new selector for each selection
|
||||||
|
ReceiverSelector.shared = new ReceiverSelector();
|
||||||
|
|
||||||
|
function onReceiverChange() {
|
||||||
|
ReceiverSelector.shared.update(deviceManager.getDevices());
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceManager.addEventListener(
|
||||||
|
"receiverDeviceUp",
|
||||||
|
onReceiverChange
|
||||||
|
);
|
||||||
|
deviceManager.addEventListener(
|
||||||
|
"receiverDeviceDown",
|
||||||
|
onReceiverChange
|
||||||
|
);
|
||||||
|
deviceManager.addEventListener(
|
||||||
|
"receiverDeviceUpdated",
|
||||||
|
onReceiverChange
|
||||||
|
);
|
||||||
|
deviceManager.addEventListener(
|
||||||
|
"receiverDeviceMediaUpdated",
|
||||||
|
onReceiverChange
|
||||||
|
);
|
||||||
|
|
||||||
|
function onSelectorSelected(
|
||||||
|
ev: CustomEvent<ReceiverSelectionCast>
|
||||||
|
) {
|
||||||
|
logger.info("Selected receiver", ev.detail);
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
actionType: ReceiverSelectionActionType.Cast,
|
||||||
|
receiverDevice: ev.detail.receiverDevice,
|
||||||
|
mediaType: ev.detail.mediaType
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function onSelectorStop(ev: CustomEvent<ReceiverSelectionStop>) {
|
||||||
|
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<string>) {
|
||||||
|
reject(ev.detail);
|
||||||
|
}
|
||||||
|
function onReceiverMessage(
|
||||||
|
ev: CustomEvent<ReceiverSelectorReceiverMessage>
|
||||||
|
) {
|
||||||
|
deviceManager.sendReceiverMessage(
|
||||||
|
ev.detail.deviceId,
|
||||||
|
ev.detail.message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function onMediaMessage(
|
||||||
|
ev: CustomEvent<ReceiverSelectorMediaMessage>
|
||||||
|
) {
|
||||||
|
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<boolean>;
|
||||||
|
if (castInstance?.appId) {
|
||||||
|
const appTag = getAppTag(baseConfig, castInstance.appId);
|
||||||
|
isRequestAppAudioCompatible = appTag?.supports_audio_only;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiverSelector.shared.open({
|
||||||
|
receiverDevices: deviceManager.getDevices(),
|
||||||
|
defaultMediaType,
|
||||||
|
availableMediaTypes,
|
||||||
|
appId: castInstance?.appId,
|
||||||
|
// Create page info
|
||||||
|
pageInfo: pageUrl
|
||||||
|
? {
|
||||||
|
url: pageUrl,
|
||||||
|
tabId: contextTabId,
|
||||||
|
frameId: contextFrameId,
|
||||||
|
sessionRequest: selectionOpts?.sessionRequest,
|
||||||
|
isRequestAppAudioCompatible
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import bridge, { BridgeInfo } from "../lib/bridge";
|
|||||||
|
|
||||||
import castManager from "./castManager";
|
import castManager from "./castManager";
|
||||||
import deviceManager from "./deviceManager";
|
import deviceManager from "./deviceManager";
|
||||||
import selectorManager from "./selectorManager";
|
import ReceiverSelector from "./ReceiverSelector";
|
||||||
|
|
||||||
import { initMenus } from "./menus";
|
import { initMenus } from "./menus";
|
||||||
import { initWhitelist } from "./whitelist";
|
import { initWhitelist } from "./whitelist";
|
||||||
import { baseConfigStorage, fetchBaseConfig } from "../cast/googleapi";
|
import { baseConfigStorage, fetchBaseConfig } from "../cast/googleApi";
|
||||||
|
|
||||||
const _ = browser.i18n.getMessage;
|
const _ = browser.i18n.getMessage;
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ async function init() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selection = await selectorManager.getSelection(tab.id);
|
const selection = await ReceiverSelector.getSelection(tab.id);
|
||||||
if (selection) {
|
if (selection) {
|
||||||
castManager.loadSender({
|
castManager.loadSender({
|
||||||
tabId: tab.id,
|
tabId: tab.id,
|
||||||
|
|||||||
@@ -11,10 +11,8 @@ import {
|
|||||||
ReceiverSelectorMediaType
|
ReceiverSelectorMediaType
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
import { ReceiverSelection } from "./ReceiverSelector";
|
|
||||||
|
|
||||||
import deviceManager from "./deviceManager";
|
import deviceManager from "./deviceManager";
|
||||||
import selectorManager from "./selectorManager";
|
import ReceiverSelector, { ReceiverSelection } from "./ReceiverSelector";
|
||||||
|
|
||||||
type AnyPort = Port | MessagePort;
|
type AnyPort = Port | MessagePort;
|
||||||
|
|
||||||
@@ -225,7 +223,7 @@ export default new (class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const selection = await selectorManager.getSelection(
|
const selection = await ReceiverSelector.getSelection(
|
||||||
instance.contentTabId,
|
instance.contentTabId,
|
||||||
instance.contentFrameId,
|
instance.contentFrameId,
|
||||||
{ sessionRequest: message.data.sessionRequest }
|
{ sessionRequest: message.data.sessionRequest }
|
||||||
@@ -297,7 +295,7 @@ export default new (class {
|
|||||||
* same one that caused the session creation.
|
* same one that caused the session creation.
|
||||||
*/
|
*/
|
||||||
case "main:closeReceiverSelector": {
|
case "main:closeReceiverSelector": {
|
||||||
const selector = await selectorManager.getSelector();
|
const selector = ReceiverSelector.shared;
|
||||||
const shouldClose = await options.get(
|
const shouldClose = await options.get(
|
||||||
"receiverSelectorWaitForConnection"
|
"receiverSelectorWaitForConnection"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import {
|
|||||||
ReceiverSelectorMediaType
|
ReceiverSelectorMediaType
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
import { ReceiverSelection } from "./ReceiverSelector";
|
import ReceiverSelector, { ReceiverSelection } from "./ReceiverSelector";
|
||||||
|
|
||||||
import selectorManager from "./selectorManager";
|
|
||||||
import castManager from "./castManager";
|
import castManager from "./castManager";
|
||||||
|
|
||||||
const _ = browser.i18n.getMessage;
|
const _ = browser.i18n.getMessage;
|
||||||
@@ -157,10 +155,12 @@ async function onMenuClicked(
|
|||||||
|
|
||||||
let selection: Nullable<ReceiverSelection> = null;
|
let selection: Nullable<ReceiverSelection> = null;
|
||||||
try {
|
try {
|
||||||
selection = await selectorManager.getSelection(
|
selection = await ReceiverSelector.getSelection(
|
||||||
tab.id,
|
tab.id,
|
||||||
info.frameId,
|
info.frameId,
|
||||||
{ withMediaSender: castMediaMenuClicked }
|
{
|
||||||
|
withMediaSender: castMediaMenuClicked
|
||||||
|
}
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error("Failed to get receiver selection (cast menu)", err);
|
logger.error("Failed to get receiver selection (cast menu)", err);
|
||||||
|
|||||||
@@ -1,257 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
import options from "../lib/options";
|
|
||||||
import logger from "../lib/logger";
|
|
||||||
|
|
||||||
import { getMediaTypesForPageUrl } from "../lib/utils";
|
|
||||||
import { BaseConfig, baseConfigStorage, getAppTag } from "../cast/googleapi";
|
|
||||||
import { SessionRequest } from "../cast/sdk/classes";
|
|
||||||
|
|
||||||
import castManager from "./castManager";
|
|
||||||
import deviceManager from "./deviceManager";
|
|
||||||
|
|
||||||
import ReceiverSelector, {
|
|
||||||
ReceiverSelection,
|
|
||||||
ReceiverSelectionCast,
|
|
||||||
ReceiverSelectionStop,
|
|
||||||
ReceiverSelectorMediaMessage,
|
|
||||||
ReceiverSelectorReceiverMessage
|
|
||||||
} from "./ReceiverSelector";
|
|
||||||
|
|
||||||
import {
|
|
||||||
ReceiverSelectionActionType,
|
|
||||||
ReceiverSelectorMediaType
|
|
||||||
} from "../types";
|
|
||||||
|
|
||||||
let baseConfig: BaseConfig;
|
|
||||||
baseConfigStorage
|
|
||||||
.get("baseConfig")
|
|
||||||
.then(value => {
|
|
||||||
baseConfig = value.baseConfig;
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
logger.error("Failed to get Chromecast base config!");
|
|
||||||
});
|
|
||||||
|
|
||||||
let sharedSelector: ReceiverSelector;
|
|
||||||
async function getSelector() {
|
|
||||||
if (!sharedSelector) {
|
|
||||||
try {
|
|
||||||
sharedSelector = new ReceiverSelector();
|
|
||||||
} catch (err) {
|
|
||||||
throw logger.error("Failed to create receiver selector.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sharedSelector;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens a receiver selector with the specified default/available media
|
|
||||||
* types.
|
|
||||||
*
|
|
||||||
* Returns a promise that:
|
|
||||||
* - Resolves to a ReceiverSelection object if selection is
|
|
||||||
* successful.
|
|
||||||
* - Resolves to null if the selection is cancelled.
|
|
||||||
* - Rejects if the selection fails.
|
|
||||||
*/
|
|
||||||
async function getSelection(
|
|
||||||
contextTabId: number,
|
|
||||||
contextFrameId = 0,
|
|
||||||
selectionOpts?: {
|
|
||||||
sessionRequest?: SessionRequest;
|
|
||||||
withMediaSender?: boolean;
|
|
||||||
}
|
|
||||||
): Promise<ReceiverSelection | null> {
|
|
||||||
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 (sharedSelector && sharedSelector.isOpen) {
|
|
||||||
sharedSelector.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a new selector for each selection
|
|
||||||
sharedSelector = new ReceiverSelector();
|
|
||||||
|
|
||||||
function onReceiverChange() {
|
|
||||||
sharedSelector.update(deviceManager.getDevices());
|
|
||||||
}
|
|
||||||
|
|
||||||
deviceManager.addEventListener("receiverDeviceUp", onReceiverChange);
|
|
||||||
deviceManager.addEventListener("receiverDeviceDown", onReceiverChange);
|
|
||||||
deviceManager.addEventListener(
|
|
||||||
"receiverDeviceUpdated",
|
|
||||||
onReceiverChange
|
|
||||||
);
|
|
||||||
deviceManager.addEventListener(
|
|
||||||
"receiverDeviceMediaUpdated",
|
|
||||||
onReceiverChange
|
|
||||||
);
|
|
||||||
|
|
||||||
function onSelectorSelected(ev: CustomEvent<ReceiverSelectionCast>) {
|
|
||||||
logger.info("Selected receiver", ev.detail);
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
actionType: ReceiverSelectionActionType.Cast,
|
|
||||||
receiverDevice: ev.detail.receiverDevice,
|
|
||||||
mediaType: ev.detail.mediaType
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function onSelectorStop(ev: CustomEvent<ReceiverSelectionStop>) {
|
|
||||||
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<string>) {
|
|
||||||
reject(ev.detail);
|
|
||||||
}
|
|
||||||
function onReceiverMessage(
|
|
||||||
ev: CustomEvent<ReceiverSelectorReceiverMessage>
|
|
||||||
) {
|
|
||||||
deviceManager.sendReceiverMessage(
|
|
||||||
ev.detail.deviceId,
|
|
||||||
ev.detail.message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
function onMediaMessage(ev: CustomEvent<ReceiverSelectorMediaMessage>) {
|
|
||||||
deviceManager.sendMediaMessage(
|
|
||||||
ev.detail.deviceId,
|
|
||||||
ev.detail.message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sharedSelector.addEventListener("selected", onSelectorSelected);
|
|
||||||
sharedSelector.addEventListener("stop", onSelectorStop);
|
|
||||||
sharedSelector.addEventListener("cancelled", onSelectorCancelled);
|
|
||||||
sharedSelector.addEventListener("error", onSelectorError);
|
|
||||||
sharedSelector.addEventListener("receiverMessage", onReceiverMessage);
|
|
||||||
sharedSelector.addEventListener("mediaMessage", onMediaMessage);
|
|
||||||
sharedSelector.addEventListener("close", removeListeners);
|
|
||||||
|
|
||||||
function removeListeners() {
|
|
||||||
sharedSelector.removeEventListener("selected", onSelectorSelected);
|
|
||||||
sharedSelector.removeEventListener("stop", onSelectorStop);
|
|
||||||
sharedSelector.removeEventListener(
|
|
||||||
"cancelled",
|
|
||||||
onSelectorCancelled
|
|
||||||
);
|
|
||||||
sharedSelector.removeEventListener("error", onSelectorError);
|
|
||||||
sharedSelector.removeEventListener(
|
|
||||||
"receiverMessage",
|
|
||||||
onReceiverMessage
|
|
||||||
);
|
|
||||||
sharedSelector.removeEventListener("mediaMessage", onMediaMessage);
|
|
||||||
sharedSelector.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<boolean>;
|
|
||||||
if (castInstance?.appId) {
|
|
||||||
const appTag = getAppTag(baseConfig, castInstance.appId);
|
|
||||||
isRequestAppAudioCompatible = appTag?.supports_audio_only;
|
|
||||||
}
|
|
||||||
|
|
||||||
sharedSelector.open({
|
|
||||||
receiverDevices: deviceManager.getDevices(),
|
|
||||||
defaultMediaType,
|
|
||||||
availableMediaTypes,
|
|
||||||
appId: castInstance?.appId,
|
|
||||||
// Create page info
|
|
||||||
pageInfo: pageUrl
|
|
||||||
? {
|
|
||||||
url: pageUrl,
|
|
||||||
tabId: contextTabId,
|
|
||||||
frameId: contextFrameId,
|
|
||||||
sessionRequest: selectionOpts?.sessionRequest,
|
|
||||||
isRequestAppAudioCompatible
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getSelection,
|
|
||||||
getSelector
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user