Protocol handler for deep linking in desktop app

This commit is contained in:
David Meza 2017-10-09 11:12:21 -05:00
parent fb9a005f39
commit 40892e0430
5 changed files with 52 additions and 9 deletions

View file

@ -20,6 +20,12 @@
]
}
],
"protocols": [
{
"name": "Mattermost",
"schemes": ["mattermost"]
}
],
"deb": {
"synopsis": "Mattermost"
},

View file

@ -254,8 +254,7 @@ const MainPage = createReactClass({
withTab={this.props.teams.length > 1}
useSpellChecker={this.props.useSpellChecker}
onSelectSpellCheckerLocale={this.props.onSelectSpellCheckerLocale}
src={team.url}
name={team.name}
team={team}
onTargetURLChange={self.handleTargetURLChange}
onUnreadCountChange={handleUnreadCountChange}
onNotificationClick={handleNotificationClick}

View file

@ -15,11 +15,10 @@ const preloadJS = `file://${remote.app.getAppPath()}/browser/webview/mattermost_
const MattermostView = createReactClass({
propTypes: {
name: PropTypes.string,
id: PropTypes.string,
onTargetURLChange: PropTypes.func,
onUnreadCountChange: PropTypes.func,
src: PropTypes.string,
team: PropTypes.object,
active: PropTypes.bool,
withTab: PropTypes.bool,
useSpellChecker: PropTypes.bool,
@ -44,8 +43,18 @@ const MattermostView = createReactClass({
var self = this;
var webview = findDOMNode(this.refs.webview);
ipcRenderer.on('protocol-deeplink', (event, lastUrl) => {
webview.executeJavaScript(
'history.pushState(null, null, "/' +
lastUrl.replace(lastUrl.match(/(?:[^/]*\/){3}/), '') + '");'
);
webview.executeJavaScript(
'dispatchEvent(new PopStateEvent("popstate", null));'
);
});
webview.addEventListener('did-fail-load', (e) => {
console.log(self.props.name, 'webview did-fail-load', e);
console.log(self.props.team.name, 'webview did-fail-load', e);
if (e.errorCode === -3) { // An operation was aborted (due to user action).
return;
}
@ -139,7 +148,7 @@ const MattermostView = createReactClass({
});
webview.addEventListener('console-message', (e) => {
const message = `[${this.props.name}] ${e.message}`;
const message = `[${this.props.team.name}] ${e.message}`;
switch (e.level) {
case 0:
console.log(message);
@ -223,6 +232,10 @@ const MattermostView = createReactClass({
if (!this.props.active) {
classNames.push('mattermostView-hidden');
}
const deeplinkingUrl = remote.getCurrentWindow().deeplinkingUrl;
const lastUrl = (deeplinkingUrl === null ? this.props.team.url : deeplinkingUrl);
return (
<div>
{ errorView }
@ -230,7 +243,7 @@ const MattermostView = createReactClass({
id={this.props.id}
className={classNames.join(' ')}
preload={preloadJS}
src={this.props.src}
src={lastUrl}
ref='webview'
/>
</div>);

View file

@ -44,6 +44,7 @@ const assetsDir = path.resolve(app.getAppPath(), 'assets');
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;
let spellChecker = null;
let deeplinkingUrl = null;
var argv = require('yargs').parse(process.argv.slice(1));
@ -148,7 +149,14 @@ const trayImages = (() => {
})();
// If there is already an instance, activate the window in the existing instace and quit this one
if (app.makeSingleInstance((/*commandLine, workingDirectory*/) => {
if (app.makeSingleInstance((commandLine/*, workingDirectory*/) => {
// Protocol handler for win32
// argv: An array of the second instances (command line / deep linked) arguments
if (process.platform === 'win32') {
// Keep only command line / deep linked arguments
deeplinkingUrl = commandLine.slice(1);
}
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (mainWindow.isMinimized()) {
@ -319,6 +327,15 @@ ipcMain.on('download-url', (event, URL) => {
});
});
app.setAsDefaultProtocolClient('Mattermost');
// Protocol handler for osx
app.on('open-url', function(event, url) {
event.preventDefault();
deeplinkingUrl = url.replace('Mattermost', 'https');
mainWindow.webContents.send('protocol-deeplink', deeplinkingUrl);
});
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', () => {
@ -331,9 +348,16 @@ app.on('ready', () => {
catch((err) => console.log('An error occurred: ', err));
}
// Protocol handler for win32
if (process.platform === 'win32') {
// Keep only command line / deep linked arguments
deeplinkingUrl = process.argv.slice(1);
}
mainWindow = createMainWindow(config, {
hideOnStartup,
linuxAppIcon: path.join(assetsDir, 'appicon.png')
linuxAppIcon: path.join(assetsDir, 'appicon.png'),
deeplinkingUrl
});
mainWindow.on('closed', () => {
// Dereference the window object, usually you would store windows

View file

@ -42,6 +42,7 @@ function createMainWindow(config, options) {
});
const mainWindow = new BrowserWindow(windowOptions);
mainWindow.deeplinkingUrl = options.deeplinkingUrl;
const indexURL = global.isDev ? 'http://localhost:8080/browser/index.html' : `file://${app.getAppPath()}/browser/index.html`;
mainWindow.loadURL(indexURL);