From 84d3c377b4c75ede01a990c0fab5606f70ce432c Mon Sep 17 00:00:00 2001 From: Carmine D'Amico Date: Sun, 5 Jun 2016 12:50:15 +0200 Subject: [PATCH 1/9] first implementation for flash notification and settings to configure these --- src/browser/settings.jsx | 50 +++++++++++++++++++++++++++++++++++++++- src/common/settings.js | 5 +++- src/main.js | 5 ++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/browser/settings.jsx b/src/browser/settings.jsx index 224d9601..a5efcd97 100644 --- a/src/browser/settings.jsx +++ b/src/browser/settings.jsx @@ -49,7 +49,10 @@ var SettingsPage = React.createClass({ showTrayIcon: this.state.showTrayIcon, trayIconTheme: this.state.trayIconTheme, disablewebsecurity: this.state.disablewebsecurity, - version: settings.version + version: settings.version, + notifications: { + flashWindow: this.state.notifications.flashWindow + } }; settings.writeFileSync(this.props.configFile, config); if (process.platform === 'win32' || process.platform === 'linux') { @@ -96,6 +99,13 @@ var SettingsPage = React.createClass({ }); } }, + handleFlashWindowSetting: function(item) { + this.setState({ + notifications: { + flashWindow: item.state + } + }); + }, render: function() { var buttonStyle = { @@ -136,6 +146,40 @@ var SettingsPage = React.createClass({ ) : null; + var notificationSettings = [ + { + label: 'Never', + state: 0 + }, + { + label: 'Only when idle (after 10 seconds)', + state: 1 + }, + { + label: 'Always', + state: 2 + } + ]; + + var that = this; + var notificationElements = notificationSettings.map(function(item) { + var boundClick = that.handleFlashWindowSetting.bind(that, item); + return ( + + ); + }); + + var notifications = ( + + +

Notifications

