Protocol handler for deep linking in desktop app
This commit is contained in:
parent
fb9a005f39
commit
40892e0430
|
@ -20,6 +20,12 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"protocols": [
|
||||
{
|
||||
"name": "Mattermost",
|
||||
"schemes": ["mattermost"]
|
||||
}
|
||||
],
|
||||
"deb": {
|
||||
"synopsis": "Mattermost"
|
||||
},
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>);
|
||||
|
|
28
src/main.js
28
src/main.js
|
@ -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 instance’s (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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue