mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
Set browser action details to match cast session states
This commit is contained in:
@@ -8,6 +8,23 @@
|
||||
"description": "Description of the extension shown in the add-ons manager."
|
||||
},
|
||||
|
||||
"actionTitleDefault": {
|
||||
"message": "fx_cast: Ready to cast",
|
||||
"description": "Title for toolbar button in default state."
|
||||
},
|
||||
"actionTitleDisabled": {
|
||||
"message": "fx_cast: Unable to cast",
|
||||
"description": "Title for toolbar button in disabled state."
|
||||
},
|
||||
"actionTitleConnecting": {
|
||||
"message": "fx_cast: Connecting",
|
||||
"description": "Title for toolbar button whilst connecting."
|
||||
},
|
||||
"actionTitleConnected": {
|
||||
"message": "fx_cast: Connected",
|
||||
"description": "Title for toolbar button whilst connected."
|
||||
},
|
||||
|
||||
"popupBridgeErrorBanner": {
|
||||
"message": "There is a problem with the bridge!",
|
||||
"description": "Bridge error banner message."
|
||||
|
||||
75
ext/src/background/action.ts
Normal file
75
ext/src/background/action.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import logger from "../lib/logger";
|
||||
import castManager from "./castManager";
|
||||
|
||||
const _ = browser.i18n.getMessage;
|
||||
|
||||
const ACTION_ICON_DEFAULT_DARK = "icons/cast-default-dark.svg";
|
||||
const ACTION_ICON_DEFAULT_LIGHT = "icons/cast-default-light.svg";
|
||||
const ACTION_ICON_CONNECTING_DARK = "icons/cast-connecting-dark.svg";
|
||||
const ACTION_ICON_CONNECTING_LIGHT = "icons/cast-connecting-light.svg";
|
||||
const ACTION_ICON_CONNECTED = "icons/cast-connected.svg";
|
||||
const ACTION_ICON_DISABLED_DARK = "icons/cast-disabled-dark.svg";
|
||||
const ACTION_ICON_DISABLED_LIGHT = "icons/cast-disabled-light.svg";
|
||||
|
||||
const isDarkTheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
|
||||
export enum ActionState {
|
||||
Default,
|
||||
Connecting,
|
||||
Connected,
|
||||
Disabled
|
||||
}
|
||||
|
||||
/** Updates action details depending on given state. */
|
||||
export function updateActionState(state: ActionState, tabId?: number) {
|
||||
let title: string;
|
||||
let path: string;
|
||||
switch (state) {
|
||||
case ActionState.Default:
|
||||
title = _("actionTitleDefault");
|
||||
path = isDarkTheme
|
||||
? ACTION_ICON_DEFAULT_LIGHT
|
||||
: ACTION_ICON_DEFAULT_DARK;
|
||||
break;
|
||||
case ActionState.Connecting:
|
||||
title = _("actionTitleConnecting");
|
||||
path = isDarkTheme
|
||||
? ACTION_ICON_CONNECTING_LIGHT
|
||||
: ACTION_ICON_CONNECTING_DARK;
|
||||
break;
|
||||
case ActionState.Connected:
|
||||
title = _("actionTitleConnected");
|
||||
path = ACTION_ICON_CONNECTED;
|
||||
break;
|
||||
case ActionState.Disabled:
|
||||
title = _("actionTitleDisabled");
|
||||
path = isDarkTheme
|
||||
? ACTION_ICON_DISABLED_LIGHT
|
||||
: ACTION_ICON_DISABLED_DARK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state === ActionState.Disabled) {
|
||||
browser.browserAction.disable(tabId);
|
||||
} else {
|
||||
browser.browserAction.enable(tabId);
|
||||
}
|
||||
|
||||
browser.browserAction.setTitle({ tabId, title });
|
||||
browser.browserAction.setIcon({ tabId, path });
|
||||
}
|
||||
|
||||
export function initAction() {
|
||||
logger.info("init (action)");
|
||||
|
||||
updateActionState(ActionState.Default);
|
||||
|
||||
browser.browserAction.onClicked.addListener(async tab => {
|
||||
if (tab.id === undefined) {
|
||||
logger.error("Tab ID not found in browser action handler.");
|
||||
return;
|
||||
}
|
||||
|
||||
castManager.triggerCast(tab.id);
|
||||
});
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import messaging from "../messaging";
|
||||
import castManager from "./castManager";
|
||||
import deviceManager from "./deviceManager";
|
||||
|
||||
import { initAction } from "./action";
|
||||
import { initMenus } from "./menus";
|
||||
import { initWhitelist } from "./whitelist";
|
||||
|
||||
@@ -129,6 +130,7 @@ async function init() {
|
||||
await deviceManager.init();
|
||||
await castManager.init();
|
||||
|
||||
await initAction();
|
||||
await initMenus();
|
||||
await initWhitelist();
|
||||
|
||||
@@ -139,15 +141,6 @@ async function init() {
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
browser.browserAction.onClicked.addListener(async tab => {
|
||||
if (tab.id === undefined) {
|
||||
logger.error("Tab ID not found in browser action handler.");
|
||||
return;
|
||||
}
|
||||
|
||||
castManager.triggerCast(tab.id);
|
||||
});
|
||||
}
|
||||
|
||||
cacheBaseConfig();
|
||||
|
||||
@@ -27,6 +27,7 @@ import ReceiverSelector, {
|
||||
} from "./ReceiverSelector";
|
||||
|
||||
import deviceManager from "./deviceManager";
|
||||
import { ActionState, updateActionState } from "./action";
|
||||
|
||||
type AnyPort = Port | TypedMessagePort<Message>;
|
||||
|
||||
@@ -85,6 +86,13 @@ async function createCastSession(opts: {
|
||||
destroyCastInstance(opts.instance)
|
||||
);
|
||||
|
||||
if (opts.instance.contentContext?.tabId) {
|
||||
updateActionState(
|
||||
ActionState.Connecting,
|
||||
opts.instance.contentContext?.tabId
|
||||
);
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
@@ -161,6 +169,10 @@ function destroyCastInstance(instance: CastInstance) {
|
||||
);
|
||||
}
|
||||
|
||||
if (instance.contentContext?.tabId) {
|
||||
updateActionState(ActionState.Default, instance.contentContext?.tabId);
|
||||
}
|
||||
|
||||
activeInstances.delete(instance);
|
||||
}
|
||||
|
||||
@@ -227,6 +239,13 @@ const castManager = new (class {
|
||||
});
|
||||
|
||||
delete instance.session;
|
||||
|
||||
if (instance.contentContext?.tabId) {
|
||||
updateActionState(
|
||||
ActionState.Default,
|
||||
instance.contentContext?.tabId
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,6 +426,13 @@ async function handleBridgeMessage(instance: CastInstance, message: Message) {
|
||||
}
|
||||
});
|
||||
|
||||
if (instance.contentContext?.tabId) {
|
||||
updateActionState(
|
||||
ActionState.Connected,
|
||||
instance.contentContext?.tabId
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -529,6 +555,13 @@ async function handleContentMessage(instance: CastInstance, message: Message) {
|
||||
}
|
||||
});
|
||||
|
||||
if (instance.contentContext?.tabId) {
|
||||
updateActionState(
|
||||
ActionState.Connected,
|
||||
instance.contentContext?.tabId
|
||||
);
|
||||
}
|
||||
|
||||
break sessionLoop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import type {
|
||||
} from "../cast/sdk/types";
|
||||
import { PlayerState } from "../cast/sdk/media/enums";
|
||||
|
||||
import { ActionState, updateActionState } from "./action";
|
||||
|
||||
interface EventMap {
|
||||
deviceUp: { deviceInfo: ReceiverDevice };
|
||||
deviceDown: { deviceId: string };
|
||||
@@ -45,6 +47,8 @@ export default new (class extends TypedEventTarget<EventMap> {
|
||||
async refresh() {
|
||||
this.bridgePort?.disconnect();
|
||||
|
||||
updateActionState(ActionState.Disabled);
|
||||
|
||||
try {
|
||||
this.bridgeInfo = await bridge.getInfo();
|
||||
// eslint-disable-next-line no-empty
|
||||
@@ -65,6 +69,14 @@ export default new (class extends TypedEventTarget<EventMap> {
|
||||
}
|
||||
}
|
||||
|
||||
private updateAction() {
|
||||
if (this.receiverDevices.size > 0) {
|
||||
updateActionState(ActionState.Default);
|
||||
} else {
|
||||
updateActionState(ActionState.Disabled);
|
||||
}
|
||||
}
|
||||
|
||||
getBridgeInfo() {
|
||||
return this.bridgeInfo;
|
||||
}
|
||||
@@ -142,6 +154,8 @@ export default new (class extends TypedEventTarget<EventMap> {
|
||||
})
|
||||
);
|
||||
|
||||
this.updateAction();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -157,6 +171,8 @@ export default new (class extends TypedEventTarget<EventMap> {
|
||||
})
|
||||
);
|
||||
|
||||
this.updateAction();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user