Implement receiver action listeners

This commit is contained in:
hensm
2020-01-26 16:05:27 +00:00
parent 741379ca72
commit c676184898
7 changed files with 187 additions and 79 deletions

View File

@@ -8,7 +8,8 @@ import options from "../lib/options";
import { Message } from "../types";
import { getMediaTypesForPageUrl } from "../lib/utils";
import { ReceiverSelectorMediaType } from "./receiverSelector";
import { ReceiverSelectionActionType
, ReceiverSelectorMediaType } from "./receiverSelector";
import ReceiverSelectorManager
from "./receiverSelector/ReceiverSelectorManager";
@@ -182,31 +183,46 @@ export default new class ShimManager {
break;
}
/**
* 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) {
shim.contentPort.postMessage({
subject: "shim:/selectReceiverCancelled"
});
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) {
loadSender({
tabId: shim.contentTabId
, frameId: shim.contentFrameId
, selection
});
shim.contentPort.postMessage({
subject: "shim:/selectReceiverCancelled"
});
break;
loadSender({
tabId: shim.contentTabId
, frameId: shim.contentFrameId
, selection
});
break;
}
shim.contentPort.postMessage({
subject: "shim:/selectReceiverEnd"
, data: selection
});
break;
}
case ReceiverSelectionActionType.Stop: {
shim.contentPort.postMessage({
subject: "shim:/selectReceiverStop"
, data: selection
});
break;
}
}
// Pass selection back to shim
shim.contentPort.postMessage({
subject: "shim:/selectReceiverEnd"
, data: selection
});
} catch (err) {
// TODO: Report errors properly
shim.contentPort.postMessage({

View File

@@ -11,7 +11,8 @@ import { getMediaTypesForPageUrl, stringify } from "../lib/utils";
import { CAST_FRAMEWORK_LOADER_SCRIPT_URL
, CAST_LOADER_SCRIPT_URL } from "../lib/endpoints";
import { ReceiverSelectorMediaType } from "./receiverSelector";
import { ReceiverSelectionActionType
, ReceiverSelectorMediaType } from "./receiverSelector";
import ReceiverSelectorManager
from "./receiverSelector/ReceiverSelectorManager";
@@ -200,32 +201,41 @@ async function initMenus () {
break;
}
/**
* If the selected media type is App, that refers to the
* media sender in this context, so load media sender.
*/
if (selection.mediaType === ReceiverSelectorMediaType.App) {
await browser.tabs.executeScript(tab.id, {
code: stringify`
window.receiver = ${selection.receiver};
window.mediaUrl = ${info.srcUrl};
window.targetElementId = ${info.targetElementId};
`
, frameId: info.frameId
});
switch (selection.actionType) {
case ReceiverSelectionActionType.Cast: {
/**
* If the selected media type is App, that refers to the
* media sender in this context, so load media sender.
*/
if (selection.mediaType ===
ReceiverSelectorMediaType.App) {
await browser.tabs.executeScript(tab.id, {
file: "senders/media/bundle.js"
, frameId: info.frameId
});
} else {
await browser.tabs.executeScript(tab.id, {
code: stringify`
window.receiver = ${selection.receiver};
window.mediaUrl = ${info.srcUrl};
window.targetElementId = ${
info.targetElementId};
`
, frameId: info.frameId
});
// Handle other responses
loadSender({
tabId: tab.id
, frameId: info.frameId
, selection
});
await browser.tabs.executeScript(tab.id, {
file: "senders/media/bundle.js"
, frameId: info.frameId
});
} else {
// Handle other responses
loadSender({
tabId: tab.id
, frameId: info.frameId
, selection
});
}
break;
}
}
break;

View File

@@ -11,18 +11,30 @@ export enum ReceiverSelectorMediaType {
, File = 8
}
export interface ReceiverSelection {
export enum ReceiverSelectionActionType {
Cast = 1
, Stop = 2
}
export interface ReceiverSelectionCast {
actionType: ReceiverSelectionActionType.Cast;
receiver: Receiver;
mediaType: ReceiverSelectorMediaType;
filePath?: string;
}
export interface ReceiverSelectionStop {
actionType: ReceiverSelectionActionType.Stop;
receiver: Receiver;
}
export type ReceiverSelection = ReceiverSelectionCast | ReceiverSelectionStop;
export interface ReceiverSelectorEvents {
"selected": ReceiverSelection;
"selected": ReceiverSelectionCast;
"error": string;
"cancelled": void;
"stop": { receiver: Receiver };
"stop": ReceiverSelectionStop;
}
export default interface ReceiverSelector

View File

@@ -13,6 +13,7 @@ import { DEFAULT_MEDIA_RECEIVER_APP_ID } from "../../shim/cast/media/";
import { ReceiverSelector
, ReceiverSelectorType } from "./";
import { ReceiverSelection
, ReceiverSelectionActionType
, ReceiverSelectorMediaType } from "./ReceiverSelector";
import NativeReceiverSelector from "./NativeReceiverSelector";
@@ -122,10 +123,28 @@ async function getSelection (
// Get a new selector for each selection
sharedSelector = await createSelector();
sharedSelector.addEventListener("selected", onSelected);
sharedSelector.addEventListener("cancelled", onCancelled);
sharedSelector.addEventListener("error", onError);
sharedSelector.addEventListener("stop", onStop);
let onSelected: any;
let onCancelled: any;
let onError: any;
let onStop: any;
type EvParamsType =
Parameters<typeof sharedSelector.addEventListener>[0];
function storeListener<T> (type: EvParamsType, fn: T) {
if (type === "selected") {
onSelected = fn;
} else if (type === "cancelled") {
onCancelled = fn;
} else if (type === "error") {
onError = fn;
} else if (type === "stop") {
onStop = fn;
}
return fn;
}
function removeListeners () {
sharedSelector.removeEventListener("selected", onSelected);
@@ -134,31 +153,48 @@ async function getSelection (
sharedSelector.removeEventListener("stop", onStop);
}
function onSelected (ev: any) {
logger.info("Selected receiver", ev.detail);
resolve(ev.detail);
removeListeners();
}
sharedSelector.addEventListener("selected"
, storeListener("selected", ev => {
logger.info("Selected receiver", ev.detail);
resolve({
actionType: ReceiverSelectionActionType.Cast
, receiver: ev.detail.receiver
, mediaType: ev.detail.mediaType
, filePath: ev.detail.filePath
});
removeListeners();
}));
sharedSelector.addEventListener("cancelled"
, storeListener("cancelled", () => {
function onCancelled () {
logger.info("Cancelled receiver selection");
resolve(null);
removeListeners();
}
}));
function onError () {
logger.error("Failed to select receiver");
sharedSelector.addEventListener("error"
, storeListener("error", () => {
reject();
removeListeners();
}
}));
sharedSelector.addEventListener("stop"
, storeListener("stop", ev => {
function onStop (ev: any) {
logger.info("Stopped receiver app", ev.detail);
StatusManager.init().then(() => {
StatusManager.stopReceiverApp(ev.detail.receiver);
});
}
StatusManager.init()
.then(() => StatusManager.stopReceiverApp(ev.detail.receiver))
.then(() => {
resolve({
actionType: ReceiverSelectionActionType.Stop
, receiver: ev.detail.receiver
});
removeListeners();
});
}));
// Ensure status manager is initialized

View File

@@ -14,4 +14,5 @@ export enum ReceiverSelectorType {
}
export { ReceiverSelection
, ReceiverSelectionActionType
, ReceiverSelectorMediaType } from "./ReceiverSelector";