Move Settings Window into Modal (#3007)
* Move Settings Window into modal * Re-add for E2E tests
This commit is contained in:
parent
d2414c286f
commit
02704177c0
|
@ -11,7 +11,6 @@ import {setUnreadBadgeSetting} from 'main/badge';
|
||||||
import Tray from 'main/tray/tray';
|
import Tray from 'main/tray/tray';
|
||||||
import LoadingScreen from 'main/views/loadingScreen';
|
import LoadingScreen from 'main/views/loadingScreen';
|
||||||
import MainWindow from 'main/windows/mainWindow';
|
import MainWindow from 'main/windows/mainWindow';
|
||||||
import SettingsWindow from 'main/windows/settingsWindow';
|
|
||||||
|
|
||||||
import type {CombinedConfig, Config as ConfigType} from 'types/config';
|
import type {CombinedConfig, Config as ConfigType} from 'types/config';
|
||||||
|
|
||||||
|
@ -73,7 +72,7 @@ export function handleConfigUpdate(newConfig: CombinedConfig) {
|
||||||
|
|
||||||
if (app.isReady()) {
|
if (app.isReady()) {
|
||||||
MainWindow.sendToRenderer(RELOAD_CONFIGURATION);
|
MainWindow.sendToRenderer(RELOAD_CONFIGURATION);
|
||||||
SettingsWindow.sendToRenderer(RELOAD_CONFIGURATION);
|
ipcMain.emit(EMIT_CONFIGURATION, true, Config.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
setUnreadBadgeSetting(newConfig && newConfig.showUnreadBadge);
|
setUnreadBadgeSetting(newConfig && newConfig.showUnreadBadge);
|
||||||
|
@ -113,7 +112,6 @@ export function handleDarkModeChange(darkMode: boolean) {
|
||||||
|
|
||||||
Tray.refreshImages(Config.trayIconTheme);
|
Tray.refreshImages(Config.trayIconTheme);
|
||||||
MainWindow.sendToRenderer(DARK_MODE_CHANGE, darkMode);
|
MainWindow.sendToRenderer(DARK_MODE_CHANGE, darkMode);
|
||||||
SettingsWindow.sendToRenderer(DARK_MODE_CHANGE, darkMode);
|
|
||||||
LoadingScreen.setDarkMode(darkMode);
|
LoadingScreen.setDarkMode(darkMode);
|
||||||
|
|
||||||
ipcMain.emit(EMIT_CONFIGURATION, true, Config.data);
|
ipcMain.emit(EMIT_CONFIGURATION, true, Config.data);
|
||||||
|
|
|
@ -166,9 +166,6 @@ jest.mock('main/views/viewManager', () => ({
|
||||||
getViewByWebContentsId: jest.fn(),
|
getViewByWebContentsId: jest.fn(),
|
||||||
handleDeepLink: jest.fn(),
|
handleDeepLink: jest.fn(),
|
||||||
}));
|
}));
|
||||||
jest.mock('main/windows/settingsWindow', () => ({
|
|
||||||
show: jest.fn(),
|
|
||||||
}));
|
|
||||||
jest.mock('main/windows/mainWindow', () => ({
|
jest.mock('main/windows/mainWindow', () => ({
|
||||||
get: jest.fn(),
|
get: jest.fn(),
|
||||||
show: jest.fn(),
|
show: jest.fn(),
|
||||||
|
|
|
@ -31,6 +31,7 @@ import {
|
||||||
DOUBLE_CLICK_ON_WINDOW,
|
DOUBLE_CLICK_ON_WINDOW,
|
||||||
TOGGLE_SECURE_INPUT,
|
TOGGLE_SECURE_INPUT,
|
||||||
GET_APP_INFO,
|
GET_APP_INFO,
|
||||||
|
SHOW_SETTINGS_WINDOW,
|
||||||
} from 'common/communication';
|
} from 'common/communication';
|
||||||
import Config from 'common/config';
|
import Config from 'common/config';
|
||||||
import {Logger} from 'common/log';
|
import {Logger} from 'common/log';
|
||||||
|
@ -79,6 +80,7 @@ import {
|
||||||
handleQuit,
|
handleQuit,
|
||||||
handlePingDomain,
|
handlePingDomain,
|
||||||
handleToggleSecureInput,
|
handleToggleSecureInput,
|
||||||
|
handleShowSettingsModal,
|
||||||
} from './intercom';
|
} from './intercom';
|
||||||
import {
|
import {
|
||||||
clearAppCache,
|
clearAppCache,
|
||||||
|
@ -281,6 +283,10 @@ function initializeInterCommunicationEventListeners() {
|
||||||
ipcMain.on(DOUBLE_CLICK_ON_WINDOW, handleDoubleClick);
|
ipcMain.on(DOUBLE_CLICK_ON_WINDOW, handleDoubleClick);
|
||||||
|
|
||||||
ipcMain.on(TOGGLE_SECURE_INPUT, handleToggleSecureInput);
|
ipcMain.on(TOGGLE_SECURE_INPUT, handleToggleSecureInput);
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'test') {
|
||||||
|
ipcMain.on(SHOW_SETTINGS_WINDOW, handleShowSettingsModal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initializeAfterAppReady() {
|
async function initializeAfterAppReady() {
|
||||||
|
|
|
@ -160,3 +160,18 @@ export function handleToggleSecureInput(event: IpcMainEvent, secureInput: boolea
|
||||||
log.debug('handleToggleSecureInput', secureInput);
|
log.debug('handleToggleSecureInput', secureInput);
|
||||||
app.setSecureKeyboardEntryEnabled(secureInput);
|
app.setSecureKeyboardEntryEnabled(secureInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function handleShowSettingsModal() {
|
||||||
|
const mainWindow = MainWindow.get();
|
||||||
|
if (!mainWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModalManager.addModal(
|
||||||
|
'settingsModal',
|
||||||
|
getLocalURLString('settings.html'),
|
||||||
|
getLocalPreload('internalAPI.js'),
|
||||||
|
null,
|
||||||
|
mainWindow,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -79,10 +79,8 @@ jest.mock('main/downloadsManager', () => ({
|
||||||
}));
|
}));
|
||||||
jest.mock('main/views/viewManager', () => ({}));
|
jest.mock('main/views/viewManager', () => ({}));
|
||||||
jest.mock('main/windows/mainWindow', () => ({
|
jest.mock('main/windows/mainWindow', () => ({
|
||||||
sendToRenderer: jest.fn(),
|
get: jest.fn(),
|
||||||
on: jest.fn(),
|
|
||||||
}));
|
}));
|
||||||
jest.mock('main/windows/settingsWindow', () => ({}));
|
|
||||||
jest.mock('common/views/View', () => ({
|
jest.mock('common/views/View', () => ({
|
||||||
getViewDisplayName: (name) => name,
|
getViewDisplayName: (name) => name,
|
||||||
}));
|
}));
|
||||||
|
@ -93,6 +91,9 @@ jest.mock('main/AutoLauncher', () => ({
|
||||||
jest.mock('main/windows/callsWidgetWindow', () => ({
|
jest.mock('main/windows/callsWidgetWindow', () => ({
|
||||||
isOpen: jest.fn(),
|
isOpen: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
jest.mock('main/views/modalManager', () => ({
|
||||||
|
addModal: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('main/menus/app', () => {
|
describe('main/menus/app', () => {
|
||||||
const config = {
|
const config = {
|
||||||
|
|
|
@ -18,9 +18,11 @@ import type {UpdateManager} from 'main/autoUpdater';
|
||||||
import Diagnostics from 'main/diagnostics';
|
import Diagnostics from 'main/diagnostics';
|
||||||
import downloadsManager from 'main/downloadsManager';
|
import downloadsManager from 'main/downloadsManager';
|
||||||
import {localizeMessage} from 'main/i18nManager';
|
import {localizeMessage} from 'main/i18nManager';
|
||||||
|
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||||
|
import ModalManager from 'main/views/modalManager';
|
||||||
import ViewManager from 'main/views/viewManager';
|
import ViewManager from 'main/views/viewManager';
|
||||||
import CallsWidgetWindow from 'main/windows/callsWidgetWindow';
|
import CallsWidgetWindow from 'main/windows/callsWidgetWindow';
|
||||||
import SettingsWindow from 'main/windows/settingsWindow';
|
import MainWindow from 'main/windows/mainWindow';
|
||||||
|
|
||||||
export function createTemplate(config: Config, updateManager: UpdateManager) {
|
export function createTemplate(config: Config, updateManager: UpdateManager) {
|
||||||
const separatorItem: MenuItemConstructorOptions = {
|
const separatorItem: MenuItemConstructorOptions = {
|
||||||
|
@ -48,7 +50,18 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
|
||||||
label: settingsLabel,
|
label: settingsLabel,
|
||||||
accelerator: 'CmdOrCtrl+,',
|
accelerator: 'CmdOrCtrl+,',
|
||||||
click() {
|
click() {
|
||||||
SettingsWindow.show();
|
const mainWindow = MainWindow.get();
|
||||||
|
if (!mainWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModalManager.addModal(
|
||||||
|
'settingsModal',
|
||||||
|
getLocalURLString('settings.html'),
|
||||||
|
getLocalPreload('internalAPI.js'),
|
||||||
|
null,
|
||||||
|
mainWindow,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,13 @@ jest.mock('common/servers/serverManager', () => ({
|
||||||
jest.mock('app/serverViewState', () => ({
|
jest.mock('app/serverViewState', () => ({
|
||||||
switchServer: jest.fn(),
|
switchServer: jest.fn(),
|
||||||
}));
|
}));
|
||||||
jest.mock('main/windows/settingsWindow', () => ({}));
|
jest.mock('main/windows/mainWindow', () => ({
|
||||||
|
sendToRenderer: jest.fn(),
|
||||||
|
on: jest.fn(),
|
||||||
|
}));
|
||||||
|
jest.mock('main/views/modalManager', () => ({
|
||||||
|
addModal: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('main/menus/tray', () => {
|
describe('main/menus/tray', () => {
|
||||||
it('should show the first 9 servers (using order)', () => {
|
it('should show the first 9 servers (using order)', () => {
|
||||||
|
|
|
@ -9,7 +9,9 @@ import {Menu} from 'electron';
|
||||||
import ServerViewState from 'app/serverViewState';
|
import ServerViewState from 'app/serverViewState';
|
||||||
import ServerManager from 'common/servers/serverManager';
|
import ServerManager from 'common/servers/serverManager';
|
||||||
import {localizeMessage} from 'main/i18nManager';
|
import {localizeMessage} from 'main/i18nManager';
|
||||||
import SettingsWindow from 'main/windows/settingsWindow';
|
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||||
|
import ModalManager from 'main/views/modalManager';
|
||||||
|
import MainWindow from 'main/windows/mainWindow';
|
||||||
|
|
||||||
export function createTemplate() {
|
export function createTemplate() {
|
||||||
const servers = ServerManager.getOrderedServers();
|
const servers = ServerManager.getOrderedServers();
|
||||||
|
@ -26,7 +28,18 @@ export function createTemplate() {
|
||||||
}, {
|
}, {
|
||||||
label: process.platform === 'darwin' ? localizeMessage('main.menus.tray.preferences', 'Preferences...') : localizeMessage('main.menus.tray.settings', 'Settings'),
|
label: process.platform === 'darwin' ? localizeMessage('main.menus.tray.preferences', 'Preferences...') : localizeMessage('main.menus.tray.settings', 'Settings'),
|
||||||
click: () => {
|
click: () => {
|
||||||
SettingsWindow.show();
|
const mainWindow = MainWindow.get();
|
||||||
|
if (!mainWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModalManager.addModal(
|
||||||
|
'settingsModal',
|
||||||
|
getLocalURLString('settings.html'),
|
||||||
|
getLocalPreload('internalAPI.js'),
|
||||||
|
null,
|
||||||
|
mainWindow,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
type: 'separator',
|
type: 'separator',
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {UPDATE_APPSTATE_TOTALS} from 'common/communication';
|
||||||
import {Logger} from 'common/log';
|
import {Logger} from 'common/log';
|
||||||
import {localizeMessage} from 'main/i18nManager';
|
import {localizeMessage} from 'main/i18nManager';
|
||||||
import MainWindow from 'main/windows/mainWindow';
|
import MainWindow from 'main/windows/mainWindow';
|
||||||
import SettingsWindow from 'main/windows/settingsWindow';
|
|
||||||
|
|
||||||
const assetsDir = path.resolve(app.getAppPath(), 'assets');
|
const assetsDir = path.resolve(app.getAppPath(), 'assets');
|
||||||
const log = new Logger('Tray');
|
const log = new Logger('Tray');
|
||||||
|
@ -144,12 +143,7 @@ export class TrayIcon {
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsWindow = SettingsWindow.get();
|
mainWindow.focus();
|
||||||
if (settingsWindow) {
|
|
||||||
settingsWindow.focus();
|
|
||||||
} else {
|
|
||||||
mainWindow.focus();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private onAppStateUpdate = (anyExpired: boolean, anyMentions: number, anyUnreads: boolean) => {
|
private onAppStateUpdate = (anyExpired: boolean, anyMentions: number, anyUnreads: boolean) => {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
DARK_MODE_CHANGE,
|
DARK_MODE_CHANGE,
|
||||||
GET_MODAL_UNCLOSEABLE,
|
GET_MODAL_UNCLOSEABLE,
|
||||||
MAIN_WINDOW_RESIZED,
|
MAIN_WINDOW_RESIZED,
|
||||||
|
RELOAD_CONFIGURATION,
|
||||||
} from 'common/communication';
|
} from 'common/communication';
|
||||||
import {Logger} from 'common/log';
|
import {Logger} from 'common/log';
|
||||||
import {getAdjustedWindowBoundaries} from 'main/utils';
|
import {getAdjustedWindowBoundaries} from 'main/utils';
|
||||||
|
@ -152,6 +153,7 @@ export class ModalManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.modalQueue.forEach((modal) => {
|
this.modalQueue.forEach((modal) => {
|
||||||
|
modal.view.webContents.send(RELOAD_CONFIGURATION);
|
||||||
modal.view.webContents.send(DARK_MODE_CHANGE, config.darkMode);
|
modal.view.webContents.send(DARK_MODE_CHANGE, config.darkMode);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
|
||||||
// See LICENSE.txt for license information.
|
|
||||||
|
|
||||||
import {BrowserWindow, ipcMain} from 'electron';
|
|
||||||
|
|
||||||
import {SHOW_SETTINGS_WINDOW} from 'common/communication';
|
|
||||||
import Config from 'common/config';
|
|
||||||
import {Logger} from 'common/log';
|
|
||||||
|
|
||||||
import MainWindow from './mainWindow';
|
|
||||||
|
|
||||||
import ContextMenu from '../contextMenu';
|
|
||||||
import {getLocalPreload, getLocalURLString} from '../utils';
|
|
||||||
|
|
||||||
const log = new Logger('SettingsWindow');
|
|
||||||
|
|
||||||
export class SettingsWindow {
|
|
||||||
private win?: BrowserWindow;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
ipcMain.on(SHOW_SETTINGS_WINDOW, this.show);
|
|
||||||
}
|
|
||||||
|
|
||||||
show = () => {
|
|
||||||
if (this.win) {
|
|
||||||
this.win.show();
|
|
||||||
} else {
|
|
||||||
this.create();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
get = () => {
|
|
||||||
return this.win;
|
|
||||||
};
|
|
||||||
|
|
||||||
sendToRenderer = (channel: string, ...args: any[]) => {
|
|
||||||
this.win?.webContents.send(channel, ...args);
|
|
||||||
};
|
|
||||||
|
|
||||||
private create = () => {
|
|
||||||
const mainWindow = MainWindow.get();
|
|
||||||
if (!mainWindow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const preload = getLocalPreload('internalAPI.js');
|
|
||||||
const spellcheck = (typeof Config.useSpellChecker === 'undefined' ? true : Config.useSpellChecker);
|
|
||||||
this.win = new BrowserWindow({
|
|
||||||
title: 'Desktop App Settings',
|
|
||||||
fullscreen: false,
|
|
||||||
webPreferences: {
|
|
||||||
preload,
|
|
||||||
spellcheck,
|
|
||||||
}});
|
|
||||||
|
|
||||||
const contextMenu = new ContextMenu({}, this.win);
|
|
||||||
contextMenu.reload();
|
|
||||||
|
|
||||||
const localURL = getLocalURLString('settings.html');
|
|
||||||
this.win.setMenuBarVisibility(false);
|
|
||||||
this.win.loadURL(localURL).catch(
|
|
||||||
(reason) => {
|
|
||||||
log.error('failed to load', reason);
|
|
||||||
});
|
|
||||||
this.win.show();
|
|
||||||
|
|
||||||
if (Boolean(process.env.MM_DEBUG_SETTINGS) || false) {
|
|
||||||
this.win.webContents.openDevTools({mode: 'detach'});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.win.on('closed', () => {
|
|
||||||
delete this.win;
|
|
||||||
|
|
||||||
// For some reason, on macOS, the app will hard crash when the settings window is closed
|
|
||||||
// It seems to be related to calling view.focus() and there's no log output unfortunately
|
|
||||||
// Adding this arbitrary delay seems to get rid of it (it happens very frequently)
|
|
||||||
setTimeout(() => MainWindow.get()?.focus(), 10);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const settingsWindow = new SettingsWindow();
|
|
||||||
export default settingsWindow;
|
|
|
@ -7,7 +7,7 @@
|
||||||
import 'renderer/css/settings.css';
|
import 'renderer/css/settings.css';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {FormCheck, Col, FormGroup, FormText, Container, Row, Button, FormControl} from 'react-bootstrap';
|
import {FormCheck, Col, FormGroup, FormText, Container, Row, Button, FormControl, Modal} from 'react-bootstrap';
|
||||||
import type {IntlShape} from 'react-intl';
|
import type {IntlShape} from 'react-intl';
|
||||||
import {FormattedMessage, injectIntl} from 'react-intl';
|
import {FormattedMessage, injectIntl} from 'react-intl';
|
||||||
import type {ActionMeta, MultiValue} from 'react-select';
|
import type {ActionMeta, MultiValue} from 'react-select';
|
||||||
|
@ -25,6 +25,8 @@ const CONFIG_TYPE_UPDATES = 'updates';
|
||||||
const CONFIG_TYPE_APP_OPTIONS = 'appOptions';
|
const CONFIG_TYPE_APP_OPTIONS = 'appOptions';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
show: boolean;
|
||||||
|
onClose: () => void;
|
||||||
intl: IntlShape;
|
intl: IntlShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1228,35 +1230,36 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Modal
|
||||||
className='container-fluid'
|
show={this.props.show}
|
||||||
style={{
|
id='settingsModal'
|
||||||
height: '100%',
|
onHide={this.props.onClose}
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div
|
<Modal.Header closeButton={true}>
|
||||||
style={{
|
<Modal.Title>
|
||||||
overflowY: 'auto',
|
<FormattedMessage
|
||||||
height: '100%',
|
id='renderer.components.settingsPage.header'
|
||||||
margin: '0 -15px',
|
defaultMessage='Settings'
|
||||||
}}
|
/>
|
||||||
>
|
</Modal.Title>
|
||||||
<div style={{position: 'relative'}}>
|
</Modal.Header>
|
||||||
<h1 style={settingsPage.heading}>
|
|
||||||
<FormattedMessage
|
<Modal.Body>
|
||||||
id='renderer.components.settingsPage.header'
|
<div
|
||||||
defaultMessage='Settings'
|
style={{
|
||||||
/>
|
overflowY: 'auto',
|
||||||
</h1>
|
height: '100%',
|
||||||
<hr/>
|
margin: '0 -15px',
|
||||||
</div>
|
}}
|
||||||
<Container
|
|
||||||
className='settingsPage'
|
|
||||||
>
|
>
|
||||||
{waitForIpc}
|
<Container
|
||||||
</Container>
|
className='settingsPage'
|
||||||
</div>
|
>
|
||||||
</div>
|
{waitForIpc}
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</Modal.Body>
|
||||||
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,27 @@
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__control {
|
||||||
|
background: #242a30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__menu {
|
||||||
|
background: #242a30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__option {
|
||||||
|
background: #242a30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__option:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
#settingsModal .modal-body {
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--light) rgba(255, 255, 255, 0);
|
||||||
}
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
@import '~bootstrap-dark/src/bootstrap-dark.css';
|
|
||||||
|
|
||||||
.ServerListItem:hover {
|
|
||||||
background: #242a30;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__control {
|
|
||||||
background: #242a30;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__menu {
|
|
||||||
background: #242a30;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__option {
|
|
||||||
background: #242a30;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__option:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.16);
|
|
||||||
}
|
|
|
@ -41,3 +41,25 @@ body {
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#settingsModal .modal-content {
|
||||||
|
padding: 16px;
|
||||||
|
max-height: calc(100vh - 50px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#settingsModal .modal-body {
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--dark) rgba(255, 255, 255, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#settingsModal .modal-header {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 862px) {
|
||||||
|
#settingsModal {
|
||||||
|
max-width: 786px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// Copyright (c) 2015-2016 Yuya Ochiai
|
|
||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
@ -9,27 +8,24 @@ import 'renderer/css/settings.css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import darkStyles from 'renderer/css/lazy/settings-dark.lazy.css';
|
import SettingsPage from '../../components/SettingsPage';
|
||||||
|
import IntlProvider from '../../intl_provider';
|
||||||
|
import setupDarkMode from '../darkMode';
|
||||||
|
|
||||||
import SettingsPage from './components/SettingsPage';
|
setupDarkMode();
|
||||||
import IntlProvider from './intl_provider';
|
|
||||||
|
|
||||||
const setDarkMode = (darkMode: boolean) => {
|
const onClose = () => {
|
||||||
if (darkMode) {
|
window.desktop.modals.finishModal();
|
||||||
darkStyles.use();
|
|
||||||
} else {
|
|
||||||
darkStyles.unuse();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.desktop.onDarkModeChange((darkMode) => setDarkMode(darkMode));
|
|
||||||
window.desktop.getDarkMode().then(setDarkMode);
|
|
||||||
|
|
||||||
const start = async () => {
|
const start = async () => {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
(
|
(
|
||||||
<IntlProvider>
|
<IntlProvider>
|
||||||
<SettingsPage/>
|
<SettingsPage
|
||||||
|
show={true}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
</IntlProvider>
|
</IntlProvider>
|
||||||
)
|
)
|
||||||
,
|
,
|
|
@ -13,7 +13,7 @@ const base = require('./webpack.config.base');
|
||||||
module.exports = merge(base, {
|
module.exports = merge(base, {
|
||||||
entry: {
|
entry: {
|
||||||
index: './src/renderer/index.tsx',
|
index: './src/renderer/index.tsx',
|
||||||
settings: './src/renderer/settings.tsx',
|
settings: './src/renderer/modals/settings/settings.tsx',
|
||||||
dropdown: './src/renderer/dropdown.tsx',
|
dropdown: './src/renderer/dropdown.tsx',
|
||||||
downloadsDropdownMenu: './src/renderer/downloadsDropdownMenu.tsx',
|
downloadsDropdownMenu: './src/renderer/downloadsDropdownMenu.tsx',
|
||||||
downloadsDropdown: './src/renderer/downloadsDropdown.tsx',
|
downloadsDropdown: './src/renderer/downloadsDropdown.tsx',
|
||||||
|
|
Loading…
Reference in a new issue