Merge branch 'release-4.1'
This commit is contained in:
commit
ab802ee9d0
92
CHANGELOG.md
92
CHANGELOG.md
|
@ -1,69 +1,85 @@
|
||||||
# Mattermost Desktop Application Changelog
|
# Mattermost Desktop Application Changelog
|
||||||
|
|
||||||
## UNDER DEVELOPMENT
|
## Release v4.1.0
|
||||||
|
|
||||||
The "UNDER DEVELOPMENT" section of the Mattermost Desktop changelog appears
|
Release date: May 16, 2018
|
||||||
in the product's `master` branch to note key changes committed to `master`
|
|
||||||
and are on their way to the next stable release.
|
|
||||||
When a stable release is pushed, "UNDER DEVELOPMENT" heading is removed
|
|
||||||
from the final changelog of the release.
|
|
||||||
|
|
||||||
Release date: TBD
|
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
#### All Platforms
|
#### All Platforms
|
||||||
- Added "Enable GPU hardware acceleration" option. It's disabled by default for stability.
|
- Improved stability and performance
|
||||||
[#734](https://github.com/mattermost/desktop/pull/734)
|
- Reduced memory usage by periodically clearing cache. [#746](https://github.com/mattermost/desktop/issues/710)
|
||||||
[#750](https://github.com/mattermost/desktop/pull/750)
|
- Fixed app crashing when a server tab was drag-and-dropped to the message view.
|
||||||
- Enabled Certificate Transparency verification in HTTPS.
|
[#667](https://github.com/mattermost/desktop/issues/667)
|
||||||
[#741](https://github.com/mattermost/desktop/pull/741)
|
- Added an option to disable GPU hardware acceleration in App Settings to improve stability in some systems. [#734](https://github.com/mattermost/desktop/pull/734)
|
||||||
- Clear memory cache at a certain interval in order to reduce memory usage.
|
- Fixed Windows crash issues during installation. [#728](https://github.com/mattermost/desktop/issues/728)
|
||||||
[#746](https://github.com/mattermost/desktop/pull/746)
|
- Fixed Mac and Linux crashing after toggling "Show Mattermost icon in menu bar" app setting.
|
||||||
- Hide hovering URL bar for internal links.
|
- Updated design for loading animation icon.
|
||||||
[#745](https://github.com/mattermost/desktop/pull/745)
|
|
||||||
- Truncate long server names in server tabs.
|
|
||||||
[#518](https://github.com/mattermost/desktop/issues/518)
|
|
||||||
- Updated Mattermost animation icon which is displayed when loading a page.
|
|
||||||
[#748](https://github.com/mattermost/desktop/issues/748)
|
[#748](https://github.com/mattermost/desktop/issues/748)
|
||||||
|
- Improved appearance of server tabs.
|
||||||
|
[#518](https://github.com/mattermost/desktop/issues/518)
|
||||||
|
[#717](https://github.com/mattermost/desktop/issues/717)
|
||||||
|
- Enabled [Certificate Transparency](https://www.certificate-transparency.org/what-is-ct) verification in HTTPS.
|
||||||
|
[#741](https://github.com/mattermost/desktop/pull/741)
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
- [Windows 7/8] Desktop notifications now respect the duration setting of Control Panel.
|
- [Windows 7/8] Desktop notifications now respect the duration setting set in the Control Panel.
|
||||||
[#601](https://github.com/mattermost/desktop/issues/601)
|
[#601](https://github.com/mattermost/desktop/issues/601)
|
||||||
|
|
||||||
### Architectural Changes
|
### Architectural Changes
|
||||||
- Major version upgrade of Electron to v1.7.x to v1.8.x. Electron is the underlying technology used to build the Desktop apps.
|
- Major version upgrade of Electron from v1.7.13 to v1.8.4. Electron is the underlying technology used to build the Desktop apps.
|
||||||
[#711](https://github.com/mattermost/desktop/pull/711)
|
[#711](https://github.com/mattermost/desktop/pull/711)
|
||||||
[#741](https://github.com/mattermost/desktop/pull/741)
|
[#741](https://github.com/mattermost/desktop/pull/741)
|
||||||
<!-- Todo: Complete version number when cutting release -->
|
- Mac download files now use Zip packages rather than tar.gz files. [#749](https://github.com/mattermost/desktop/pull/749)
|
||||||
- `require` and `module.exports` were replaced with `import` and `export`.
|
- ES6 `import` and `export` now replace the `require` and `modul.export` modules for better development.
|
||||||
[#756](https://github.com/mattermost/desktop/pull/756)
|
[#756](https://github.com/mattermost/desktop/pull/756)
|
||||||
|
- Storybook added to more easily develop React componets without executing the desktop app. [#757](https://github.com/mattermost/desktop/pull/757)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
#### All Platforms
|
#### All Platforms
|
||||||
- Fixed correct spellchecker language not used for non en-US locales on initial installation.
|
|
||||||
|
- Fixed an issue where an incorrect spellchecker language was used for non `en-US` locales on initial installation.
|
||||||
[#632](https://github.com/mattermost/desktop/issues/632)
|
[#632](https://github.com/mattermost/desktop/issues/632)
|
||||||
- Fixed an issue where error page appears when U2F device is used for multi-factor authentication through single sign-on.
|
- Fixed an issue where error page appeared when U2F device was used for multi-factor authentication through single sign-on.
|
||||||
[#708](https://github.com/mattermost/desktop/issues/708)
|
[#708](https://github.com/mattermost/desktop/issues/708)
|
||||||
- Fixed an issue where the main screen opens a blank page when a tab is dropped into the screen.
|
- Fixed an issue where right-clicking an image, then choosing "Save Image", did nothing.
|
||||||
[#667](https://github.com/mattermost/desktop/issues/667)
|
[#774](https://github.com/mattermost/desktop/issues/707)
|
||||||
- Fixed "Save Image" context menu not working.
|
- Fixed an issue that prevented typing in the form fields on the add server dialog when launched from the server tab bar.
|
||||||
[#707](https://github.com/mattermost/desktop/issues/707)
|
[#780](https://github.com/mattermost/desktop/issues/780)
|
||||||
|
- Fixed an issue that could cause an error message on the add new server dialog to be misleading.
|
||||||
|
[#438](https://github.com/mattermost/desktop/issues/438)
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
- Fixed `file://` protocol not working. But localhost URL will not continue to work.
|
- Fixed an issue where `file://` protocol was not working. Note that localhost URLs are not yet supported.
|
||||||
[#579](https://github.com/mattermost/desktop/issues/579)
|
[#579](https://github.com/mattermost/desktop/issues/579)
|
||||||
- Fixed an issue where Windows installer crashed in some cases.
|
|
||||||
[#728](https://github.com/mattermost/desktop/issues/728)
|
### Known Issues
|
||||||
|
|
||||||
|
#### All Platforms
|
||||||
|
- [Clicking on a video preview opens another Mattermost window in addition to downloading the file](https://github.com/mattermost/desktop/issues/792).
|
||||||
|
- [Insecure connection produces hundreds of log messages](https://github.com/mattermost/desktop/issues/569).
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
- [App window doesn't save "floating" app position](https://github.com/mattermost/desktop/issues/617).
|
||||||
|
- [Windows 7] [Sometimes app tries to render a page inside the app instead of in a new browser tab when clicking links](https://github.com/mattermost/desktop/issues/369).
|
||||||
|
- [Windows 10] [Incorrect task name in Windows 10 startup list](https://github.com/mattermost/desktop/issues/559).
|
||||||
|
- [Mattermost UI sometimes bleeds over a file explorer](https://github.com/mattermost/desktop/issues/753).
|
||||||
|
- [When auto-starting the desktop app, the application window is included in Windows tab list](https://github.com/mattermost/desktop/issues/738).
|
||||||
|
|
||||||
#### Mac
|
#### Mac
|
||||||
- Fixed an issue where app crashed after toggling "Show Mattermost icon in menu bar" setting.
|
- The application crashes when a file upload dialog is canceled without closing Quick Look.
|
||||||
[#706](https://github.com/mattermost/desktop/issues/706)
|
- [When the app auto-starts, app page opens on screen instead of being minimized to Dock](https://github.com/mattermost/desktop/issues/583).
|
||||||
|
|
||||||
#### Linux
|
#### Linux (Beta)
|
||||||
- Fixed an issue where app crashed after toggling "Show icon in the notification area" setting.
|
- [Ubuntu - 64 bit] [Right clicking taskbar icon and choosing **Quit** only minimizes the app](https://github.com/mattermost/desktop/issues/90#issuecomment-233712183)
|
||||||
[#706](https://github.com/mattermost/desktop/issues/706)
|
- [Ubuntu - 64 bit] [Direct message notification sometimes comes as a streak of line instead of a pop up](https://github.com/mattermost/platform/issues/3589)
|
||||||
|
|
||||||
|
### Contributors
|
||||||
|
|
||||||
|
Many thanks to all our contributors. In alphabetical order:
|
||||||
|
|
||||||
|
- [Autre31415](https://github.com/Autre31415), [dmeza](https://github.com/dmeza), [hmhealey](https://github.com/hmhealey), [jasonblais](https://github.com/jasonblais), [kethinov](https://github.com/kethinov), [lieut-data](https://github.com/lieut-data), [lip-d](https://github.com/lip-d), [mkraft](https://github.com/mkraft), [yuya-oc](https://github.com/yuya-oc)
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 93 KiB |
Binary file not shown.
Before Width: | Height: | Size: 327 KiB After Width: | Height: | Size: 197 KiB |
|
@ -317,7 +317,6 @@ const MainPage = createReactClass({
|
||||||
authServerURL = `${tmpURL.protocol}//${tmpURL.host}`;
|
authServerURL = `${tmpURL.protocol}//${tmpURL.host}`;
|
||||||
authInfo = this.state.loginQueue[0].authInfo;
|
authInfo = this.state.loginQueue[0].authInfo;
|
||||||
}
|
}
|
||||||
var currentTeamURL = this.props.teams[this.state.key].url;
|
|
||||||
var modal = (
|
var modal = (
|
||||||
<NewTeamModal
|
<NewTeamModal
|
||||||
show={this.state.showNewTeamModal}
|
show={this.state.showNewTeamModal}
|
||||||
|
@ -365,7 +364,7 @@ const MainPage = createReactClass({
|
||||||
{ viewsRow }
|
{ viewsRow }
|
||||||
</Grid>
|
</Grid>
|
||||||
<TransitionGroup>
|
<TransitionGroup>
|
||||||
{ (this.state.targetURL === '' || this.state.targetURL.startsWith(currentTeamURL)) ?
|
{ (this.state.targetURL === '') ?
|
||||||
null :
|
null :
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
classNames='hovering'
|
classNames='hovering'
|
||||||
|
|
|
@ -227,9 +227,10 @@ const MattermostView = createReactClass({
|
||||||
|
|
||||||
focusOnWebView() {
|
focusOnWebView() {
|
||||||
const webview = findDOMNode(this.refs.webview);
|
const webview = findDOMNode(this.refs.webview);
|
||||||
if (!webview.getWebContents().isFocused()) {
|
const webContents = webview.getWebContents(); // webContents might not be created yet.
|
||||||
|
if (webContents && !webContents.isFocused()) {
|
||||||
webview.focus();
|
webview.focus();
|
||||||
webview.getWebContents().focus();
|
webContents.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,17 @@ export default class NewTeamModal extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
getError() {
|
getError() {
|
||||||
return this.getTeamNameValidationError() || this.getTeamUrlValidationError();
|
const nameError = this.getTeamNameValidationError();
|
||||||
|
const urlError = this.getTeamUrlValidationError();
|
||||||
|
|
||||||
|
if (nameError && urlError) {
|
||||||
|
return 'Name and URL are required.';
|
||||||
|
} else if (nameError) {
|
||||||
|
return nameError;
|
||||||
|
} else if (urlError) {
|
||||||
|
return urlError;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
validateForm() {
|
validateForm() {
|
||||||
|
@ -148,6 +158,9 @@ export default class NewTeamModal extends React.Component {
|
||||||
value={this.state.teamName}
|
value={this.state.teamName}
|
||||||
placeholder='Server Name'
|
placeholder='Server Name'
|
||||||
onChange={this.handleTeamNameChange.bind(this)}
|
onChange={this.handleTeamNameChange.bind(this)}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<FormControl.Feedback/>
|
<FormControl.Feedback/>
|
||||||
<HelpBlock>{'The name of the server displayed on your desktop app tab bar.'}</HelpBlock>
|
<HelpBlock>{'The name of the server displayed on your desktop app tab bar.'}</HelpBlock>
|
||||||
|
@ -163,6 +176,9 @@ export default class NewTeamModal extends React.Component {
|
||||||
value={this.state.teamUrl}
|
value={this.state.teamUrl}
|
||||||
placeholder='https://example.com'
|
placeholder='https://example.com'
|
||||||
onChange={this.handleTeamUrlChange.bind(this)}
|
onChange={this.handleTeamUrlChange.bind(this)}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<FormControl.Feedback/>
|
<FormControl.Feedback/>
|
||||||
<HelpBlock className='NewTeamModal-noBottomSpace'>{'The URL of your Mattermost server. Must start with http:// or https://.'}</HelpBlock>
|
<HelpBlock className='NewTeamModal-noBottomSpace'>{'The URL of your Mattermost server. Must start with http:// or https://.'}</HelpBlock>
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.TabBar>li.teamTabItem:not(.active)>a:hover {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
.TabBar .TabBar-addServerButton>a {
|
.TabBar .TabBar-addServerButton>a {
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
@ -30,6 +36,7 @@
|
||||||
color: #333;
|
color: #333;
|
||||||
background-color: #e6e6e6;
|
background-color: #e6e6e6;
|
||||||
border-color: #adadad;
|
border-color: #adadad;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.TabBar .TabBar-badge {
|
.TabBar .TabBar-badge {
|
||||||
|
|
|
@ -15,7 +15,7 @@ const defaultPreferences = {
|
||||||
},
|
},
|
||||||
showUnreadBadge: true,
|
showUnreadBadge: true,
|
||||||
useSpellChecker: true,
|
useSpellChecker: true,
|
||||||
enableHardwareAcceleration: false,
|
enableHardwareAcceleration: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defaultPreferences;
|
export default defaultPreferences;
|
||||||
|
|
|
@ -46,6 +46,7 @@ import allowProtocolDialog from './main/allowProtocolDialog';
|
||||||
import PermissionManager from './main/PermissionManager';
|
import PermissionManager from './main/PermissionManager';
|
||||||
import permissionRequestHandler from './main/permissionRequestHandler';
|
import permissionRequestHandler from './main/permissionRequestHandler';
|
||||||
import AppStateManager from './main/AppStateManager';
|
import AppStateManager from './main/AppStateManager';
|
||||||
|
import initCookieManager from './main/cookieManager';
|
||||||
|
|
||||||
import SpellChecker from './main/SpellChecker';
|
import SpellChecker from './main/SpellChecker';
|
||||||
|
|
||||||
|
@ -423,6 +424,8 @@ app.on('ready', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initCookieManager(session.defaultSession);
|
||||||
|
|
||||||
mainWindow = createMainWindow(config, {
|
mainWindow = createMainWindow(config, {
|
||||||
hideOnStartup,
|
hideOnStartup,
|
||||||
linuxAppIcon: path.join(assetsDir, 'appicon.png'),
|
linuxAppIcon: path.join(assetsDir, 'appicon.png'),
|
||||||
|
|
22
src/main/cookieManager.js
Normal file
22
src/main/cookieManager.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import {app} from 'electron';
|
||||||
|
|
||||||
|
function flushCookiesStore(session) {
|
||||||
|
session.cookies.flushStore((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function initCookieManager(session) {
|
||||||
|
// Somehow cookies are not immediately saved to disk.
|
||||||
|
// So manually flush cookie store to disk on closing the app.
|
||||||
|
// https://github.com/electron/electron/issues/8416
|
||||||
|
app.on('before-quit', () => {
|
||||||
|
flushCookiesStore(session);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('browser-window-blur', () => {
|
||||||
|
flushCookiesStore(session);
|
||||||
|
});
|
||||||
|
}
|
|
@ -37,7 +37,14 @@ export default function permissionRequestHandler(mainWindow, permissionManager)
|
||||||
dequeueRequests(requestQueue, permissionManager, origin, permission, status);
|
dequeueRequests(requestQueue, permissionManager, origin, permission, status);
|
||||||
});
|
});
|
||||||
return (webContents, permission, callback) => {
|
return (webContents, permission, callback) => {
|
||||||
const targetURL = new URL(webContents.getURL());
|
let targetURL;
|
||||||
|
try {
|
||||||
|
targetURL = new URL(webContents.getURL());
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
callback(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (permissionManager.isDenied(targetURL.origin, permission)) {
|
if (permissionManager.isDenied(targetURL.origin, permission)) {
|
||||||
callback(false);
|
callback(false);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -289,19 +289,19 @@ describe('browser/settings.html', function desc() {
|
||||||
loadSettingsPage().
|
loadSettingsPage().
|
||||||
waitForExist(ID_INPUT_ENABLE_HARDWARE_ACCELERATION, 5000);
|
waitForExist(ID_INPUT_ENABLE_HARDWARE_ACCELERATION, 5000);
|
||||||
const selected = await this.app.client.isSelected(ID_INPUT_ENABLE_HARDWARE_ACCELERATION);
|
const selected = await this.app.client.isSelected(ID_INPUT_ENABLE_HARDWARE_ACCELERATION);
|
||||||
selected.should.equal(false); // default is false
|
selected.should.equal(true); // default is true
|
||||||
|
|
||||||
await this.app.client.click(ID_INPUT_ENABLE_HARDWARE_ACCELERATION).
|
await this.app.client.click(ID_INPUT_ENABLE_HARDWARE_ACCELERATION).
|
||||||
waitForVisible('#appOptionsSaveIndicator', 5000).
|
waitForVisible('#appOptionsSaveIndicator', 5000).
|
||||||
waitForVisible('#appOptionsSaveIndicator', 5000, true); // at least 2500 ms to disappear
|
waitForVisible('#appOptionsSaveIndicator', 5000, true); // at least 2500 ms to disappear
|
||||||
const config0 = JSON.parse(fs.readFileSync(env.configFilePath, 'utf-8'));
|
const config0 = JSON.parse(fs.readFileSync(env.configFilePath, 'utf-8'));
|
||||||
config0.enableHardwareAcceleration.should.equal(true);
|
config0.enableHardwareAcceleration.should.equal(false);
|
||||||
|
|
||||||
await this.app.client.click(ID_INPUT_ENABLE_HARDWARE_ACCELERATION).
|
await this.app.client.click(ID_INPUT_ENABLE_HARDWARE_ACCELERATION).
|
||||||
waitForVisible('#appOptionsSaveIndicator', 5000).
|
waitForVisible('#appOptionsSaveIndicator', 5000).
|
||||||
waitForVisible('#appOptionsSaveIndicator', 5000, true); // at least 2500 ms to disappear
|
waitForVisible('#appOptionsSaveIndicator', 5000, true); // at least 2500 ms to disappear
|
||||||
const config1 = JSON.parse(fs.readFileSync(env.configFilePath, 'utf-8'));
|
const config1 = JSON.parse(fs.readFileSync(env.configFilePath, 'utf-8'));
|
||||||
config1.enableHardwareAcceleration.should.equal(false);
|
config1.enableHardwareAcceleration.should.equal(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue