diff --git a/app/src/bridge/index.ts b/app/src/bridge/index.ts index 4ed4285..5ff3915 100755 --- a/app/src/bridge/index.ts +++ b/app/src/bridge/index.ts @@ -387,7 +387,8 @@ function initialize (options: InitializeOptions) { const application = status.applications[0]; receiverStatusMessage.data.status.application = { - displayName: application.displayName + appId: application.appId + , displayName: application.displayName , isIdleScreen: application.isIdleScreen , statusText: application.statusText }; diff --git a/ext/src/background/ShimManager.ts b/ext/src/background/ShimManager.ts index 960f868..22b4312 100644 --- a/ext/src/background/ShimManager.ts +++ b/ext/src/background/ShimManager.ts @@ -22,6 +22,7 @@ export interface Shim { contentPort: Port; contentTabId?: number; contentFrameId?: number; + requestedAppId?: string; } @@ -33,6 +34,18 @@ export default new class ShimManager { await this.initStatusListeners(); } + public getShim (tabId: number, frameId?: number) { + for (const activeShim of this.activeShims) { + if (activeShim.contentTabId === tabId) { + if (frameId && activeShim.contentFrameId !== frameId) { + continue; + } + + return activeShim; + } + } + } + public async createShim (port: Port) { const shim = await (port instanceof MessagePort ? this.createShimFromBackground(port) @@ -129,6 +142,8 @@ export default new class ShimManager { switch (message.subject) { case "main:/shimInitialized": { + shim.requestedAppId = message.data.appId; + for (const receiver of StatusManager.getReceivers()) { shim.contentPort.postMessage({ subject: "shim:/serviceUp" @@ -148,7 +163,8 @@ export default new class ShimManager { const selection = await ReceiverSelectorManager .getSelection( ReceiverSelectorMediaType.App - , availableMediaTypes); + , availableMediaTypes + , shim.requestedAppId); // Handle cancellation if (!selection) { diff --git a/ext/src/background/background.ts b/ext/src/background/background.ts index 418ba09..24594ca 100755 --- a/ext/src/background/background.ts +++ b/ext/src/background/background.ts @@ -65,10 +65,12 @@ function initBrowserAction () { * top-level frame. */ browser.browserAction.onClicked.addListener(async tab => { + const currentShim = ShimManager.getShim(tab.id); const selection = await ReceiverSelectorManager.getSelection( ReceiverSelectorMediaType.Tab , getMediaTypesForPageUrl(tab.url) - & ~ReceiverSelectorMediaType.App); + & ~ReceiverSelectorMediaType.App + , currentShim.requestedAppId); if (selection) { loadSender({ @@ -159,9 +161,11 @@ async function initMenus () { switch (info.menuItemId) { case menuIdMediaCast: { + const currentShim = ShimManager.getShim(tab.id, info.frameId); const selection = await ReceiverSelectorManager.getSelection( ReceiverSelectorMediaType.App - , availableMediaTypes); + , availableMediaTypes + , currentShim.requestedAppId); // Selection cancelled if (!selection) { @@ -200,9 +204,11 @@ async function initMenus () { } case menuIdMirroringCast: { + const currentShim = ShimManager.getShim(tab.id, info.frameId); const selection = await ReceiverSelectorManager.getSelection( ReceiverSelectorMediaType.Tab - , availableMediaTypes & ~ReceiverSelectorMediaType.App); + , availableMediaTypes & ~ReceiverSelectorMediaType.App + , currentShim.requestedAppId); loadSender({ tabId: tab.id diff --git a/ext/src/background/receiverSelector/NativeReceiverSelector.ts b/ext/src/background/receiverSelector/NativeReceiverSelector.ts index 6b5a077..779d449 100644 --- a/ext/src/background/receiverSelector/NativeReceiverSelector.ts +++ b/ext/src/background/receiverSelector/NativeReceiverSelector.ts @@ -1,6 +1,7 @@ "use strict"; import bridge from "../../lib/bridge"; +import knownApps from "../../lib/knownApps"; import options from "../../lib/options"; import { TypedEventTarget } from "../../lib/typedEvents"; @@ -43,7 +44,8 @@ export default class NativeReceiverSelector public async open ( receivers: Receiver[] , defaultMediaType: ReceiverSelectorMediaType - , availableMediaTypes: ReceiverSelectorMediaType): Promise { + , availableMediaTypes: ReceiverSelectorMediaType + , requestedAppId: string): Promise { this.bridgePort = await bridge.connect(); @@ -94,7 +96,8 @@ export default class NativeReceiverSelector , i18n_extensionName: _("extensionName") , i18n_castButtonTitle: _("popupCastButtonTitle") - , i18n_mediaTypeApp: _("popupMediaTypeApp") + , i18n_mediaTypeApp: + knownApps[requestedAppId] ?? _("popupMediaTypeApp") , i18n_mediaTypeTab: _("popupMediaTypeTab") , i18n_mediaTypeScreen: _("popupMediaTypeScreen") , i18n_mediaTypeFile: _("popupMediaTypeFile") diff --git a/ext/src/background/receiverSelector/PopupReceiverSelector.ts b/ext/src/background/receiverSelector/PopupReceiverSelector.ts index 1b6dd04..4fd91b8 100644 --- a/ext/src/background/receiverSelector/PopupReceiverSelector.ts +++ b/ext/src/background/receiverSelector/PopupReceiverSelector.ts @@ -27,6 +27,7 @@ export default class PopupReceiverSelector private wasReceiverSelected: boolean = false; private _isOpen: boolean = false; + private requestedAppId: string; constructor () { @@ -59,6 +60,11 @@ export default class PopupReceiverSelector this.messagePortDisconnected = true; }); + this.messagePort.postMessage({ + subject: "popup:/sendRequestedAppId" + , data: { requestedAppId: this.requestedAppId } + }); + this.messagePort.postMessage({ subject: "popup:/populateReceiverList" , data: { @@ -77,7 +83,10 @@ export default class PopupReceiverSelector public async open ( receivers: Receiver[] , defaultMediaType: ReceiverSelectorMediaType - , availableMediaTypes: ReceiverSelectorMediaType): Promise { + , availableMediaTypes: ReceiverSelectorMediaType + , requestedAppId: string): Promise { + + this.requestedAppId = requestedAppId; // If popup already exists, close it if (this.windowId) { @@ -124,6 +133,7 @@ export default class PopupReceiverSelector } this._isOpen = false; + this.requestedAppId = null; if (this.messagePort && !this.messagePortDisconnected) { this.messagePort.disconnect(); diff --git a/ext/src/background/receiverSelector/ReceiverSelector.ts b/ext/src/background/receiverSelector/ReceiverSelector.ts index edd8d90..aa7412c 100644 --- a/ext/src/background/receiverSelector/ReceiverSelector.ts +++ b/ext/src/background/receiverSelector/ReceiverSelector.ts @@ -31,7 +31,8 @@ export default interface ReceiverSelector open (receivers: Receiver[] , defaultMediaType: ReceiverSelectorMediaType - , availableMediaTypes: ReceiverSelectorMediaType): void; + , availableMediaTypes: ReceiverSelectorMediaType + , requestedAppId: string): void; close (): void; } diff --git a/ext/src/background/receiverSelector/ReceiverSelectorManager.ts b/ext/src/background/receiverSelector/ReceiverSelectorManager.ts index 9ff7659..3071662 100644 --- a/ext/src/background/receiverSelector/ReceiverSelectorManager.ts +++ b/ext/src/background/receiverSelector/ReceiverSelectorManager.ts @@ -54,7 +54,8 @@ async function getSelection ( , availableMediaTypes = ReceiverSelectorMediaType.Tab | ReceiverSelectorMediaType.Screen - | ReceiverSelectorMediaType.File) + | ReceiverSelectorMediaType.File + , requestedAppId: string) : Promise { return new Promise(async (resolve, reject) => { @@ -104,7 +105,8 @@ async function getSelection ( sharedSelector.open( Array.from(StatusManager.getReceivers()) , defaultMediaType - , availableMediaTypes); + , availableMediaTypes + , requestedAppId); }); } diff --git a/ext/src/lib/knownApps.ts b/ext/src/lib/knownApps.ts new file mode 100644 index 0000000..0b99af0 --- /dev/null +++ b/ext/src/lib/knownApps.ts @@ -0,0 +1,23 @@ +"use strict"; + +/** + * TODO: Just keep a list of IDs and cache names from the Google API: + * https://clients3.google.com/cast/chromecast/device/app?a=[appId] + * + * Also, localization since the API supports it. + */ +export default { + "CA5E8412": "Netflix" + , "233637DE": "YouTube" + , "17608BC8": "Prime Video" + , "CC32E753": "Spotify" + , "5E81F6DB": "BBC iPlayer" + , "03977A48": "BBC Sounds" + , "AA666EDD": "Crunchyroll" + , "10AAD887": "All 4" + , "9AC194DC": "Plex" + , "CD7B9F59": "Global Player Live" + , "B3DCF968": "Twitch" + , "B88B034A": "Dailymotion" + , "CC1AD845": "TEST" +} as Record; diff --git a/ext/src/manifest.json b/ext/src/manifest.json index 9882da4..ddc1925 100755 --- a/ext/src/manifest.json +++ b/ext/src/manifest.json @@ -32,7 +32,7 @@ "all_frames": true , "js": [ "shim/content.js" - , "senders/media/overlay/overlayContentLoader.js" + //, "senders/media/overlay/overlayContentLoader.js" ] , "matches": [ "" ] , "run_at": "document_start" diff --git a/ext/src/shim/cast/index.ts b/ext/src/shim/cast/index.ts index 1e84978..1984278 100755 --- a/ext/src/shim/cast/index.ts +++ b/ext/src/shim/cast/index.ts @@ -101,6 +101,7 @@ export function initialize ( sendMessageResponse({ subject: "main:/shimInitialized" + , data: { appId: apiConfig.sessionRequest.appId } }); apiConfig.receiverListener(receiverList.length diff --git a/ext/src/ui/popup/index.tsx b/ext/src/ui/popup/index.tsx index 3c0ef0c..f5f1013 100755 --- a/ext/src/ui/popup/index.tsx +++ b/ext/src/ui/popup/index.tsx @@ -4,6 +4,8 @@ import React, { Component } from "react"; import ReactDOM from "react-dom"; +import knownApps from "../../lib/knownApps"; + import { getNextEllipsis } from "../../lib/utils"; import { Message, Receiver } from "../../types"; @@ -30,6 +32,7 @@ interface PopupAppState { availableMediaTypes: ReceiverSelectorMediaType; isLoading: boolean; filePath: string; + requestedAppId: string; } class PopupApp extends Component<{}, PopupAppState> { @@ -46,6 +49,7 @@ class PopupApp extends Component<{}, PopupAppState> { , availableMediaTypes: ReceiverSelectorMediaType.App , isLoading: false , filePath: null + , requestedAppId: null }; // Store window ref @@ -64,6 +68,14 @@ class PopupApp extends Component<{}, PopupAppState> { this.port.onMessage.addListener((message: Message) => { switch (message.subject) { + case "popup:/sendRequestedAppId": { + this.setState({ + requestedAppId: message.data.requestedAppId + }); + + break; + } + case "popup:/populateReceiverList": { this.defaultMediaType = message.data.defaultMediaType; @@ -124,7 +136,8 @@ class PopupApp extends Component<{}, PopupAppState> {