URI handling (WIP) #116

Merged
alexliebowitz merged 5 commits from uri-handling into master 2017-05-08 16:11:19 +02:00
4 changed files with 65 additions and 5 deletions

View file

@ -30,6 +30,10 @@ let daemonStopRequested = false;
// this is set to true and app.quit() is called again to quit for real. // this is set to true and app.quit() is called again to quit for real.
let readyToQuit = false; 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 checkForNewVersion(callback) {
function formatRc(ver) { function formatRc(ver) {
// Adds dash if needed to make RC suffix semver friendly // Adds dash if needed to make RC suffix semver friendly
@ -110,9 +114,16 @@ function getPidsForProcessName(name) {
function createWindow () { function createWindow () {
win = new BrowserWindow({backgroundColor: '#155B4A', minWidth: 800, minHeight: 600 }) //$color-primary win = new BrowserWindow({backgroundColor: '#155B4A', minWidth: 800, minHeight: 600 }) //$color-primary
win.maximize() win.maximize()
// win.webContents.openDevTools(); // win.webContents.openDevTools();
win.loadURL(`file://${__dirname}/dist/index.html`) 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.webContents.on('did-finish-load', () => {
win.webContents.send('open-uri-requested', openUri);
});
}
win.on('closed', () => { win.on('closed', () => {
win = null win = null
}) })
@ -303,3 +314,17 @@ function upgrade(event, installerPath) {
} }
ipcMain.on('upgrade', upgrade); ipcMain.on('upgrade', upgrade);
if (process.platform == 'darwin') {
app.on('open-url', (event, 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
win.webContents.send('open-uri-requested', process.argv[2]);
}

View file

@ -32,11 +32,19 @@
}, },
"backgroundColor": "155B4A" "backgroundColor": "155B4A"
}, },
"protocols": [{
"name": "lbry",
"role": "Viewer",
"schemes": ["lbry"]
}],
"linux": { "linux": {
"target": "deb" "target": "deb"
}, },
"win": { "win": {
"target": "nsis" "target": "nsis"
},
"nsis": {
"perMachine": true
} }
}, },
"devDependencies": { "devDependencies": {

View file

@ -88,13 +88,22 @@ var App = React.createClass({
downloadComplete: false, downloadComplete: false,
}); });
}, },
componentWillMount: function() { 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); window.addEventListener("popstate", this.onHistoryPop);
document.addEventListener('unhandledError', (event) => { document.addEventListener('unhandledError', (event) => {
this.alertError(event.detail); this.alertError(event.detail);
}); });
ipcRenderer.on('open-uri-requested', (event, uri) => {
this.showUri(uri);
});
//open links in external browser and skip full redraw on changing page //open links in external browser and skip full redraw on changing page
document.addEventListener('click', (event) => { document.addEventListener('click', (event) => {
var target = event.target; var target = event.target;
@ -136,6 +145,11 @@ var App = React.createClass({
componentDidMount: function() { componentDidMount: function() {
this._isMounted = true; 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() { componentWillUnmount: function() {
this._isMounted = false; this._isMounted = false;
window.removeEventListener("popstate", this.onHistoryPop); window.removeEventListener("popstate", this.onHistoryPop);
@ -152,13 +166,13 @@ var App = React.createClass({
pageArgs: term pageArgs: term
}); });
}, },
onSubmit: function(uri) { showUri: function(uri) {
this._storeHistoryOfNextRender = true; this._storeHistoryOfNextRender = true;
this.setState({ this.setState({
address: uri, address: uri,
appUrl: "?show=" + encodeURIComponent(uri), appUrl: "?show=" + encodeURIComponent(uri),
viewingPage: "show", viewingPage: "show",
pageArgs: uri pageArgs: uri,
}) })
}, },
handleUpgradeClicked: function() { handleUpgradeClicked: function() {
@ -275,7 +289,7 @@ var App = React.createClass({
this._fullScreenPages.includes(this.state.viewingPage) ? this._fullScreenPages.includes(this.state.viewingPage) ?
mainContent : mainContent :
<div id="window"> <div id="window">
<Header onSearch={this.onSearch} onSubmit={this.onSubmit} address={address} wunderBarIcon={wunderBarIcon} viewingPage={this.state.viewingPage} /> <Header onSearch={this.onSearch} onSubmit={this.showUri} address={address} wunderBarIcon={wunderBarIcon} viewingPage={this.state.viewingPage} />
<div id="main-content"> <div id="main-content">
{mainContent} {mainContent}
</div> </div>

View file

@ -8,7 +8,7 @@ import SplashScreen from './component/splash.js';
import SnackBar from './component/snack-bar.js'; import SnackBar from './component/snack-bar.js';
import {AuthOverlay} from './component/auth.js'; import {AuthOverlay} from './component/auth.js';
const {remote} = require('electron'); const {remote, ipcRenderer} = require('electron');
const contextMenu = remote.require('./menu/context-menu'); const contextMenu = remote.require('./menu/context-menu');
lbry.showMenuIfNeeded(); lbry.showMenuIfNeeded();
@ -19,6 +19,18 @@ window.addEventListener('contextmenu', (event) => {
event.preventDefault(); 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() { let init = function() {
window.lbry = lbry; window.lbry = lbry;
window.lighthouse = lighthouse; window.lighthouse = lighthouse;
@ -30,7 +42,8 @@ let init = function() {
function onDaemonReady() { function onDaemonReady() {
window.sessionStorage.setItem('loaded', 'y'); //once we've made it here once per session, we don't need to show splash again window.sessionStorage.setItem('loaded', 'y'); //once we've made it here once per session, we don't need to show splash again
ReactDOM.render(<div>{ lbryio.enabled ? <AuthOverlay/> : '' }<App /><SnackBar /></div>, canvas) ipcRenderer.removeListener('open-uri-requested', onOpenUriRequested); // <App /> will handle listening for URI requests once it's loaded
ReactDOM.render(<div>{ lbryio.enabled ? <AuthOverlay/> : '' }<App {... openUri ? {openUri: openUri} : {}} /><SnackBar /></div>, canvas)
} }
if (window.sessionStorage.getItem('loaded') == 'y') { if (window.sessionStorage.getItem('loaded') == 'y') {