From 758bb59ccb1d99e887436e69c84ed2787a35979e Mon Sep 17 00:00:00 2001 From: Alex Liebowitz Date: Fri, 5 May 2017 05:15:58 -0400 Subject: [PATCH 1/5] Add basics of URI handling for Mac and Windows --- app/main.js | 9 +++++++++ package.json | 8 ++++++++ ui/js/main.js | 6 +++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/main.js b/app/main.js index eb867a2d7..3dcb85968 100644 --- a/app/main.js +++ b/app/main.js @@ -303,3 +303,12 @@ function upgrade(event, installerPath) { } ipcMain.on('upgrade', upgrade); + +if (process.platform == 'darwin') { + app.on('open-url', (event, uri) => { + win.webContents.send('open-uri-requested', url); + }); +} else if (process.argv.length >= 3) { + // No open-url event on Win, but we can still handle URIs provided at launch time + win.webContents.send('open-uri-requested', process.argv[2]); +} diff --git a/package.json b/package.json index 45142bbaa..af8cc1393 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,19 @@ }, "backgroundColor": "155B4A" }, + "protocols": [{ + "name": "lbry", + "role": "Viewer", + "schemes": ["lbry"] + }], "linux": { "target": "deb" }, "win": { "target": "nsis" + }, + "nsis": { + "perMachine": true } }, "devDependencies": { diff --git a/ui/js/main.js b/ui/js/main.js index 610ca8594..5985dbf6a 100644 --- a/ui/js/main.js +++ b/ui/js/main.js @@ -8,7 +8,7 @@ import SplashScreen from './component/splash.js'; import SnackBar from './component/snack-bar.js'; import {AuthOverlay} from './component/auth.js'; -const {remote} = require('electron'); +const {remote, ipcRenderer} = require('electron'); const contextMenu = remote.require('./menu/context-menu'); lbry.showMenuIfNeeded(); @@ -19,6 +19,10 @@ window.addEventListener('contextmenu', (event) => { event.preventDefault(); }); +ipcRenderer.on('open-uri-requested', (event, uri) => { + window.location.href = `?show=${uri}`; +}); + let init = function() { window.lbry = lbry; window.lighthouse = lighthouse; -- 2.45.2 From 499fa1214f15aea8080e73b469b43f4baa91e3ab Mon Sep 17 00:00:00 2001 From: Alex Liebowitz Date: Mon, 8 May 2017 02:33:37 -0400 Subject: [PATCH 2/5] Fix variable name in open URI callback --- app/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main.js b/app/main.js index 3dcb85968..3a2f33bc2 100644 --- a/app/main.js +++ b/app/main.js @@ -306,7 +306,7 @@ ipcMain.on('upgrade', upgrade); if (process.platform == 'darwin') { app.on('open-url', (event, uri) => { - win.webContents.send('open-uri-requested', url); + win.webContents.send('open-uri-requested', uri); }); } else if (process.argv.length >= 3) { // No open-url event on Win, but we can still handle URIs provided at launch time -- 2.45.2 From 38ea41775b7b95dbb8b76979962e765d701a071f Mon Sep 17 00:00:00 2001 From: Alex Liebowitz Date: Mon, 8 May 2017 02:36:42 -0400 Subject: [PATCH 3/5] Avoid page reload when loading URIs passed in from other apps --- ui/js/app.js | 8 ++++++-- ui/js/main.js | 4 ---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/js/app.js b/ui/js/app.js index 85f8891a6..472be423c 100644 --- a/ui/js/app.js +++ b/ui/js/app.js @@ -95,6 +95,10 @@ var App = React.createClass({ this.alertError(event.detail); }); + ipcRenderer.on('open-uri-requested', (event, uri) => { + this.openUri(uri); + }); + //open links in external browser and skip full redraw on changing page document.addEventListener('click', (event) => { var target = event.target; @@ -152,7 +156,7 @@ var App = React.createClass({ pageArgs: term }); }, - onSubmit: function(uri) { + openUri: function(uri) { this._storeHistoryOfNextRender = true; this.setState({ address: uri, @@ -275,7 +279,7 @@ var App = React.createClass({ this._fullScreenPages.includes(this.state.viewingPage) ? mainContent :
-
+
{mainContent}
diff --git a/ui/js/main.js b/ui/js/main.js index 5985dbf6a..bfd9e8a50 100644 --- a/ui/js/main.js +++ b/ui/js/main.js @@ -19,10 +19,6 @@ window.addEventListener('contextmenu', (event) => { event.preventDefault(); }); -ipcRenderer.on('open-uri-requested', (event, uri) => { - window.location.href = `?show=${uri}`; -}); - let init = function() { window.lbry = lbry; window.lighthouse = lighthouse; -- 2.45.2 From ef4274012fc2a8d2d81f1665f311dbf2f9743922 Mon Sep 17 00:00:00 2001 From: Alex Liebowitz Date: Mon, 8 May 2017 05:04:11 -0400 Subject: [PATCH 4/5] Add better handling for URIs requested during load --- app/main.js | 17 ++++++++++++++++- ui/js/app.js | 18 ++++++++++++++---- ui/js/main.js | 15 ++++++++++++++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/app/main.js b/app/main.js index 3a2f33bc2..71fe2840a 100644 --- a/app/main.js +++ b/app/main.js @@ -30,6 +30,10 @@ let daemonStopRequested = false; // this is set to true and app.quit() is called again to quit for real. let readyToQuit = false; +// If we receive a URI to open from an external app but there's no window to +// send it to, it's cached in this variable. +let openUri = null; + function checkForNewVersion(callback) { function formatRc(ver) { // Adds dash if needed to make RC suffix semver friendly @@ -113,6 +117,12 @@ function createWindow () { win.maximize() // win.webContents.openDevTools(); win.loadURL(`file://${__dirname}/dist/index.html`) + if (openUri) { // We stored and received a URI that an external app requested before we had a window object + win.on('did-finish-load', () => { + win.webContents.send('open-uri-requested', openUri); + }); + } + win.on('closed', () => { win = null }) @@ -306,7 +316,12 @@ ipcMain.on('upgrade', upgrade); if (process.platform == 'darwin') { app.on('open-url', (event, uri) => { - win.webContents.send('open-uri-requested', uri); + if (!win) { + // Window not created yet, so store up requested URI for when it is + openUri = uri; + } else { + win.webContents.send('open-uri-requested', uri); + } }); } else if (process.argv.length >= 3) { // No open-url event on Win, but we can still handle URIs provided at launch time diff --git a/ui/js/app.js b/ui/js/app.js index 472be423c..ee7a65f17 100644 --- a/ui/js/app.js +++ b/ui/js/app.js @@ -88,7 +88,12 @@ var App = React.createClass({ downloadComplete: false, }); }, + componentWillMount: function() { + if ('openUri' in this.props) { // A URI was requested by an external app + this.showUri(this.props.openUri); + } + window.addEventListener("popstate", this.onHistoryPop); document.addEventListener('unhandledError', (event) => { @@ -96,7 +101,7 @@ var App = React.createClass({ }); ipcRenderer.on('open-uri-requested', (event, uri) => { - this.openUri(uri); + this.showUri(uri); }); //open links in external browser and skip full redraw on changing page @@ -140,6 +145,11 @@ var App = React.createClass({ componentDidMount: function() { this._isMounted = true; }, + componentWillReceiveProps: function(nextProps) { + if ('openUri' in nextProps && (!('openUri' in this.props) || nextProps.openUri != this.props.openUri)) { + this.showUri(nextProps.openUri); + } + }, componentWillUnmount: function() { this._isMounted = false; window.removeEventListener("popstate", this.onHistoryPop); @@ -156,13 +166,13 @@ var App = React.createClass({ pageArgs: term }); }, - openUri: function(uri) { + showUri: function(uri) { this._storeHistoryOfNextRender = true; this.setState({ address: uri, appUrl: "?show=" + encodeURIComponent(uri), viewingPage: "show", - pageArgs: uri + pageArgs: uri, }) }, handleUpgradeClicked: function() { @@ -279,7 +289,7 @@ var App = React.createClass({ this._fullScreenPages.includes(this.state.viewingPage) ? mainContent :
-
+
{mainContent}
diff --git a/ui/js/main.js b/ui/js/main.js index bfd9e8a50..ef63fc055 100644 --- a/ui/js/main.js +++ b/ui/js/main.js @@ -19,6 +19,18 @@ window.addEventListener('contextmenu', (event) => { event.preventDefault(); }); +let openUri = null; + +function onOpenUriRequested(event, uri) { + /** + * If an external app requests a URI while we're still on the splash screen, we store it to + * later pass into the App component. + */ + openUri = uri; +}; +ipcRenderer.on('open-uri-requested', onOpenUriRequested); + + let init = function() { window.lbry = lbry; window.lighthouse = lighthouse; @@ -30,7 +42,8 @@ let init = function() { function onDaemonReady() { window.sessionStorage.setItem('loaded', 'y'); //once we've made it here once per session, we don't need to show splash again - ReactDOM.render(
{ lbryio.enabled ? : '' }
, canvas) + ipcRenderer.removeListener('open-uri-requested', onOpenUriRequested); // will handle listening for URI requests once it's loaded + ReactDOM.render(
{ lbryio.enabled ? : '' }
, canvas) } if (window.sessionStorage.getItem('loaded') == 'y') { -- 2.45.2 From 2761ebbd924785775441f2408fb8d1fe42b361e2 Mon Sep 17 00:00:00 2001 From: Alex Liebowitz Date: Mon, 8 May 2017 05:22:38 -0400 Subject: [PATCH 5/5] Attach did-finish-load event to win.webContents instead of win --- app/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/main.js b/app/main.js index 71fe2840a..cac430513 100644 --- a/app/main.js +++ b/app/main.js @@ -114,11 +114,12 @@ function getPidsForProcessName(name) { function createWindow () { win = new BrowserWindow({backgroundColor: '#155B4A', minWidth: 800, minHeight: 600 }) //$color-primary + win.maximize() // win.webContents.openDevTools(); win.loadURL(`file://${__dirname}/dist/index.html`) if (openUri) { // We stored and received a URI that an external app requested before we had a window object - win.on('did-finish-load', () => { + win.webContents.on('did-finish-load', () => { win.webContents.send('open-uri-requested', openUri); }); } -- 2.45.2