From c24c6412c08bb4401ba9f5806f28fbeac5376312 Mon Sep 17 00:00:00 2001 From: hensm Date: Tue, 11 Dec 2018 23:11:01 +0000 Subject: [PATCH] Add bridge debug info to options page --- app/src/main.js | 4 +- ext/src/_locales/en/messages.json | 28 +++ ext/src/lib/getBridgeInfo.js | 37 ++++ ext/src/main.js | 27 --- ext/src/options/index.jsx | 271 +++++++++++++++++++----------- ext/src/options/styles/index.css | 44 ++++- 6 files changed, 281 insertions(+), 130 deletions(-) create mode 100644 ext/src/lib/getBridgeInfo.js diff --git a/app/src/main.js b/app/src/main.js index 0e3252d..c3c269c 100755 --- a/app/src/main.js +++ b/app/src/main.js @@ -97,11 +97,11 @@ async function handleMessage (message) { switch (message.subject) { - case "bridge:initialize": { + case "bridge:getInfo": { const extensionVersion = message.data; return { - subject: "main:bridgeInitialized" + subject: "main:bridgeInfo" , data: __applicationVersion }; }; diff --git a/ext/src/_locales/en/messages.json b/ext/src/_locales/en/messages.json index eb20c60..477992c 100755 --- a/ext/src/_locales/en/messages.json +++ b/ext/src/_locales/en/messages.json @@ -18,6 +18,34 @@ } + , "optionsBridgeCategoryName": { + "message": "Bridge" + } + , "optionsBridgeCategoryDescription": { + "message": "Native bridge application." + } + , "optionsBridgeLoading": { + "message": "Loading bridge info..." + } + , "optionsBridgeMissing": { + "message": "Bridge application not found. Try downloading and installing the latest version." + } + , "optionsBridgeInfo": { + "message": "Bridge info:" + } + , "optionsBridgeStatusCompatible": { + "message": "STATUS: COMPATIBLE" + } + , "optionsBridgeStatusIncompatible": { + "message": "STATUS: INCOMPATIBLE" + } + , "optionsBridgeOlder": { + "message": "Bridge version older than expected, try updating bridge to the latest bridge version." + } + , "optionsBridgeNewer": { + "message": "Bridge version newer than expected, try updating extension to the latest bridge version." + } + , "optionsMediaCategoryName": { "message": "Media casting" } diff --git a/ext/src/lib/getBridgeInfo.js b/ext/src/lib/getBridgeInfo.js new file mode 100644 index 0000000..56b9043 --- /dev/null +++ b/ext/src/lib/getBridgeInfo.js @@ -0,0 +1,37 @@ +import semver from "semver"; + +export default async function getBridgeInfo () { + let applicationVersion; + try { + const response = await browser.runtime.sendNativeMessage( + APPLICATION_NAME + , { subject: "bridge:getInfo" + , data: EXTENSION_VERSION }); + + applicationVersion = response.data; + } catch (err) { + return null; + } + + /** + * Compare installed bridge version to the version the + * extension was built alongside and is known to be + * compatible with. + * + * TODO: Determine compatibility with semver and enforce/notify + * user. + */ + if (applicationVersion !== APPLICATION_VERSION) { + console.error(`Expecting ${APPLICATION_NAME} v${APPLICATION_VERSION}, found v${applicationVersion}.` + , semver.lt(applicationVersion, APPLICATION_VERSION) + ? "Try updating the native app to the latest version." + : "Try updating the extension to the latest version"); + } + + return { + version: applicationVersion + , isVersionCompatible: applicationVersion === APPLICATION_VERSION + , isVersionOlder: semver.lt(applicationVersion, APPLICATION_VERSION) + , isVersionNewer: semver.gt(applicationVersion, APPLICATION_VERSION) + }; +} diff --git a/ext/src/main.js b/ext/src/main.js index d515d8a..603de3d 100755 --- a/ext/src/main.js +++ b/ext/src/main.js @@ -340,12 +340,6 @@ function initBridge (tabId, frameId) { bridgeMap.set(tabId, port); } - // Start version handoff - port.postMessage({ - subject: "bridge:initialize" - , data: EXTENSION_VERSION - }); - port.onDisconnect.addListener(p => { if (p.error) { console.error(`${APPLICATION_NAME} disconnected:`, p.error.message); @@ -431,27 +425,6 @@ messageRouter.register("main", async (message, sender) => { break; }; - case "main:bridgeInitialized": { - const applicationVersion = message.data; - - /** - * Compare installed bridge version to the version the - * extension was built alongside and is known to be - * compatible with. - * - * TODO: Determine compatibility with semver and enforce/notify - * user. - */ - if (applicationVersion !== APPLICATION_VERSION) { - console.error(`Expecting ${APPLICATION_NAME} v${APPLICATION_VERSION}, found v${applicationVersion}.` - , semver.lt(applicationVersion, APPLICATION_VERSION) - ? "Try updating the native app to the latest version." - : "Try updating the extension to the latest version"); - } - - break; - }; - case "main:openPopup": { await openPopup(tabId); break; diff --git a/ext/src/options/index.jsx b/ext/src/options/index.jsx index df0721a..f246f4c 100644 --- a/ext/src/options/index.jsx +++ b/ext/src/options/index.jsx @@ -6,6 +6,8 @@ import ReactDOM from "react-dom"; import defaultOptions from "./defaultOptions"; import EditableList from "./EditableList"; +import getBridgeInfo from "../lib/getBridgeInfo"; + const _ = browser.i18n.getMessage; @@ -41,6 +43,8 @@ class App extends Component { this.state = { options: props.options + , bridgeInfo: null + , bridgeLoading: true , isFormValid: true }; @@ -54,6 +58,14 @@ class App extends Component { = this.getWhitelistItemPatternError.bind(this); } + async componentDidMount () { + const bridgeInfo = await getBridgeInfo(); + this.setState({ + bridgeInfo + , bridgeLoading: false + }); + } + /** * Set stored option values to current state */ @@ -126,140 +138,199 @@ class App extends Component { return _("optionsUserAgentWhitelistInvalidMatchPattern", info); } + async updateBridgeInfo () { + this.setState({ + bridgeLoading: true + }); + + const bridgeInfo = await getBridgeInfo(); + + this.setState({ + bridgeInfo + , bridgeLoading: false + }); + } + render () { return ( -
{ this.form = form; }} - onSubmit={ this.handleFormSubmit } - onChange={ this.handleFormChange }> -
- - { _("optionsMediaCategoryName") } - -

- { _("optionsMediaCategoryDescription") } -

+
+ { this.form = form; }} + onSubmit={ this.handleFormSubmit } + onChange={ this.handleFormChange }> - - -
+
- { _("optionsLocalMediaCategoryName") } + { _("optionsMediaCategoryName") }

