Refresh device manager with options bridge status and propagate to popup

This commit is contained in:
hensm
2022-09-04 07:32:42 +01:00
parent 25bd72f0fe
commit 75f334f4ae
8 changed files with 75 additions and 37 deletions

View File

@@ -149,11 +149,15 @@ export default class ReceiverSelector extends TypedEventTarget<ReceiverSelectorE
} }
/** Updates receiver devices displayed in the receiver selector. */ /** Updates receiver devices displayed in the receiver selector. */
public update(devices: ReceiverDevice[], connectedSessionIds: string[]) { public update(
devices: ReceiverDevice[],
isBridgeCompatible: boolean,
connectedSessionIds: string[]
) {
this.devices = devices; this.devices = devices;
this.messagePort?.postMessage({ this.messagePort?.postMessage({
subject: "popup:update", subject: "popup:update",
data: { devices, connectedSessionIds } data: { devices, isBridgeCompatible, connectedSessionIds }
}); });
} }
@@ -205,8 +209,7 @@ export default class ReceiverSelector extends TypedEventTarget<ReceiverSelectorE
subject: "popup:init", subject: "popup:init",
data: { data: {
appInfo: this.appInfo, appInfo: this.appInfo,
pageInfo: this.pageInfo, pageInfo: this.pageInfo
isBridgeCompatible: this.isBridgeCompatible
} }
}); });
@@ -214,6 +217,7 @@ export default class ReceiverSelector extends TypedEventTarget<ReceiverSelectorE
subject: "popup:update", subject: "popup:update",
data: { data: {
devices: this.devices, devices: this.devices,
isBridgeCompatible: this.isBridgeCompatible,
defaultMediaType: this.defaultMediaType, defaultMediaType: this.defaultMediaType,
availableMediaTypes: this.availableMediaTypes availableMediaTypes: this.availableMediaTypes
} }

View File

