From adf494e944e6fc813d3852b31e71ec5839540d38 Mon Sep 17 00:00:00 2001 From: Devin Binnie <52460000+devinbinnie@users.noreply.github.com> Date: Tue, 4 Jan 2022 15:00:56 -0500 Subject: [PATCH] [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 --- src/common/config/defaultPreferences.ts | 2 +- src/common/config/index.test.js | 2 + src/common/config/index.ts | 6 +++ .../config/migrationPreferences.test.js | 38 +++++++++++++++++++ src/common/config/migrationPreferences.ts | 21 ++++++++++ src/main/Validator.test.js | 2 +- src/main/Validator.ts | 2 +- src/main/constants.ts | 2 + src/main/tray/tray.ts | 3 +- src/renderer/components/SettingsPage.tsx | 18 ++++++++- src/types/config.ts | 4 ++ 11 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/common/config/migrationPreferences.test.js create mode 100644 src/common/config/migrationPreferences.ts diff --git a/src/common/config/defaultPreferences.ts b/src/common/config/defaultPreferences.ts index 8f6b988c..3e318493 100644 --- a/src/common/config/defaultPreferences.ts +++ b/src/common/config/defaultPreferences.ts @@ -20,7 +20,7 @@ const defaultPreferences: ConfigV3 = { version: 3, teams: [], showTrayIcon: true, - trayIconTheme: 'light', + trayIconTheme: 'use_system', minimizeToTray: true, notifications: { flashWindow: 2, diff --git a/src/common/config/index.test.js b/src/common/config/index.test.js index 067501bb..2a45ebb7 100644 --- a/src/common/config/index.test.js +++ b/src/common/config/index.test.js @@ -89,6 +89,8 @@ jest.mock('common/config/upgradePreferences', () => { }); }); +jest.mock('common/config/migrationPreferences', () => jest.fn()); + jest.mock('common/config/buildConfig', () => { return { defaultTeams: [buildTeam], diff --git a/src/common/config/index.ts b/src/common/config/index.ts index f22d54f3..c27a047a 100644 --- a/src/common/config/index.ts +++ b/src/common/config/index.ts @@ -31,6 +31,7 @@ import defaultPreferences, {getDefaultDownloadLocation} from './defaultPreferenc import upgradeConfigData from './upgradePreferences'; import buildConfig from './buildConfig'; 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 @@ -339,6 +340,11 @@ export class Config extends EventEmitter { this.writeFileSync(this.configFilePath, configData); 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) { log.error(`Failed to update configuration to version ${this.defaultConfigData.version}.`); } diff --git a/src/common/config/migrationPreferences.test.js b/src/common/config/migrationPreferences.test.js new file mode 100644 index 00000000..0f72c36a --- /dev/null +++ b/src/common/config/migrationPreferences.test.js @@ -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, + }); + }); + }); +}); diff --git a/src/common/config/migrationPreferences.ts b/src/common/config/migrationPreferences.ts new file mode 100644 index 00000000..e78b44da --- /dev/null +++ b/src/common/config/migrationPreferences.ts @@ -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(migrationInfoPath); + let didMigrate = false; + + if (!migrationPrefs.getValue('updateTrayIconWin32') && process.platform === 'win32') { + config.trayIconTheme = 'use_system'; + migrationPrefs.setValue('updateTrayIconWin32', true); + didMigrate = true; + } + + return didMigrate; +} diff --git a/src/main/Validator.test.js b/src/main/Validator.test.js index a15191a5..1d77b396 100644 --- a/src/main/Validator.test.js +++ b/src/main/Validator.test.js @@ -149,7 +149,7 @@ describe('main/Validator', () => { ], }, ], - trayIconTheme: 'light', + trayIconTheme: 'use_system', useSpellChecker: true, version: 3, }; diff --git a/src/main/Validator.ts b/src/main/Validator.ts index 5cabe840..40e691c2 100644 --- a/src/main/Validator.ts +++ b/src/main/Validator.ts @@ -108,7 +108,7 @@ const configDataSchemaV3 = Joi.object({ })).default([]), })).default([]), 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), notifications: Joi.object({ flashWindow: Joi.any().valid(0, 2).default(0), diff --git a/src/main/constants.ts b/src/main/constants.ts index f59c594d..bd6b325d 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -17,6 +17,7 @@ export let appVersionJson = ''; export let certificateStorePath = ''; export let trustedOriginsStoreFile = ''; export let boundsInfoPath = ''; +export let migrationInfoPath = ''; export function updatePaths(emit = false) { userDataPath = app.getPath('userData'); @@ -27,6 +28,7 @@ export function updatePaths(emit = false) { certificateStorePath = path.resolve(userDataPath, 'certificate.json'); trustedOriginsStoreFile = path.resolve(userDataPath, 'trustedOrigins.json'); boundsInfoPath = path.join(userDataPath, 'bounds-info.json'); + migrationInfoPath = path.resolve(userDataPath, 'migration-info.json'); if (emit) { ipcMain.emit(UPDATE_PATHS); diff --git a/src/main/tray/tray.ts b/src/main/tray/tray.ts index 914766d9..371b8052 100644 --- a/src/main/tray/tray.ts +++ b/src/main/tray/tray.ts @@ -18,7 +18,8 @@ let lastMessage = app.name; /* istanbul ignore next */ 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) { case 'win32': diff --git a/src/renderer/components/SettingsPage.tsx b/src/renderer/components/SettingsPage.tsx index 58d40bbb..434e5988 100644 --- a/src/renderer/components/SettingsPage.tsx +++ b/src/renderer/components/SettingsPage.tsx @@ -637,7 +637,7 @@ export default class SettingsPage extends React.PureComponent); } - if (window.process.platform === 'linux') { + if (window.process.platform === 'linux' || window.process.platform === 'win32') { options.push( {'Icon theme: '} + {window.process.platform === 'win32' && + <> + this.handleChangeTrayIconTheme('use_system')} + label={'Use system default'} + /> + {' '} + + }