- { _("optionsLocalMediaCategoryDescription") } + { _("optionsMediaCategoryDescription") }

+ +
+ + { _("optionsLocalMediaCategoryName") } + +

+ { _("optionsLocalMediaCategoryDescription") } +

+ + + + +
+
+ +
+ + { _("optionsMirroringCategoryName") } + +

+ { _("optionsMirroringCategoryDescription") } +

+ +
-
-
- - { _("optionsMirroringCategoryName") } - -

- { _("optionsMirroringCategoryDescription") } -

+
+ + { _("optionsUserAgentWhitelistCategoryName") } + +

+ { _("optionsUserAgentWhitelistCategoryDescription") } +

-
- -
- -
- - { _("optionsUserAgentWhitelistCategoryName") } - -

- { _("optionsUserAgentWhitelistCategoryDescription") } -

- - - -
-
- { _("optionsUserAgentWhitelistContent") } -
- +
+ +
-
+ -
- - +
+ { do { + if (this.state.bridgeLoading) { +
+ { _("optionsBridgeLoading") } + +
+ } else if (this.state.bridgeInfo) { + const bridgeInfo = this.state.bridgeInfo; + let debugInfo = + `${bridgeInfo.isVersionCompatible + ? _("optionsBridgeStatusCompatible") + : _("optionsBridgeStatusIncompatible")}\n\n` + + `${APPLICATION_NAME} v${bridgeInfo.version}\n` + + `Expected: ${APPLICATION_VERSION}\n` + + `Found: ${bridgeInfo.version}\n`; + + if (bridgeInfo.isVersionOlder) { + debugInfo += `\n${_("optionsBridgeOlder")}` + } + if (bridgeInfo.isVersionNewer) { + debugInfo += `\n${_("optionsBridgeNewer")}` + } + +
+ { _("optionsBridgeInfo") } +
+ +
+
+ } else { +
+ { _("optionsBridgeInfo") } +
+ { _("optionsBridgeMissing") } +
+
+ } + }}
- +
); } } -browser.storage.sync.get("options").then(({options}) => { +(async () => { + const { options } = await browser.storage.sync.get("options"); + ReactDOM.render( , document.querySelector("#root")); -}); +})() diff --git a/ext/src/options/styles/index.css b/ext/src/options/styles/index.css index 21dbca8..0577c03 100644 --- a/ext/src/options/styles/index.css +++ b/ext/src/options/styles/index.css @@ -17,6 +17,48 @@ } +.bridge { + margin-top: 20px; +} + +.bridge, +.bridge__loading { + display: flex; + flex-direction: column; +} + +.bridge__loading { + align-items: center; + align-self: center; + font-size: 1.25em; + font-weight: 300; + width: 30%; +} + +.bridge__loading progress { + margin-top: 5px; + width: 100%; +} + +.bridge__missing { + background-color: #d70022; + border-radius: 5px; + color: white; + padding: 5px; + margin-top: 5px; +} + +.bridge__found { + margin-top: 5px; +} + +.bridge__info { + height: 150px; + margin-inline-start: 5px; + width: 80%; +} + + .category { border: initial; display: grid; @@ -24,7 +66,7 @@ grid-column-gap: 20px; grid-row-gap: 5px; margin: initial; - padding: 15px 0; + padding: 10px 0; } .category:disabled {