[MM-36058][MM-40572] Tray fixes (#1933)
* [MM-36058] Added config migration function, update default tray icon theme to system, allow Windows users to override icon theme * [MM-40572] Restore minimize to tray option for Windows * Lint fix * Test fix * Oops
This commit is contained in:
@@ -20,7 +20,7 @@ const defaultPreferences: ConfigV3 = {
|
|||||||
version: 3,
|
version: 3,
|
||||||
teams: [],
|
teams: [],
|
||||||
showTrayIcon: true,
|
showTrayIcon: true,
|
||||||
trayIconTheme: 'light',
|
trayIconTheme: 'use_system',
|
||||||
minimizeToTray: true,
|
minimizeToTray: true,
|
||||||
notifications: {
|
notifications: {
|
||||||
flashWindow: 2,
|
flashWindow: 2,
|
||||||
|
@@ -89,6 +89,8 @@ jest.mock('common/config/upgradePreferences', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.mock('common/config/migrationPreferences', () => jest.fn());
|
||||||
|
|
||||||
jest.mock('common/config/buildConfig', () => {
|
jest.mock('common/config/buildConfig', () => {
|
||||||
return {
|
return {
|
||||||
defaultTeams: [buildTeam],
|
defaultTeams: [buildTeam],
|
||||||
|
@@ -31,6 +31,7 @@ import defaultPreferences, {getDefaultDownloadLocation} from './defaultPreferenc
|
|||||||
import upgradeConfigData from './upgradePreferences';
|
import upgradeConfigData from './upgradePreferences';
|
||||||
import buildConfig from './buildConfig';
|
import buildConfig from './buildConfig';
|
||||||
import RegistryConfig, {REGISTRY_READ_EVENT} from './RegistryConfig';
|
import RegistryConfig, {REGISTRY_READ_EVENT} from './RegistryConfig';
|
||||||
|
import migrateConfigItems from './migrationPreferences';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles loading and merging all sources of configuration as well as saving user provided config
|
* Handles loading and merging all sources of configuration as well as saving user provided config
|
||||||
@@ -339,6 +340,11 @@ export class Config extends EventEmitter {
|
|||||||
this.writeFileSync(this.configFilePath, configData);
|
this.writeFileSync(this.configFilePath, configData);
|
||||||
log.info(`Configuration updated to version ${this.defaultConfigData.version} successfully.`);
|
log.info(`Configuration updated to version ${this.defaultConfigData.version} successfully.`);
|
||||||
}
|
}
|
||||||
|
const didMigrate = migrateConfigItems(configData);
|
||||||
|
if (didMigrate) {
|
||||||
|
this.writeFileSync(this.configFilePath, configData);
|
||||||
|
log.info('Migrating config items successfully.');
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(`Failed to update configuration to version ${this.defaultConfigData.version}.`);
|
log.error(`Failed to update configuration to version ${this.defaultConfigData.version}.`);
|
||||||
}
|
}
|
||||||
|
38
src/common/config/migrationPreferences.test.js
Normal file
38
src/common/config/migrationPreferences.test.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import JsonFileManager from 'common/JsonFileManager';
|
||||||
|
|
||||||
|
import migrateConfigItems from './migrationPreferences';
|
||||||
|
|
||||||
|
jest.mock('common/JsonFileManager', () => jest.fn());
|
||||||
|
|
||||||
|
describe('common/config/migrationPreferences', () => {
|
||||||
|
describe('migrateConfigItems', () => {
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not migrate if all items migrated', () => {
|
||||||
|
JsonFileManager.mockImplementation(() => ({
|
||||||
|
getValue: () => true,
|
||||||
|
}));
|
||||||
|
expect(migrateConfigItems({})).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should migrate if items are not migrated', () => {
|
||||||
|
const originalPlatform = process.platform;
|
||||||
|
Object.defineProperty(process, 'platform', {
|
||||||
|
value: 'win32',
|
||||||
|
});
|
||||||
|
JsonFileManager.mockImplementation(() => ({
|
||||||
|
getValue: () => false,
|
||||||
|
setValue: jest.fn(),
|
||||||
|
}));
|
||||||
|
expect(migrateConfigItems({})).toBe(true);
|
||||||
|
Object.defineProperty(process, 'platform', {
|
||||||
|
value: originalPlatform,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
21
src/common/config/migrationPreferences.ts
Normal file
21
src/common/config/migrationPreferences.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import {Config, MigrationInfo} from 'types/config';
|
||||||
|
|
||||||
|
import JsonFileManager from 'common/JsonFileManager';
|
||||||
|
|
||||||
|
import {migrationInfoPath} from 'main/constants';
|
||||||
|
|
||||||
|
export default function migrateConfigItems(config: Config) {
|
||||||
|
const migrationPrefs = new JsonFileManager<MigrationInfo>(migrationInfoPath);
|
||||||
|
let didMigrate = false;
|
||||||
|
|
||||||
|
if (!migrationPrefs.getValue('updateTrayIconWin32') && process.platform === 'win32') {
|
||||||
|
config.trayIconTheme = 'use_system';
|
||||||
|
migrationPrefs.setValue('updateTrayIconWin32', true);
|
||||||
|
didMigrate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return didMigrate;
|
||||||
|
}
|
@@ -149,7 +149,7 @@ describe('main/Validator', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
trayIconTheme: 'light',
|
trayIconTheme: 'use_system',
|
||||||
useSpellChecker: true,
|
useSpellChecker: true,
|
||||||
version: 3,
|
version: 3,
|
||||||
};
|
};
|
||||||
|
@@ -108,7 +108,7 @@ const configDataSchemaV3 = Joi.object<ConfigV3>({
|
|||||||
})).default([]),
|
})).default([]),
|
||||||
})).default([]),
|
})).default([]),
|
||||||
showTrayIcon: Joi.boolean().default(false),
|
showTrayIcon: Joi.boolean().default(false),
|
||||||
trayIconTheme: Joi.any().allow('').valid('light', 'dark').default('light'),
|
trayIconTheme: Joi.any().allow('').valid('light', 'dark', 'use_system').default('use_system'),
|
||||||
minimizeToTray: Joi.boolean().default(false),
|
minimizeToTray: Joi.boolean().default(false),
|
||||||
notifications: Joi.object({
|
notifications: Joi.object({
|
||||||
flashWindow: Joi.any().valid(0, 2).default(0),
|
flashWindow: Joi.any().valid(0, 2).default(0),
|
||||||
|
@@ -17,6 +17,7 @@ export let appVersionJson = '';
|
|||||||
export let certificateStorePath = '';
|
export let certificateStorePath = '';
|
||||||
export let trustedOriginsStoreFile = '';
|
export let trustedOriginsStoreFile = '';
|
||||||
export let boundsInfoPath = '';
|
export let boundsInfoPath = '';
|
||||||
|
export let migrationInfoPath = '';
|
||||||
|
|
||||||
export function updatePaths(emit = false) {
|
export function updatePaths(emit = false) {
|
||||||
userDataPath = app.getPath('userData');
|
userDataPath = app.getPath('userData');
|
||||||
@@ -27,6 +28,7 @@ export function updatePaths(emit = false) {
|
|||||||
certificateStorePath = path.resolve(userDataPath, 'certificate.json');
|
certificateStorePath = path.resolve(userDataPath, 'certificate.json');
|
||||||
trustedOriginsStoreFile = path.resolve(userDataPath, 'trustedOrigins.json');
|
trustedOriginsStoreFile = path.resolve(userDataPath, 'trustedOrigins.json');
|
||||||
boundsInfoPath = path.join(userDataPath, 'bounds-info.json');
|
boundsInfoPath = path.join(userDataPath, 'bounds-info.json');
|
||||||
|
migrationInfoPath = path.resolve(userDataPath, 'migration-info.json');
|
||||||
|
|
||||||
if (emit) {
|
if (emit) {
|
||||||
ipcMain.emit(UPDATE_PATHS);
|
ipcMain.emit(UPDATE_PATHS);
|
||||||
|
@@ -18,7 +18,8 @@ let lastMessage = app.name;
|
|||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
export function refreshTrayImages(trayIconTheme: string) {
|
export function refreshTrayImages(trayIconTheme: string) {
|
||||||
const winTheme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
const systemTheme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||||
|
const winTheme = trayIconTheme === 'use_system' ? systemTheme : trayIconTheme;
|
||||||
|
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case 'win32':
|
case 'win32':
|
||||||
|
@@ -637,7 +637,7 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
</FormCheck>);
|
</FormCheck>);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.process.platform === 'linux') {
|
if (window.process.platform === 'linux' || window.process.platform === 'win32') {
|
||||||
options.push(
|
options.push(
|
||||||
<FormGroup
|
<FormGroup
|
||||||
key='trayIconTheme'
|
key='trayIconTheme'
|
||||||
@@ -645,6 +645,20 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
style={{marginLeft: '20px'}}
|
style={{marginLeft: '20px'}}
|
||||||
>
|
>
|
||||||
{'Icon theme: '}
|
{'Icon theme: '}
|
||||||
|
{window.process.platform === 'win32' &&
|
||||||
|
<>
|
||||||
|
<FormCheck
|
||||||
|
type='radio'
|
||||||
|
inline={true}
|
||||||
|
name='trayIconTheme'
|
||||||
|
value='use_system'
|
||||||
|
defaultChecked={this.state.trayIconTheme === 'use_system' || !this.state.trayIconTheme}
|
||||||
|
onChange={() => this.handleChangeTrayIconTheme('use_system')}
|
||||||
|
label={'Use system default'}
|
||||||
|
/>
|
||||||
|
{' '}
|
||||||
|
</>
|
||||||
|
}
|
||||||
<FormCheck
|
<FormCheck
|
||||||
type='radio'
|
type='radio'
|
||||||
inline={true}
|
inline={true}
|
||||||
@@ -668,7 +682,7 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.process.platform === 'linux') {
|
if (window.process.platform === 'linux' || window.process.platform === 'win32') {
|
||||||
options.push(
|
options.push(
|
||||||
<FormCheck
|
<FormCheck
|
||||||
key='inputMinimizeToTray'
|
key='inputMinimizeToTray'
|
||||||
|
@@ -118,3 +118,7 @@ export type LocalConfiguration = Config & {
|
|||||||
appName: string;
|
appName: string;
|
||||||
enableServerManagement: boolean;
|
enableServerManagement: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type MigrationInfo = {
|
||||||
|
updateTrayIconWin32: boolean;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user