Merge branch 'release-4.1'

This commit is contained in:
Yuya Ochiai 2018-05-17 00:39:58 +09:00
commit ab802ee9d0
12 changed files with 119 additions and 48 deletions

View file

@ -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

View file

@ -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'

View file

@ -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();
} }
}, },

View file

@ -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>

View file

@ -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 {

View file

@ -15,7 +15,7 @@ const defaultPreferences = {
}, },
showUnreadBadge: true, showUnreadBadge: true,
useSpellChecker: true, useSpellChecker: true,
enableHardwareAcceleration: false, enableHardwareAcceleration: true,
}; };
export default defaultPreferences; export default defaultPreferences;

View file

@ -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
View 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);
});
}

View file

@ -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;

View file

@ -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);
}); });
}); });
}); });