mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
Add popup warning banner when the bridge has a problem
This commit is contained in:
@@ -8,6 +8,14 @@
|
|||||||
"description": "Description of the extension shown in the add-ons manager."
|
"description": "Description of the extension shown in the add-ons manager."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"popupBridgeErrorBanner": {
|
||||||
|
"message": "There is a problem with the bridge!",
|
||||||
|
"description": "Bridge error banner message."
|
||||||
|
},
|
||||||
|
"popupBridgeErrorBannerOptions": {
|
||||||
|
"message": "More Information",
|
||||||
|
"description": "Bridge error banner button label."
|
||||||
|
},
|
||||||
"popupWhitelistNotWhitelisted": {
|
"popupWhitelistNotWhitelisted": {
|
||||||
"message": "$appName$ is not whitelisted",
|
"message": "$appName$ is not whitelisted",
|
||||||
"description": "Receiver selector whitelist suggestion banner label.",
|
"description": "Receiver selector whitelist suggestion banner label.",
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default class ReceiverSelector extends TypedEventTarget<ReceiverSelectorE
|
|||||||
appInfo?: ReceiverSelectorAppInfo;
|
appInfo?: ReceiverSelectorAppInfo;
|
||||||
pageInfo?: ReceiverSelectorPageInfo;
|
pageInfo?: ReceiverSelectorPageInfo;
|
||||||
|
|
||||||
constructor() {
|
constructor(private isBridgeCompatible: boolean) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.onConnect = this.onConnect.bind(this);
|
this.onConnect = this.onConnect.bind(this);
|
||||||
@@ -205,7 +205,8 @@ 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
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -710,7 +710,9 @@ async function getReceiverSelection(selectionOpts: {
|
|||||||
*/
|
*/
|
||||||
function createSelector() {
|
function createSelector() {
|
||||||
// Get a new selector for each selection
|
// Get a new selector for each selection
|
||||||
const selector = new ReceiverSelector();
|
const selector = new ReceiverSelector(
|
||||||
|
deviceManager.getBridgeInfo()?.isVersionCompatible ?? false
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends message to cast instance to trigger stopped receiver action
|
* Sends message to cast instance to trigger stopped receiver action
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import bridge from "../lib/bridge";
|
import bridge, { BridgeInfo } from "../lib/bridge";
|
||||||
import logger from "../lib/logger";
|
import logger from "../lib/logger";
|
||||||
import { TypedEventTarget } from "../lib/TypedEventTarget";
|
import { TypedEventTarget } from "../lib/TypedEventTarget";
|
||||||
|
|
||||||
@@ -34,6 +34,7 @@ export default new (class extends TypedEventTarget<EventMap> {
|
|||||||
private receiverDevices = new Map<string, ReceiverDevice>();
|
private receiverDevices = new Map<string, ReceiverDevice>();
|
||||||
|
|
||||||
private bridgePort?: Port;
|
private bridgePort?: Port;
|
||||||
|
private bridgeInfo?: BridgeInfo;
|
||||||
async init() {
|
async init() {
|
||||||
if (!this.bridgePort) {
|
if (!this.bridgePort) {
|
||||||
await this.refresh();
|
await this.refresh();
|
||||||
@@ -48,17 +49,28 @@ export default new (class extends TypedEventTarget<EventMap> {
|
|||||||
this.bridgePort?.disconnect();
|
this.bridgePort?.disconnect();
|
||||||
this.receiverDevices.clear();
|
this.receiverDevices.clear();
|
||||||
|
|
||||||
this.bridgePort = await bridge.connect();
|
try {
|
||||||
this.bridgePort.onMessage.addListener(this.onBridgeMessage);
|
this.bridgeInfo = await bridge.getInfo();
|
||||||
this.bridgePort.onDisconnect.addListener(this.onBridgeDisconnect);
|
// eslint-disable-next-line no-empty
|
||||||
|
} catch {}
|
||||||
|
|
||||||
this.bridgePort.postMessage({
|
if (this.bridgeInfo?.isVersionCompatible) {
|
||||||
subject: "bridge:startDiscovery",
|
this.bridgePort = await bridge.connect();
|
||||||
data: {
|
this.bridgePort.onMessage.addListener(this.onBridgeMessage);
|
||||||
// Also send back status messages
|
this.bridgePort.onDisconnect.addListener(this.onBridgeDisconnect);
|
||||||
shouldWatchStatus: true
|
|
||||||
}
|
this.bridgePort.postMessage({
|
||||||
});
|
subject: "bridge:startDiscovery",
|
||||||
|
data: {
|
||||||
|
// Also send back status messages
|
||||||
|
shouldWatchStatus: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getBridgeInfo() {
|
||||||
|
return this.bridgeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a list of receiver devices. */
|
/** Gets a list of receiver devices. */
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ 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": {
|
||||||
|
|||||||
@@ -3,11 +3,14 @@
|
|||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<style>
|
<style>
|
||||||
|
path {
|
||||||
|
fill: rgba(12, 12, 13, .8);
|
||||||
|
}
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
path {
|
path {
|
||||||
fill: rgba(249, 249, 250, .8);
|
fill: rgba(249, 249, 250, .8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<path fill="rgba(12, 12, 13, .8)" d="M8 1a7 7 0 1 0 7 7 7.008 7.008 0 0 0-7-7zm0 13a6 6 0 1 1 6-6 6.007 6.007 0 0 1-6 6zm0-7a1 1 0 0 0-1 1v3a1 1 0 1 0 2 0V8a1 1 0 0 0-1-1zm0-3.188A1.188 1.188 0 1 0 9.188 5 1.188 1.188 0 0 0 8 3.812z"></path>
|
<path d="M8 1a7 7 0 1 0 7 7 7.008 7.008 0 0 0-7-7zm0 13a6 6 0 1 1 6-6 6.007 6.007 0 0 1-6 6zm0-7a1 1 0 0 0-1 1v3a1 1 0 1 0 2 0V8a1 1 0 0 0-1-1zm0-3.188A1.188 1.188 0 1 0 9.188 5 1.188 1.188 0 0 0 8 3.812z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 710 B After Width: | Height: | Size: 746 B |
16
ext/src/ui/assets/photon_warning.svg
Normal file
16
ext/src/ui/assets/photon_warning.svg
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<style>
|
||||||
|
path {
|
||||||
|
fill: rgba(12, 12, 13, .8);
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
path {
|
||||||
|
fill: rgba(249, 249, 250, .8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<path d="M14.742 12.106L9.789 2.2a2 2 0 0 0-3.578 0l-4.953 9.91A2 2 0 0 0 3.047 15h9.905a2 2 0 0 0 1.79-2.894zM7 5a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0zm1 8.25A1.25 1.25 0 1 1 9.25 12 1.25 1.25 0 0 1 8 13.25z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 741 B |
@@ -27,6 +27,9 @@
|
|||||||
/** Media types available to select. */
|
/** Media types available to select. */
|
||||||
let availableMediaTypes = ReceiverSelectorMediaType.App;
|
let availableMediaTypes = ReceiverSelectorMediaType.App;
|
||||||
|
|
||||||
|
/** Whether to show bridge warning banner. */
|
||||||
|
let isBridgeCompatible = true;
|
||||||
|
|
||||||
/** Devices to display. */
|
/** Devices to display. */
|
||||||
let devices: ReceiverDevice[] = [];
|
let devices: ReceiverDevice[] = [];
|
||||||
/** IDs of sessions connected by this extension. */
|
/** IDs of sessions connected by this extension. */
|
||||||
@@ -171,6 +174,7 @@
|
|||||||
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": {
|
||||||
@@ -319,18 +323,32 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="whitelist-banner" hidden={!shouldSuggestWhitelist}>
|
{#if !isBridgeCompatible}
|
||||||
<img src="photon_info.svg" alt="icon, info" />
|
<div class="banner banner--warn">
|
||||||
{_("popupWhitelistNotWhitelisted", knownApp?.name)}
|
{_("popupBridgeErrorBanner")}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (!knownApp || !pageInfo) return;
|
browser.runtime.openOptionsPage();
|
||||||
addToWhitelist(knownApp, pageInfo);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{_("popupBridgeErrorBannerOptions")}
|
||||||
{_("popupWhitelistAddToWhitelist")}
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
|
|
||||||
|
{#if shouldSuggestWhitelist}
|
||||||
|
<div class="banner banner--info">
|
||||||
|
{_("popupWhitelistNotWhitelisted", knownApp?.name)}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
if (!knownApp || !pageInfo) return;
|
||||||
|
addToWhitelist(knownApp, pageInfo);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{_("popupWhitelistAddToWhitelist")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if availableMediaTypes !== ReceiverSelectorMediaType.None}
|
{#if availableMediaTypes !== ReceiverSelectorMediaType.None}
|
||||||
<div class="media-type-select">
|
<div class="media-type-select">
|
||||||
|
|||||||
@@ -91,13 +91,13 @@
|
|||||||
isExpanded = false;
|
isExpanded = false;
|
||||||
} else if (
|
} else if (
|
||||||
// If app is running
|
// If app is running
|
||||||
application?.appId &&
|
application &&
|
||||||
// And user hasn't manually changed the expanded state
|
// And user hasn't manually changed the expanded state
|
||||||
!isExpandedUserModified &&
|
!isExpandedUserModified &&
|
||||||
// And auto-expansion is enabled
|
// And auto-expansion is enabled
|
||||||
opts?.receiverSelectorExpandActive
|
opts?.receiverSelectorExpandActive
|
||||||
) {
|
) {
|
||||||
isExpanded = connectedSessionIds.includes(application?.transportId);
|
isExpanded = connectedSessionIds.includes(application.transportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether a session request is in progress for this receiver.. */
|
/** Whether a session request is in progress for this receiver.. */
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
#root {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
--font-size: 13px;
|
--font-size: 13px;
|
||||||
background: var(--box-background);
|
background: var(--box-background);
|
||||||
@@ -12,7 +21,7 @@ body {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.whitelist-banner {
|
.banner {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: var(--blue-50-a30);
|
background-color: var(--blue-50-a30);
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
||||||
@@ -21,18 +30,34 @@ body {
|
|||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
padding: 0.5em 0.75em;
|
padding: 0.5em 0.75em;
|
||||||
}
|
}
|
||||||
.whitelist-banner > button {
|
.banner > button {
|
||||||
--button-background: hsla(0, 0%, 50%, 0.3);
|
--button-background: hsla(0, 0%, 50%, 0.3);
|
||||||
--button-background-hover: hsla(0, 0%, 30%, 0.3);
|
--button-background-hover: hsla(0, 0%, 30%, 0.3);
|
||||||
--button-background-active: hsla(0, 0%, 10%, 0.3);
|
--button-background-active: hsla(0, 0%, 10%, 0.3);
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.banner--warn {
|
||||||
|
background-color: var(--red-60-a30);
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner::before {
|
||||||
|
content: "";
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
.banner--info::before {
|
||||||
|
background-image: url("../../assets/photon_info.svg");
|
||||||
|
}
|
||||||
|
.banner--warn::before {
|
||||||
|
background-image: url("../../assets/photon_warning.svg");
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.whitelist-banner {
|
.banner {
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.25);
|
border-bottom: 1px solid rgba(255, 255, 255, 0.25);
|
||||||
}
|
}
|
||||||
.whitelist-banner > button {
|
.banner > button {
|
||||||
--button-background: hsla(0, 0%, 50%, 0.3);
|
--button-background: hsla(0, 0%, 50%, 0.3);
|
||||||
--button-background-hover: hsla(0, 0%, 70%, 0.3);
|
--button-background-hover: hsla(0, 0%, 70%, 0.3);
|
||||||
--button-background-active: hsla(0, 0%, 90%, 0.3);
|
--button-background-active: hsla(0, 0%, 90%, 0.3);
|
||||||
|
|||||||
Reference in New Issue
Block a user