Merge branch 'master' into dev
This commit is contained in:
commit
517cc16835
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
- Added the tooltip text for the tray icon in order to show count of unread channels/mantions.
|
- Added the tooltip text 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.
|
||||||
- Added installers (experimemtal)
|
- Added installers (experimemtal)
|
||||||
|
|
||||||
#### OS X
|
#### OS X
|
||||||
|
@ -41,6 +43,7 @@
|
||||||
|
|
||||||
#### Linux
|
#### Linux
|
||||||
- Added the option to show the icon on menu bar. (requires libappindicator1 on Ubuntu)
|
- 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)
|
## Release v1.2.1 (Beta)
|
||||||
|
|
|
@ -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
|
||||||
|
|
8
PULL_REQUEST_TEMPLATE.md
Normal file
8
PULL_REQUEST_TEMPLATE.md
Normal file
|
@ -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
|
|
@ -52,7 +52,7 @@ deploy win64 zip
|
||||||
deploy osx tar.gz
|
deploy osx tar.gz
|
||||||
deploy linux-ia32 tar.gz
|
deploy linux-ia32 tar.gz
|
||||||
deploy linux-x64 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-ia32.deb release/mattermost-desktop-$RELEASE_TAG-ia32.deb
|
||||||
upload mattermost-desktop-$RELEASE_TAG-linux-amd64.deb release/mattermost-desktop-$RELEASE_TAG-amd64.deb
|
upload mattermost-desktop-$RELEASE_TAG-linux-x64.deb release/mattermost-desktop-$RELEASE_TAG.deb
|
||||||
upload mattermost-setup-$RELEASE_TAG-win32.exe release/windows-installer-ia32/mattermost-setup-ia32.exe
|
upload mattermost-setup-$RELEASE_TAG-win32.exe release/windows-installer-ia32/mattermost-setup-ia32.exe
|
||||||
upload mattermost-setup-$RELEASE_TAG-win64.exe release/windows-installer-x64/mattermost-setup-x64.exe
|
upload mattermost-setup-$RELEASE_TAG-win64.exe release/windows-installer-x64/mattermost-setup-x64.exe
|
||||||
|
|
|
@ -122,6 +122,8 @@ The Settings Page is available from the **File** menu under **Settings** (Click
|
||||||
- **Allow insecure contents**
|
- **Allow insecure contents**
|
||||||
- If your team is hosted on `https://`, images with `http://` are not rendered by default.
|
- 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.
|
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
|
## Menu Bar
|
||||||
|
|
|
@ -202,7 +202,7 @@ function makePackage(platform, arch, callback) {
|
||||||
icon: 'resources/icon',
|
icon: 'resources/icon',
|
||||||
"version-string": {
|
"version-string": {
|
||||||
CompanyName: distPackageAuthor,
|
CompanyName: distPackageAuthor,
|
||||||
LegalCopyright: `Copyright (c) 2015 - 2016 ${packageJson.author.name}`,
|
LegalCopyright: `Copyright (c) 2015 - ${new Date().getFullYear()} ${packageJson.author.name}`,
|
||||||
FileDescription: packageJson.description,
|
FileDescription: packageJson.description,
|
||||||
OriginalFilename: packageJson.productName + '.exe',
|
OriginalFilename: packageJson.productName + '.exe',
|
||||||
ProductVersion: packageJson.version,
|
ProductVersion: packageJson.version,
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
"package": "gulp package",
|
"package": "gulp package",
|
||||||
"package:windows": "gulp package:windows",
|
"package:windows": "gulp package:windows",
|
||||||
"package:osx": "gulp package:osx",
|
"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",
|
"package:all": "gulp package:all",
|
||||||
"prettify": "gulp prettify",
|
"prettify": "gulp prettify",
|
||||||
"installer": "node ./script/installer.js"
|
"installer": "node ./script/installer.js"
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"chai-as-promised": "^5.3.0",
|
"chai-as-promised": "^5.3.0",
|
||||||
"del": "^2.2.0",
|
"del": "^2.2.0",
|
||||||
"electron-builder": "3.20.0",
|
"electron-builder": "5.2.1",
|
||||||
"electron-connect": "^0.3.7",
|
"electron-connect": "^0.3.7",
|
||||||
"electron-packager": "^7.0.1",
|
"electron-packager": "^7.0.1",
|
||||||
"electron-prebuilt": "1.2.2",
|
"electron-prebuilt": "1.2.2",
|
||||||
|
@ -62,7 +62,8 @@
|
||||||
"app-bundle-id": "com.mattermost.desktop",
|
"app-bundle-id": "com.mattermost.desktop",
|
||||||
"app-category-type": "public.app-category.productivity",
|
"app-category-type": "public.app-category.productivity",
|
||||||
"linux": {
|
"linux": {
|
||||||
"synopsis": "Mattermost Desktop"
|
"synopsis": "Mattermost Desktop",
|
||||||
|
"target": "deb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"directories": {
|
"directories": {
|
||||||
|
|
|
@ -6,6 +6,7 @@ const settings = require('../common/settings');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const ReactDOM = require('react-dom');
|
const ReactDOM = require('react-dom');
|
||||||
const ReactBootstrap = require('react-bootstrap');
|
const ReactBootstrap = require('react-bootstrap');
|
||||||
|
var AutoLaunch = require('auto-launch');
|
||||||
|
|
||||||
const Grid = ReactBootstrap.Grid;
|
const Grid = ReactBootstrap.Grid;
|
||||||
const Row = ReactBootstrap.Row;
|
const Row = ReactBootstrap.Row;
|
||||||
|
@ -16,6 +17,10 @@ const ListGroup = ReactBootstrap.ListGroup;
|
||||||
const ListGroupItem = ReactBootstrap.ListGroupItem;
|
const ListGroupItem = ReactBootstrap.ListGroupItem;
|
||||||
const Glyphicon = ReactBootstrap.Glyphicon;
|
const Glyphicon = ReactBootstrap.Glyphicon;
|
||||||
|
|
||||||
|
var appLauncher = new AutoLaunch({
|
||||||
|
name: 'Mattermost'
|
||||||
|
});
|
||||||
|
|
||||||
function backToIndex() {
|
function backToIndex() {
|
||||||
remote.getCurrentWindow().loadURL('file://' + __dirname + '/index.html');
|
remote.getCurrentWindow().loadURL('file://' + __dirname + '/index.html');
|
||||||
}
|
}
|
||||||
|
@ -35,6 +40,16 @@ var SettingsPage = React.createClass({
|
||||||
|
|
||||||
return config;
|
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) {
|
handleTeamsChange: function(teams) {
|
||||||
this.setState({
|
this.setState({
|
||||||
teams: teams
|
teams: teams
|
||||||
|
@ -49,13 +64,25 @@ var SettingsPage = React.createClass({
|
||||||
showTrayIcon: this.state.showTrayIcon,
|
showTrayIcon: this.state.showTrayIcon,
|
||||||
trayIconTheme: this.state.trayIconTheme,
|
trayIconTheme: this.state.trayIconTheme,
|
||||||
disablewebsecurity: this.state.disablewebsecurity,
|
disablewebsecurity: this.state.disablewebsecurity,
|
||||||
version: settings.version
|
version: settings.version,
|
||||||
|
notifications: {
|
||||||
|
flashWindow: this.state.notifications.flashWindow
|
||||||
|
}
|
||||||
};
|
};
|
||||||
settings.writeFileSync(this.props.configFile, config);
|
settings.writeFileSync(this.props.configFile, config);
|
||||||
if (process.platform === 'win32' || process.platform === 'linux') {
|
if (process.platform === 'win32' || process.platform === 'linux') {
|
||||||
var currentWindow = remote.getCurrentWindow();
|
var currentWindow = remote.getCurrentWindow();
|
||||||
currentWindow.setAutoHideMenuBar(config.hideMenuBar);
|
currentWindow.setAutoHideMenuBar(config.hideMenuBar);
|
||||||
currentWindow.setMenuBarVisibility(!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();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcRenderer.send('update-menu', config);
|
ipcRenderer.send('update-menu', config);
|
||||||
|
@ -87,6 +114,11 @@ var SettingsPage = React.createClass({
|
||||||
trayIconTheme: this.refs.trayIconTheme.getValue()
|
trayIconTheme: this.refs.trayIconTheme.getValue()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleChangeAutoStart: function() {
|
||||||
|
this.setState({
|
||||||
|
autostart: this.refs.autostart.getChecked()
|
||||||
|
});
|
||||||
|
},
|
||||||
handleShowTeamForm: function() {
|
handleShowTeamForm: function() {
|
||||||
if (!this.state.showAddTeamForm) {
|
if (!this.state.showAddTeamForm) {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -98,6 +130,13 @@ var SettingsPage = React.createClass({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
handleFlashWindowSetting: function(item) {
|
||||||
|
this.setState({
|
||||||
|
notifications: {
|
||||||
|
flashWindow: item.state
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
var buttonStyle = {
|
var buttonStyle = {
|
||||||
|
@ -129,6 +168,10 @@ var SettingsPage = React.createClass({
|
||||||
}
|
}
|
||||||
options.push(<Input key="inputDisableWebSecurity" ref="disablewebsecurity" type="checkbox" label="Allow mixed content (Enabling allows both secure and insecure content, images and scripts to render and execute. Disabling allows only secure content.)"
|
options.push(<Input key="inputDisableWebSecurity" ref="disablewebsecurity" type="checkbox" label="Allow mixed content (Enabling allows both secure and insecure content, images and scripts to render and execute. Disabling allows only secure content.)"
|
||||||
checked={ this.state.disablewebsecurity } onChange={ this.handleChangeDisableWebSecurity } />);
|
checked={ this.state.disablewebsecurity } onChange={ this.handleChangeDisableWebSecurity } />);
|
||||||
|
//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(<Input key="inputAutoStart" ref="autostart" type="checkbox" label="Start app on login." checked={ this.state.autostart } onChange={ this.handleChangeAutoStart } />);
|
||||||
|
}
|
||||||
var options_row = (options.length > 0) ? (
|
var options_row = (options.length > 0) ? (
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={ 12 }>
|
<Col md={ 12 }>
|
||||||
|
@ -138,6 +181,40 @@ var SettingsPage = React.createClass({
|
||||||
</Row>
|
</Row>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
|
var notificationSettings = [
|
||||||
|
{
|
||||||
|
label: 'Never',
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
/* ToDo: Idle isn't implemented yet
|
||||||
|
{
|
||||||
|
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 (
|
||||||
|
<Input key={ "flashWindow" + item.state } name="handleFlashWindow" ref={ "flashWindow" + item.state } type="radio" label={ item.label } value={ item.state } onChange={ boundClick }
|
||||||
|
checked={ that.state.notifications.flashWindow == item.state ? "checked" : "" } />
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
var notifications = (
|
||||||
|
<Row>
|
||||||
|
<Col md={ 12 }>
|
||||||
|
<h2>Notifications</h2> Configure, that the taskicon in the taskbar blinks when you were mentioned.
|
||||||
|
{ notificationElements }
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid className="settingsPage">
|
<Grid className="settingsPage">
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -152,6 +229,10 @@ var SettingsPage = React.createClass({
|
||||||
</Row>
|
</Row>
|
||||||
{ teams_row }
|
{ teams_row }
|
||||||
{ options_row }
|
{ options_row }
|
||||||
|
{ notifications }
|
||||||
|
<div>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={ 12 }>
|
<Col md={ 12 }>
|
||||||
<Button id="btnCancel" onClick={ this.handleCancel }>Cancel</Button>
|
<Button id="btnCancel" onClick={ this.handleCancel }>Cancel</Button>
|
||||||
|
|
|
@ -97,30 +97,15 @@ function isElementVisible(elem) {
|
||||||
return elem.offsetHeight !== 0;
|
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.override({
|
||||||
|
// Send a notification event to the main process.
|
||||||
notification: function(title, options) {
|
notification: function(title, options) {
|
||||||
ipc.send('notified', {
|
ipc.send('notified', {
|
||||||
title: title,
|
title: title,
|
||||||
options: options
|
options: options
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Show window even if it is hidden/minimized when notification is clicked.
|
// Show window even if it is hidden/minimized when notification is clicked.
|
||||||
notification.override({
|
|
||||||
onclick: function() {
|
onclick: function() {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
// show() breaks Aero Snap state.
|
// show() breaks Aero Snap state.
|
||||||
|
@ -132,4 +117,3 @@ else {
|
||||||
ipc.sendToHost('onNotificationClick');
|
ipc.sendToHost('onNotificationClick');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -3,5 +3,12 @@ var release_split = os.release().split('.');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
major: parseInt(release_split[0]),
|
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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,10 @@ var loadDefault = function(version) {
|
||||||
showTrayIcon: false,
|
showTrayIcon: false,
|
||||||
trayIconTheme: '',
|
trayIconTheme: '',
|
||||||
disablewebsecurity: true,
|
disablewebsecurity: true,
|
||||||
version: 1
|
version: 1,
|
||||||
|
notifications: {
|
||||||
|
flashWindow: 0 // 0 = flash never, 1 = only when idle (after 10 seconds), 2 = always
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
26
src/main.js
26
src/main.js
|
@ -11,12 +11,27 @@ const {
|
||||||
systemPreferences
|
systemPreferences
|
||||||
} = require('electron');
|
} = require('electron');
|
||||||
|
|
||||||
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 fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
var settings = require('./common/settings');
|
var settings = require('./common/settings');
|
||||||
|
const osVersion = require('./common/osVersion');
|
||||||
var certificateStore = require('./main/certificateStore').load(path.resolve(app.getPath('userData'), 'certificate.json'));
|
var certificateStore = require('./main/certificateStore').load(path.resolve(app.getPath('userData'), 'certificate.json'));
|
||||||
var appMenu = require('./main/menus/app');
|
var appMenu = require('./main/menus/app');
|
||||||
const allowProtocolDialog = require('./main/allowProtocolDialog');
|
const allowProtocolDialog = require('./main/allowProtocolDialog');
|
||||||
|
@ -218,11 +233,20 @@ app.on('ready', function() {
|
||||||
mainWindow.focus();
|
mainWindow.focus();
|
||||||
});
|
});
|
||||||
ipcMain.on('notified', function(event, arg) {
|
ipcMain.on('notified', function(event, arg) {
|
||||||
|
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({
|
trayIcon.displayBalloon({
|
||||||
icon: path.resolve(__dirname, 'resources/appicon.png'),
|
icon: path.resolve(__dirname, 'resources/appicon.png'),
|
||||||
title: arg.title,
|
title: arg.title,
|
||||||
content: arg.options.body
|
content: arg.options.body
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set overlay icon from dataURL
|
// Set overlay icon from dataURL
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"electron-connect": "^0.3.3"
|
"electron-connect": "^0.3.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"auto-launch": "^2.0.1",
|
||||||
"bootstrap": "^3.3.6",
|
"bootstrap": "^3.3.6",
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"os-locale": "^1.4.0",
|
"os-locale": "^1.4.0",
|
||||||
|
|
Loading…
Reference in a new issue