+ { notificationElements } + +
+ ) + return ( @@ -150,6 +194,10 @@ var SettingsPage = React.createClass({ { teams_row } { options_row } + { notifications } +
+
+
diff --git a/src/common/settings.js b/src/common/settings.js index d9561194..093dcf8f 100644 --- a/src/common/settings.js +++ b/src/common/settings.js @@ -26,7 +26,10 @@ var loadDefault = function(version) { showTrayIcon: false, trayIconTheme: '', disablewebsecurity: true, - version: 1 + version: 1, + notifications: { + flashWindow: 0 // 0 = flash never, 1 = only when idle (after 10 seconds), 2 = always + } }; } } diff --git a/src/main.js b/src/main.js index baa80e49..ef3a7792 100644 --- a/src/main.js +++ b/src/main.js @@ -189,6 +189,10 @@ app.on('ready', function() { title: arg.title, content: arg.options.body }); + + if (config.notifications.flashWindow == 2) { + mainWindow.flashFrame(true); + } }); // Set overlay icon from dataURL @@ -209,6 +213,7 @@ app.on('ready', function() { } else { trayIcon.setImage(trayImages.normal); + mainWindow.flashFrame(false); trayIcon.setToolTip(app.getName()); } }); From 73a11ea398d3c2f7e66ae895c6161d6a9a37c252 Mon Sep 17 00:00:00 2001 From: Carmine D'Amico Date: Tue, 7 Jun 2016 22:17:44 +0200 Subject: [PATCH 2/9] added todo for idle notification and add a text to explain notification config --- src/browser/settings.jsx | 22 +++++++++++----------- src/main.js | 3 ++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/browser/settings.jsx b/src/browser/settings.jsx index a5efcd97..1b7cddd3 100644 --- a/src/browser/settings.jsx +++ b/src/browser/settings.jsx @@ -151,10 +151,11 @@ var SettingsPage = React.createClass({ label: 'Never', state: 0 }, + /* ToDo: Idle isn't implemented yet { label: 'Only when idle (after 10 seconds)', state: 1 - }, + },*/ { label: 'Always', state: 2 @@ -165,19 +166,18 @@ var SettingsPage = React.createClass({ var notificationElements = notificationSettings.map(function(item) { var boundClick = that.handleFlashWindowSetting.bind(that, item); return ( - - ); + + ); }); var notifications = ( - - -

Notifications

- { notificationElements } - -
+ + +

Notifications

Configure, that the taskicon in the taskbar blinks when you were mentioned. + { notificationElements } + +
) return ( diff --git a/src/main.js b/src/main.js index ef3a7792..703a746a 100644 --- a/src/main.js +++ b/src/main.js @@ -190,6 +190,7 @@ app.on('ready', function() { content: arg.options.body }); + /* Todo: add idle here */ if (config.notifications.flashWindow == 2) { mainWindow.flashFrame(true); } @@ -213,8 +214,8 @@ app.on('ready', function() { } else { trayIcon.setImage(trayImages.normal); - mainWindow.flashFrame(false); trayIcon.setToolTip(app.getName()); + mainWindow.flashFrame(false); } }); } From 87da29dc32cc9c30ece15d0a0f7424f4a0578d03 Mon Sep 17 00:00:00 2001 From: Kolja Lampe Date: Sat, 11 Jun 2016 10:31:18 +0200 Subject: [PATCH 3/9] Change package entry for electron-builder. See https://github.com/mattermost/desktop/pull/138#discussion_r63242703 --- gulpfile.js | 2 +- package.json | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 16df5c77..a4f01f9b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -193,7 +193,7 @@ function makePackage(platform, arch, callback) { icon: 'resources/icon', "version-string": { CompanyName: packageJson.author.name, - LegalCopyright: 'Copyright (c) 2015 - 2016' + packageJson.author.name, + LegalCopyright: 'Copyright (c) 2015 - ' + new Date().getFullYear() + ' ' + packageJson.author.name, FileDescription: packageJson.description, OriginalFilename: packageJson.productName + '.exe', ProductVersion: packageJson.version, diff --git a/package.json b/package.json index 94394588..464c20f3 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "package": "gulp package", "package:windows": "gulp package:windows", "package:osx": "gulp package:osx", - "package:linux": "gulp build && build --platform linux --arch all -d deb", + "package:linux": "gulp build && build --platform linux --arch all", "package:all": "gulp package:all", "prettify": "gulp prettify", "installer": "node ./script/installer.js" @@ -34,7 +34,7 @@ "babel-preset-react": "^6.5.0", "chromedriver": "^2.20.0", "del": "^2.2.0", - "electron-builder": "3.20.0", + "electron-builder": "5.2.1", "electron-connect": "^0.3.7", "electron-packager": "^7.0.1", "electron-prebuilt": "0.37.8", @@ -63,7 +63,8 @@ "app-bundle-id": "com.mattermost.desktop", "app-category-type": "public.app-category.productivity", "linux": { - "synopsis": "Mattermost Desktop" + "synopsis": "Mattermost Desktop", + "target": "deb" } }, "directories": { From c40fd843571c5292dab3ac1d90ea22abdecc0ea7 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sun, 12 Jun 2016 23:26:32 +0900 Subject: [PATCH 4/9] Fix arch name for .deb packages in deploy script --- circle/make_draft.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/circle/make_draft.sh b/circle/make_draft.sh index a9a1fe2f..549bf369 100755 --- a/circle/make_draft.sh +++ b/circle/make_draft.sh @@ -52,5 +52,5 @@ deploy win64 zip deploy osx tar.gz deploy linux-ia32 tar.gz deploy linux-x64 tar.gz -upload mattermost-desktop-$RELEASE_TAG-linux-i386.deb release/mattermost-desktop-$RELEASE_TAG-i386.deb -upload mattermost-desktop-$RELEASE_TAG-linux-amd64.deb release/mattermost-desktop-$RELEASE_TAG-amd64.deb +upload mattermost-desktop-$RELEASE_TAG-linux-ia32.deb release/mattermost-desktop-$RELEASE_TAG-ia32.deb +upload mattermost-desktop-$RELEASE_TAG-linux-x64.deb release/mattermost-desktop-$RELEASE_TAG.deb From 447f6ec41d77e2855cf5940f0c5c19ca95b6acbf Mon Sep 17 00:00:00 2001 From: Kolja Lampe Date: Sat, 11 Jun 2016 02:17:18 +0200 Subject: [PATCH 5/9] Adds a setting to launch the app on system login --- src/browser/settings.jsx | 33 +++++++++++++++++++++++++++++++++ src/main.js | 16 +++++++++++++++- src/package.json | 1 + 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/browser/settings.jsx b/src/browser/settings.jsx index 224d9601..91cbbbc8 100644 --- a/src/browser/settings.jsx +++ b/src/browser/settings.jsx @@ -6,6 +6,7 @@ const settings = require('../common/settings'); const React = require('react'); const ReactDOM = require('react-dom'); const ReactBootstrap = require('react-bootstrap'); +var AutoLaunch = require('auto-launch'); const Grid = ReactBootstrap.Grid; const Row = ReactBootstrap.Row; @@ -16,6 +17,10 @@ const ListGroup = ReactBootstrap.ListGroup; const ListGroupItem = ReactBootstrap.ListGroupItem; const Glyphicon = ReactBootstrap.Glyphicon; +var appLauncher = new AutoLaunch({ + name: 'Mattermost' +}); + function backToIndex() { remote.getCurrentWindow().loadURL('file://' + __dirname + '/index.html'); } @@ -35,6 +40,16 @@ var SettingsPage = React.createClass({ return config; }, + componentDidMount: function() { + if (process.platform === 'win32' || process.platform === 'linux') { + var self = this; + appLauncher.isEnabled().then(function(enabled) { + self.setState({ + autostart: enabled + }); + }); + } + }, handleTeamsChange: function(teams) { this.setState({ teams: teams @@ -56,6 +71,15 @@ var SettingsPage = React.createClass({ var currentWindow = remote.getCurrentWindow(); currentWindow.setAutoHideMenuBar(config.hideMenuBar); currentWindow.setMenuBarVisibility(!config.hideMenuBar); + + var autostart = this.state.autostart; + appLauncher.isEnabled().then(function(enabled) { + if (enabled && !autostart) { + appLauncher.disable(); + } else if (!enabled && autostart) { + appLauncher.enable(); + } + }); } if (typeof toIndex == 'undefined' || toIndex) { @@ -85,6 +109,11 @@ var SettingsPage = React.createClass({ trayIconTheme: this.refs.trayIconTheme.getValue() }); }, + handleChangeAutoStart: function() { + this.setState({ + autostart: this.refs.autostart.getChecked() + }); + }, handleShowTeamForm: function() { if (!this.state.showAddTeamForm) { this.setState({ @@ -127,6 +156,10 @@ var SettingsPage = React.createClass({ } options.push(); + //OSX has an option in the tray, to set the app to autostart, so we choose to not support this option for OSX + if (process.platform === 'win32' || process.platform === 'linux') { + options.push(); + } var options_row = (options.length > 0) ? ( diff --git a/src/main.js b/src/main.js index baa80e49..ecdcfa99 100644 --- a/src/main.js +++ b/src/main.js @@ -3,7 +3,21 @@ const electron = require('electron'); const app = electron.app; // Module to control application life. -if (require('electron-squirrel-startup')) app.quit(); +if (process.platform === 'win32') { + var cmd = process.argv[1]; + if (cmd === '--squirrel-uninstall') { + var AutoLaunch = require('auto-launch'); + var appLauncher = new AutoLaunch({ + name: 'Mattermost' + }); + appLauncher.isEnabled().then(function(enabled) { + if (enabled) + appLauncher.disable(); + }); + } +} + +require('electron-squirrel-startup'); const BrowserWindow = electron.BrowserWindow; // Module to create native browser window. const Menu = electron.Menu; diff --git a/src/package.json b/src/package.json index bd17e5d6..6a1e2f77 100644 --- a/src/package.json +++ b/src/package.json @@ -13,6 +13,7 @@ "electron-connect": "^0.3.3" }, "dependencies": { + "auto-launch": "^2.0.1", "bootstrap": "^3.3.6", "os-locale": "^1.4.0", "react": "^15.0.1", From 3698b194952da5173e05405e9ccfa2ccfcc6a86b Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Thu, 16 Jun 2016 21:08:40 +0900 Subject: [PATCH 6/9] Update docs --- CHANGELOG.md | 2 ++ docs/setup.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4bf02bf..f8d8252c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,11 @@ #### Windows - Added the tooltip for the tray icon in order to show count of unread channels/mantions. +- Added the option to launch the application on login. #### Linux - Added the option to show the icon on menu bar. (requires libappindicator1 on Ubuntu) +- Added the option to launch the application on login. ## Release v1.2.1 (Beta) diff --git a/docs/setup.md b/docs/setup.md index 324e5440..04e54f43 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -122,6 +122,8 @@ The Settings Page is available from the **File** menu under **Settings** (Click - **Allow insecure contents** - If your team is hosted on `https://`, images with `http://` are not rendered by default. This option allows such images to be rendered, but please be careful for security. + - **Start app on login** (Windows, Linux) + - This option starts the application when you login. ## Menu Bar From 4b11504b81d2cf75cb4b65bf5570953be472eae2 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Thu, 16 Jun 2016 21:31:03 +0900 Subject: [PATCH 7/9] Update issue templates --- ISSUE_TEMPLATE.md | 10 +++++++++- PULL_REQUEST_TEMPLATE.md | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 PULL_REQUEST_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 60007948..36e543c3 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1 +1,9 @@ -- [ ] Did you read `CONTRIBUTING.md`? +First of all, please read `CONTRIBUTING.md`. + +--- + +When you have a trouble, please write below. +- Operationg system +- Mattermost desktop app version +- Mattermost server version +- How to reproduce the trouble diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..791d1f8f --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ +First of all, please read `CONTRIBUTING.md` + +--- + +- [ ] Complete [Mattermost Contributor Agreement](http://www.mattermost.org/mattermost-contributor-agreement/) +- [ ] Execute `npm run prettify` to format codes +- [ ] Write about environment which you tested + - Operating system From 722807a5cb3ce6dbc819e26bdf2289c35163e57d Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Thu, 16 Jun 2016 22:10:55 +0900 Subject: [PATCH 8/9] Refactor notification to simplify event handling --- src/browser/webview/mattermost.js | 52 +++++++++++-------------------- src/common/osVersion.js | 9 +++++- src/main.js | 24 ++++++++------ 3 files changed, 40 insertions(+), 45 deletions(-) diff --git a/src/browser/webview/mattermost.js b/src/browser/webview/mattermost.js index ba9500c4..353efce5 100644 --- a/src/browser/webview/mattermost.js +++ b/src/browser/webview/mattermost.js @@ -97,39 +97,23 @@ function isElementVisible(elem) { return elem.offsetHeight !== 0; } -// On Windows 8.1 and Windows 8, a shortcut with a Application User Model ID must be installed to the Start screen. -// In current version, use tray balloon for notification -function isLowerThanOrEqualWindows8_1() { - if (process.platform != 'win32') { - return false; - } - var osVersion = require('../../common/osVersion'); - return (osVersion.major <= 6 && osVersion.minor <= 3); -}; - -if (process.platform === 'win32' && isLowerThanOrEqualWindows8_1()) { - // Show balloon when notified. - notification.override({ - notification: function(title, options) { - ipc.send('notified', { - title: title, - options: options - }); - } - }); -} -else { +notification.override({ + // Send a notification event to the main process. + notification: function(title, options) { + ipc.send('notified', { + title: title, + options: options + }); + }, // Show window even if it is hidden/minimized when notification is clicked. - notification.override({ - onclick: function() { - if (process.platform === 'win32') { - // show() breaks Aero Snap state. - electron.remote.getCurrentWindow().focus(); - } - else { - electron.remote.getCurrentWindow().show(); - } - ipc.sendToHost('onNotificationClick'); + onclick: function() { + if (process.platform === 'win32') { + // show() breaks Aero Snap state. + electron.remote.getCurrentWindow().focus(); } - }); -} + else { + electron.remote.getCurrentWindow().show(); + } + ipc.sendToHost('onNotificationClick'); + } +}); diff --git a/src/common/osVersion.js b/src/common/osVersion.js index 8b320fbb..5be0c495 100644 --- a/src/common/osVersion.js +++ b/src/common/osVersion.js @@ -3,5 +3,12 @@ var release_split = os.release().split('.'); module.exports = { major: parseInt(release_split[0]), - minor: parseInt(release_split[1]) + minor: parseInt(release_split[1]), + isLowerThanOrEqualWindows8_1: function() { + if (process.platform != 'win32') { + return false; + } + // consider Windows 7 and later. + return (this.major <= 6 && this.minor <= 3); + } }; diff --git a/src/main.js b/src/main.js index 703a746a..11de4d01 100644 --- a/src/main.js +++ b/src/main.js @@ -14,6 +14,7 @@ const fs = require('fs'); const path = require('path'); var settings = require('./common/settings'); +const osVersion = require('./common/osVersion'); var certificateStore = require('./main/certificateStore').load(path.resolve(app.getPath('userData'), 'certificate.json')); var appMenu = require('./main/menus/app'); const allowProtocolDialog = require('./main/allowProtocolDialog'); @@ -184,15 +185,19 @@ app.on('ready', function() { mainWindow.focus(); }); ipc.on('notified', function(event, arg) { - trayIcon.displayBalloon({ - icon: path.resolve(__dirname, 'resources/appicon.png'), - title: arg.title, - content: arg.options.body - }); - - /* Todo: add idle here */ - if (config.notifications.flashWindow == 2) { - mainWindow.flashFrame(true); + if (process.platform === 'win32') { + if (config.notifications.flashWindow === 2) { + mainWindow.flashFrame(true); + } + // On Windows 8.1 and Windows 8, a shortcut with a Application User Model ID must be installed to the Start screen. + // In current version, use tray balloon for notification + if (osVersion.isLowerThanOrEqualWindows8_1()) { + trayIcon.displayBalloon({ + icon: path.resolve(__dirname, 'resources/appicon.png'), + title: arg.title, + content: arg.options.body + }); + } } }); @@ -215,7 +220,6 @@ app.on('ready', function() { else { trayIcon.setImage(trayImages.normal); trayIcon.setToolTip(app.getName()); - mainWindow.flashFrame(false); } }); } From 2b7dc1190e942f1ce2d37101824ae5b9cef4c440 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Fri, 17 Jun 2016 21:50:01 +0900 Subject: [PATCH 9/9] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8d8252c..1febe2be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ #### Windows - Added the tooltip for the tray icon in order to show count of unread channels/mantions. - Added the option to launch the application on login. +- Added the option to blink the taskbar icon when a new message has arrived. #### Linux - Added the option to show the icon on menu bar. (requires libappindicator1 on Ubuntu)