Fix some issues caused by i18n addition (#2209)

* Fix some issues caused by i18n addition

* Couple more small changes
This commit is contained in:
Devin Binnie 2022-07-26 09:11:56 -04:00 committed by GitHub
parent 821112c038
commit e73e77daf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 183 additions and 175 deletions

View file

@ -5,10 +5,10 @@
const fs = require('fs');
const ps = require('ps-node');
const path = require('path');
const ps = require('ps-node');
const {_electron: electron} = require('playwright');
const chai = require('chai');
const {ipcRenderer} = require('electron');

View file

@ -2,25 +2,8 @@
// See LICENSE.txt for license information.
// Copyright (c) 2015-2016 Yuya Ochiai
import {screen} from 'electron';
import {DEVELOPMENT, PRODUCTION} from './constants';
function getDisplayBoundaries() {
const displays = screen.getAllDisplays();
return displays.map((display) => {
return {
maxX: display.workArea.x + display.workArea.width,
maxY: display.workArea.y + display.workArea.height,
minX: display.workArea.x,
minY: display.workArea.y,
maxWidth: display.workArea.width,
maxHeight: display.workArea.height,
};
});
}
function runMode() {
return process.env.NODE_ENV === PRODUCTION ? PRODUCTION : DEVELOPMENT;
}
@ -65,7 +48,6 @@ export function t(s: string) {
}
export default {
getDisplayBoundaries,
runMode,
shorten,
isVersionGreaterThanOrEqualTo,

View file

@ -3,7 +3,7 @@
import fs from 'fs-extra';
import {dialog} from 'electron';
import {dialog, screen} from 'electron';
import Config from 'common/config';
import JsonFileManager from 'common/JsonFileManager';
@ -34,6 +34,9 @@ jest.mock('electron', () => ({
showOpenDialogSync: jest.fn(),
showMessageBoxSync: jest.fn(),
},
screen: {
getAllDisplays: jest.fn(),
},
}));
jest.mock('common/config', () => ({
@ -42,7 +45,6 @@ jest.mock('common/config', () => ({
jest.mock('common/JsonFileManager');
jest.mock('common/utils/util', () => ({
isVersionGreaterThanOrEqualTo: jest.fn(),
getDisplayBoundaries: jest.fn(),
}));
jest.mock('main/autoUpdater', () => ({}));
@ -182,13 +184,13 @@ describe('main/app/utils', () => {
describe('resizeScreen', () => {
beforeEach(() => {
Utils.getDisplayBoundaries.mockReturnValue([{
minX: 400,
minY: 300,
maxX: 2320,
maxY: 1380,
width: 1920,
height: 1080,
screen.getAllDisplays.mockReturnValue([{
workArea: {
x: 400,
y: 300,
width: 1920,
height: 1080,
},
}]);
});
it('should keep the same position if it is within a display', () => {

View file

@ -5,7 +5,7 @@ import path from 'path';
import fs from 'fs-extra';
import {app, BrowserWindow, Menu, Rectangle, Session, session, dialog, nativeImage} from 'electron';
import {app, BrowserWindow, Menu, Rectangle, Session, session, dialog, nativeImage, screen} from 'electron';
import log, {LevelOption} from 'electron-log';
import {MigrationInfo, TeamWithTabs} from 'types/config';
@ -147,10 +147,25 @@ function isWithinDisplay(state: Rectangle, display: Boundaries) {
return !(midX > display.maxX || midY > display.maxY);
}
function getDisplayBoundaries() {
const displays = screen.getAllDisplays();
return displays.map((display) => {
return {
maxX: display.workArea.x + display.workArea.width,
maxY: display.workArea.y + display.workArea.height,
minX: display.workArea.x,
minY: display.workArea.y,
maxWidth: display.workArea.width,
maxHeight: display.workArea.height,
};
});
}
function getValidWindowPosition(state: Rectangle) {
// Check if the previous position is out of the viewable area
// (e.g. because the screen has been plugged off)
const boundaries = Utils.getDisplayBoundaries();
const boundaries = getDisplayBoundaries();
const display = boundaries.find((boundary) => {
return isWithinDisplay(state, boundary);
});

View file

@ -7,6 +7,8 @@ import {AuthenticationResponseDetails} from 'electron/renderer';
import {MODAL_CANCEL, MODAL_RESULT, RETRIEVE_MODAL_INFO} from 'common/communication';
import IntlProvider from 'renderer/intl_provider';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'renderer/css/modals.css';
@ -30,11 +32,13 @@ const getAuthInfo = () => {
const start = async () => {
ReactDOM.render(
<LoginModal
onLogin={handleLogin}
onCancel={handleLoginCancel}
getAuthInfo={getAuthInfo}
/>,
<IntlProvider>
<LoginModal
onLogin={handleLogin}
onCancel={handleLoginCancel}
getAuthInfo={getAuthInfo}
/>
</IntlProvider>,
document.getElementById('app'),
);
};

View file

@ -13,8 +13,6 @@ import {AuthenticationResponseDetails, AuthInfo} from 'electron/renderer';
import urlUtils from 'common/utils/url';
import {MODAL_INFO} from 'common/communication';
import IntlProvider from 'renderer/intl_provider';
type Props = {
onCancel: (request: AuthenticationResponseDetails) => void;
onLogin: (request: AuthenticationResponseDetails, username: string, password: string) => void;
@ -116,98 +114,96 @@ class LoginModal extends React.PureComponent<Props, State> {
const {intl} = this.props;
return (
<IntlProvider>
<Modal
show={Boolean(this.state.request && this.state.authInfo)}
>
<Modal.Header>
<Modal.Title>
<FormattedMessage
id='renderer.modals.login.loginModal.title'
defaultMessage='Authentication Required'
/>
</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>
{this.renderLoginModalMessage()}
</p>
<Form
onSubmit={this.handleSubmit}
>
<FormGroup>
<Col
as={FormLabel}
sm={2}
>
<FormattedMessage
id='renderer.modals.login.loginModal.username'
defaultMessage='User Name'
/>
</Col>
<Col sm={10}>
<FormControl
type='text'
placeholder={intl.formatMessage({id: 'renderer.modals.login.loginModal.username', defaultMessage: 'User Name'})}
onChange={this.setUsername}
value={this.state.username}
onClick={(e: React.MouseEvent<HTMLInputElement>) => {
e.stopPropagation();
}}
/>
</Col>
</FormGroup>
<FormGroup>
<Col
as={FormLabel}
sm={2}
>
<FormattedMessage
id='renderer.modals.login.loginModal.password'
defaultMessage='Password'
/>
</Col>
<Col sm={10}>
<FormControl
type='password'
placeholder={intl.formatMessage({id: 'renderer.modals.login.loginModal.password', defaultMessage: 'Password'})}
onChange={this.setPassword}
value={this.state.password}
onClick={(e: React.MouseEvent<HTMLInputElement>) => {
e.stopPropagation();
}}
/>
</Col>
</FormGroup>
<FormGroup>
<Col sm={12}>
<div className='pull-right'>
<Button
type='submit'
variant='primary'
>
<FormattedMessage
id='label.login'
defaultMessage='Login'
/>
</Button>
{ ' ' }
<Button
variant='link'
onClick={this.handleCancel}
>
<FormattedMessage
id='label.cancel'
defaultMessage='Cancel'
/>
</Button>
</div>
</Col>
</FormGroup>
</Form>
</Modal.Body>
</Modal>
</IntlProvider>
<Modal
show={Boolean(this.state.request && this.state.authInfo)}
>
<Modal.Header>
<Modal.Title>
<FormattedMessage
id='renderer.modals.login.loginModal.title'
defaultMessage='Authentication Required'
/>
</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>
{this.renderLoginModalMessage()}
</p>
<Form
onSubmit={this.handleSubmit}
>
<FormGroup>
<Col
as={FormLabel}
sm={2}
>
<FormattedMessage
id='renderer.modals.login.loginModal.username'
defaultMessage='User Name'
/>
</Col>
<Col sm={10}>
<FormControl
type='text'
placeholder={intl.formatMessage({id: 'renderer.modals.login.loginModal.username', defaultMessage: 'User Name'})}
onChange={this.setUsername}
value={this.state.username}
onClick={(e: React.MouseEvent<HTMLInputElement>) => {
e.stopPropagation();
}}
/>
</Col>
</FormGroup>
<FormGroup>
<Col
as={FormLabel}
sm={2}
>
<FormattedMessage
id='renderer.modals.login.loginModal.password'
defaultMessage='Password'
/>
</Col>
<Col sm={10}>
<FormControl
type='password'
placeholder={intl.formatMessage({id: 'renderer.modals.login.loginModal.password', defaultMessage: 'Password'})}
onChange={this.setPassword}
value={this.state.password}
onClick={(e: React.MouseEvent<HTMLInputElement>) => {
e.stopPropagation();
}}
/>
</Col>
</FormGroup>
<FormGroup>
<Col sm={12}>
<div className='pull-right'>
<Button
type='submit'
variant='primary'
>
<FormattedMessage
id='label.login'
defaultMessage='Login'
/>
</Button>
{ ' ' }
<Button
variant='link'
onClick={this.handleCancel}
>
<FormattedMessage
id='label.cancel'
defaultMessage='Cancel'
/>
</Button>
</div>
</Col>
</FormGroup>
</Form>
</Modal.Body>
</Modal>
);
}
}

View file

@ -6,6 +6,8 @@ import ReactDOM from 'react-dom';
import {MODAL_CANCEL, MODAL_RESULT, RETRIEVE_MODAL_INFO, MODAL_SEND_IPC_MESSAGE} from 'common/communication';
import IntlProvider from 'renderer/intl_provider';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'renderer/css/modals.css';
@ -33,12 +35,14 @@ const openExternalLink = (protocol: string, url: string) => {
const start = async () => {
ReactDOM.render(
<PermissionModal
getPermissionInfo={getPermissionInfo}
handleDeny={handleDeny}
handleGrant={handleGrant}
openExternalLink={openExternalLink}
/>,
<IntlProvider>
<PermissionModal
getPermissionInfo={getPermissionInfo}
handleDeny={handleDeny}
handleGrant={handleGrant}
openExternalLink={openExternalLink}
/>
</IntlProvider>,
document.getElementById('app'),
);
};

View file

@ -13,7 +13,6 @@ import urlUtil from 'common/utils/url';
import {t} from 'common/utils/util';
import {MODAL_INFO} from 'common/communication';
import {PERMISSION_DESCRIPTION} from 'common/permissions';
import IntlProvider from 'renderer/intl_provider';
type Props = {
handleDeny: React.MouseEventHandler<HTMLButtonElement>;
@ -57,11 +56,19 @@ class PermissionModal extends React.PureComponent<Props, State> {
}
getModalTitle() {
const permission = this.props.intl.formatMessage({id: `common.permissions.${PERMISSION_DESCRIPTION[this.state.permission!]}`});
if (!this.state.permission) {
return null;
}
const permission = this.props.intl.formatMessage({id: PERMISSION_DESCRIPTION[this.state.permission!]});
return this.props.intl.formatMessage({id: 'renderer.modals.permission.permissionModal.title', defaultMessage: '{permission} Required'}, {permission});
}
getModalBody() {
if (!this.state.permission) {
return null;
}
const {url, permission} = this.state;
const originDisplay = url ? urlUtil.getHost(url) : this.props.intl.formatMessage({id: 'renderer.modals.permission.permissionModal.unknownOrigin', defaultMessage: 'unknown origin'});
const originLink = url ? originDisplay : '';
@ -84,7 +91,7 @@ class PermissionModal extends React.PureComponent<Props, State> {
id='renderer.modals.permission.permissionModal.body'
defaultMessage={'A site that\'s not included in your Mattermost server configuration requires access for {permission}.'}
values={{
permission: this.props.intl.formatMessage({id: `common.permissions.${PERMISSION_DESCRIPTION[permission!]}`}),
permission: this.props.intl.formatMessage({id: PERMISSION_DESCRIPTION[permission!]}),
}}
/>
{}
@ -113,42 +120,40 @@ class PermissionModal extends React.PureComponent<Props, State> {
render() {
return (
<IntlProvider>
<Modal
bsClass='modal'
className='permission-modal'
show={Boolean(this.state.url && this.state.permission)}
id='requestPermissionModal'
enforceFocus={true}
onHide={() => {}}
>
<Modal.Header>
<Modal.Title>{this.getModalTitle()}</Modal.Title>
</Modal.Header>
<Modal.Body>
{this.getModalBody()}
</Modal.Body>
<Modal.Footer className={'remove-border'}>
<div>
<Button onClick={this.props.handleDeny}>
<FormattedMessage
id='label.cancel'
defaultMessage='Cancel'
/>
</Button>
<Button
variant='primary'
onClick={this.props.handleGrant}
>
<FormattedMessage
id='label.accept'
defaultMessage='Accept'
/>
</Button>
</div>
</Modal.Footer>
</Modal>
</IntlProvider>
<Modal
bsClass='modal'
className='permission-modal'
show={Boolean(this.state.url && this.state.permission)}
id='requestPermissionModal'
enforceFocus={true}
onHide={() => {}}
>
<Modal.Header>
<Modal.Title>{this.getModalTitle()}</Modal.Title>
</Modal.Header>
<Modal.Body>
{this.getModalBody()}
</Modal.Body>
<Modal.Footer className={'remove-border'}>
<div>
<Button onClick={this.props.handleDeny}>
<FormattedMessage
id='label.cancel'
defaultMessage='Cancel'
/>
</Button>
<Button
variant='primary'
onClick={this.props.handleGrant}
>
<FormattedMessage
id='label.accept'
defaultMessage='Accept'
/>
</Button>
</div>
</Modal.Footer>
</Modal>
);
}
}