@@ -1,14 +1,16 @@
import defaultOptions from "../defaultOptions";
import logger from "../lib/logger"; import logger from "../lib/logger";
import options from "../lib/options"; import options from "../lib/options";
import bridge, { BridgeInfo } from "../lib/bridge"; import bridge, { BridgeInfo } from "../lib/bridge";
import { baseConfigStorage, fetchBaseConfig } from "../lib/chromecastConfigApi";
import defaultOptions from "../defaultOptions";
import messaging from "../messaging";
import castManager from "./castManager"; import castManager from "./castManager";
import deviceManager from "./deviceManager"; import deviceManager from "./deviceManager";
import { initMenus } from "./menus"; import { initMenus } from "./menus";
import { initWhitelist } from "./whitelist"; import { initWhitelist } from "./whitelist";
import { baseConfigStorage, fetchBaseConfig } from "../lib/chromecastConfigApi";
const _ = browser.i18n.getMessage; const _ = browser.i18n.getMessage;
@@ -130,6 +132,14 @@ async function init() {
await initMenus(); await initMenus();
await initWhitelist(); await initWhitelist();
messaging.onMessage.addListener(message => {
switch (message.subject) {
case "main:refreshDeviceManager":
deviceManager.refresh();
break;
}
});
browser.browserAction.onClicked.addListener(async tab => { browser.browserAction.onClicked.addListener(async tab => {
if (tab.id === undefined) { if (tab.id === undefined) {
logger.error("Tab ID not found in browser action handler."); logger.error("Tab ID not found in browser action handler.");

View File

@@ -761,7 +761,11 @@ function createSelector() {
} }
} }
selector.update(deviceManager.getDevices(), connectedSessionIds); selector.update(
deviceManager.getDevices(),
deviceManager.getBridgeInfo()?.isVersionCompatible ?? false,
connectedSessionIds
);
}; };
deviceManager.addEventListener("deviceUp", onDeviceChange); deviceManager.addEventListener("deviceUp", onDeviceChange);

View File

@@ -47,7 +47,6 @@ export default new (class extends TypedEventTarget<EventMap> {
*/ */
async refresh() { async refresh() {
this.bridgePort?.disconnect(); this.bridgePort?.disconnect();
this.receiverDevices.clear();
try { try {
this.bridgeInfo = await bridge.getInfo(); this.bridgeInfo = await bridge.getInfo();
@@ -218,20 +217,28 @@ export default new (class extends TypedEventTarget<EventMap> {
}; };
private onBridgeDisconnect = () => { private onBridgeDisconnect = () => {
const deviceIds = [...this.receiverDevices.keys()];
delete this.bridgeInfo;
this.receiverDevices.clear();
// Notify listeners of device availablility // Notify listeners of device availablility
for (const [, receiverDevice] of this.receiverDevices) { for (const deviceId of deviceIds) {
const event = new CustomEvent("deviceDown", { const event = new CustomEvent("deviceDown", {
detail: { deviceId: receiverDevice.id } detail: { deviceId }
}); });
this.dispatchEvent(event); this.dispatchEvent(event);
} }
this.receiverDevices.clear(); /**
* Reconnect 10 seconds after disconnect if not already
// Re-initialize after 10 seconds * reconnected (like immediately after a refresh).
*/
window.setTimeout(() => { window.setTimeout(() => {
this.refresh(); if (!this.bridgeInfo) {
this.refresh();
}
}, 10000); }, 10000);
}; };
})(); })();

View File

@@ -46,11 +46,11 @@ type ExtMessageDefinitions = {
"popup:init": { "popup:init": {
appInfo?: ReceiverSelectorAppInfo; appInfo?: ReceiverSelectorAppInfo;
pageInfo?: ReceiverSelectorPageInfo; pageInfo?: ReceiverSelectorPageInfo;
isBridgeCompatible: boolean;
}; };
/** Updates selector popup with new data. */ /** Updates selector popup with new data. */
"popup:update": { "popup:update": {
devices: ReceiverDevice[]; devices: ReceiverDevice[];
isBridgeCompatible: boolean;
connectedSessionIds?: string[]; connectedSessionIds?: string[];
defaultMediaType?: ReceiverSelectorMediaType; defaultMediaType?: ReceiverSelectorMediaType;
availableMediaTypes?: ReceiverSelectorMediaType; availableMediaTypes?: ReceiverSelectorMediaType;
@@ -102,6 +102,12 @@ type ExtMessageDefinitions = {
"main:sendReceiverMessage": ReceiverSelectorReceiverMessage; "main:sendReceiverMessage": ReceiverSelectorReceiverMessage;
/** Allows the selector popup to send cast NS_MEDIA messages. */ /** Allows the selector popup to send cast NS_MEDIA messages. */
"main:sendMediaMessage": ReceiverSelectorMediaMessage; "main:sendMediaMessage": ReceiverSelectorMediaMessage;
/**
* Tells the device manager to clear its device list and re-connect
* to the bridge.
*/
"main:refreshDeviceManager": void;
}; };
/** /**
@@ -319,21 +325,23 @@ export default new (class Messenger {
return browser.tabs.connect(tabId, connectInfo) as Port; return browser.tabs.connect(tabId, connectInfo) as Port;
} }
onConnect = { sendMessage(
addListener(cb: (port: Port) => void) { message: Message,
browser.runtime.onConnect.addListener( options?: browser.runtime._SendMessageOptions
cb as (port: browser.runtime.Port) => void ): Promise<any>;
); sendMessage(
}, extensionId: string,
removeListener(cb: (port: Port) => void) { options?: browser.runtime._SendMessageOptions
browser.runtime.onConnect.removeListener( ): Promise<any>;
cb as (port: browser.runtime.Port) => void sendMessage(
); messageOrExtensionId: string | Message,
}, options?: browser.runtime._SendMessageOptions
hasListener(cb: (port: Port) => void) { ) {
return browser.runtime.onConnect.hasListener( return browser.runtime.sendMessage(messageOrExtensionId, options);
cb as (port: browser.runtime.Port) => void }
);
} onConnect = browser.runtime.onConnect as WebExtEvent<(port: Port) => void>;
}; onMessage = browser.runtime.onMessage as WebExtEvent<
(message: Message, sender: browser.runtime.MessageSender) => void
>;
})(); })();

View File

@@ -10,9 +10,10 @@
BridgeAuthenticationError BridgeAuthenticationError
} from "../../lib/bridge"; } from "../../lib/bridge";
import logger from "../../lib/logger"; import logger from "../../lib/logger";
import type { Options } from "../../lib/options"; import type { Options } from "../../lib/options";
import messaging from "../../messaging";
const _ = browser.i18n.getMessage; const _ = browser.i18n.getMessage;
export let opts: Options; export let opts: Options;
@@ -26,13 +27,15 @@
let statusTitle: string; let statusTitle: string;
let statusText: Nullable<string> = null; let statusText: Nullable<string> = null;
async function checkBridgeStatus() { async function refreshBridgeStatus() {
// Reset state // Reset state
bridgeInfo = null; bridgeInfo = null;
bridgeInfoError = null; bridgeInfoError = null;
isLoadingInfo = true; isLoadingInfo = true;
statusText = null; statusText = null;
messaging.sendMessage({ subject: "main:refreshDeviceManager" });
try { try {
bridgeInfo = await bridge.getInfo(); bridgeInfo = await bridge.getInfo();
} catch (err) { } catch (err) {
@@ -78,7 +81,7 @@
} }
onMount(() => { onMount(() => {
checkBridgeStatus(); refreshBridgeStatus();
}); });
// Updates // Updates
@@ -197,7 +200,7 @@
type="button" type="button"
class="ghost bridge__refresh" class="ghost bridge__refresh"
title={_("optionsBridgeRefresh")} title={_("optionsBridgeRefresh")}
on:click={checkBridgeStatus} on:click={refreshBridgeStatus}
/> />
</div> </div>

View File

@@ -174,10 +174,11 @@
case "popup:init": case "popup:init":
appInfo = message.data.appInfo; appInfo = message.data.appInfo;
pageInfo = message.data.pageInfo; pageInfo = message.data.pageInfo;
isBridgeCompatible = message.data.isBridgeCompatible;
break; break;
case "popup:update": { case "popup:update": {
isBridgeCompatible = message.data.isBridgeCompatible;
updateKnownApp(); updateKnownApp();
if ( if (

View File

@@ -92,6 +92,7 @@ body {
.receiver-list__not-found { .receiver-list__not-found {
align-items: center; align-items: center;
color: var(--secondary-color);
display: flex; display: flex;
height: 50px; height: 50px;
justify-content: center; justify-content: center;