Refactor config, move ipc calls to app module, some cleanup (#2669)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {app, ipcMain} from 'electron';
|
||||
import {app, ipcMain, nativeTheme} from 'electron';
|
||||
|
||||
import {CombinedConfig} from 'types/config';
|
||||
import {CombinedConfig, ConfigServer, Config as ConfigType} from 'types/config';
|
||||
|
||||
import {DARK_MODE_CHANGE, EMIT_CONFIGURATION, RELOAD_CONFIGURATION} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
@@ -25,6 +25,49 @@ const log = new Logger('App.Config');
|
||||
// config event handlers
|
||||
//
|
||||
|
||||
export function handleGetConfiguration() {
|
||||
log.debug('handleGetConfiguration');
|
||||
|
||||
return Config.data;
|
||||
}
|
||||
|
||||
export function handleGetLocalConfiguration() {
|
||||
log.debug('handleGetLocalConfiguration');
|
||||
|
||||
return {
|
||||
...Config.localData,
|
||||
appName: app.name,
|
||||
enableServerManagement: Config.enableServerManagement,
|
||||
canUpgrade: Config.canUpgrade,
|
||||
};
|
||||
}
|
||||
|
||||
export function updateConfiguration(event: Electron.IpcMainEvent, properties: Array<{key: keyof ConfigType; data: ConfigType[keyof ConfigType]}> = []) {
|
||||
log.debug('updateConfiguration', properties);
|
||||
|
||||
if (properties.length) {
|
||||
const newData = properties.reduce((obj, data) => {
|
||||
(obj as any)[data.key] = data.data;
|
||||
return obj;
|
||||
}, {} as Partial<ConfigType>);
|
||||
Config.setMultiple(newData);
|
||||
}
|
||||
}
|
||||
|
||||
export function handleUpdateTheme() {
|
||||
log.debug('Config.handleUpdateTheme');
|
||||
|
||||
Config.set('darkMode', nativeTheme.shouldUseDarkColors);
|
||||
}
|
||||
|
||||
export function handleUpdateTeams(event: Electron.IpcMainInvokeEvent, newTeams: ConfigServer[]) {
|
||||
log.debug('Config.handleUpdateTeams');
|
||||
log.silly('Config.handleUpdateTeams', newTeams);
|
||||
|
||||
Config.setServers(newTeams);
|
||||
return Config.teams;
|
||||
}
|
||||
|
||||
export function handleConfigUpdate(newConfig: CombinedConfig) {
|
||||
if (newConfig.logLevel) {
|
||||
setLoggingLevel(newConfig.logLevel);
|
||||
|
@@ -59,6 +59,9 @@ jest.mock('electron', () => ({
|
||||
removeHandler: jest.fn(),
|
||||
removeListener: jest.fn(),
|
||||
},
|
||||
nativeTheme: {
|
||||
on: jest.fn(),
|
||||
},
|
||||
screen: {
|
||||
on: jest.fn(),
|
||||
},
|
||||
@@ -111,6 +114,7 @@ jest.mock('main/allowProtocolDialog', () => ({
|
||||
jest.mock('main/app/app', () => ({}));
|
||||
jest.mock('main/app/config', () => ({
|
||||
handleConfigUpdate: jest.fn(),
|
||||
handleUpdateTheme: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/app/intercom', () => ({
|
||||
handleMainWindowIsShown: jest.fn(),
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import {app, ipcMain, session} from 'electron';
|
||||
import {app, ipcMain, nativeTheme, session} from 'electron';
|
||||
import installExtension, {REACT_DEVELOPER_TOOLS} from 'electron-devtools-installer';
|
||||
import isDev from 'electron-is-dev';
|
||||
|
||||
@@ -35,6 +35,11 @@ import {
|
||||
PING_DOMAIN,
|
||||
MAIN_WINDOW_SHOWN,
|
||||
OPEN_APP_MENU,
|
||||
GET_CONFIGURATION,
|
||||
GET_LOCAL_CONFIGURATION,
|
||||
UPDATE_CONFIGURATION,
|
||||
UPDATE_PATHS,
|
||||
UPDATE_TEAMS,
|
||||
} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
import {Logger} from 'common/log';
|
||||
@@ -47,7 +52,7 @@ import AutoLauncher from 'main/AutoLauncher';
|
||||
import updateManager from 'main/autoUpdater';
|
||||
import {setupBadge} from 'main/badge';
|
||||
import CertificateManager from 'main/certificateManager';
|
||||
import {updatePaths} from 'main/constants';
|
||||
import {configPath, updatePaths} from 'main/constants';
|
||||
import CriticalErrorHandler from 'main/CriticalErrorHandler';
|
||||
import downloadsManager from 'main/downloadsManager';
|
||||
import i18nManager from 'main/i18nManager';
|
||||
@@ -71,7 +76,15 @@ import {
|
||||
handleAppWindowAllClosed,
|
||||
handleChildProcessGone,
|
||||
} from './app';
|
||||
import {handleConfigUpdate, handleDarkModeChange} from './config';
|
||||
import {
|
||||
handleConfigUpdate,
|
||||
handleDarkModeChange,
|
||||
handleGetConfiguration,
|
||||
handleGetLocalConfiguration,
|
||||
handleUpdateTheme,
|
||||
updateConfiguration,
|
||||
handleUpdateTeams,
|
||||
} from './config';
|
||||
import {
|
||||
handleMainWindowIsShown,
|
||||
handleAppVersion,
|
||||
@@ -177,7 +190,15 @@ async function initializeConfig() {
|
||||
|
||||
resolve();
|
||||
});
|
||||
Config.init();
|
||||
Config.init(configPath, app.name, app.getAppPath());
|
||||
ipcMain.on(UPDATE_PATHS, () => {
|
||||
log.debug('Config.UPDATE_PATHS');
|
||||
|
||||
Config.setConfigPath(configPath);
|
||||
if (Config.data) {
|
||||
Config.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -232,6 +253,11 @@ function initializeBeforeAppReady() {
|
||||
} else if (mainProtocol) {
|
||||
app.setAsDefaultProtocolClient(mainProtocol);
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin' || process.platform === 'win32') {
|
||||
nativeTheme.on('updated', handleUpdateTheme);
|
||||
handleUpdateTheme();
|
||||
}
|
||||
}
|
||||
|
||||
function initializeInterCommunicationEventListeners() {
|
||||
@@ -269,6 +295,10 @@ function initializeInterCommunicationEventListeners() {
|
||||
ipcMain.on(START_UPDATE_DOWNLOAD, handleStartDownload);
|
||||
ipcMain.on(START_UPGRADE, handleStartUpgrade);
|
||||
ipcMain.handle(PING_DOMAIN, handlePingDomain);
|
||||
ipcMain.handle(GET_CONFIGURATION, handleGetConfiguration);
|
||||
ipcMain.handle(GET_LOCAL_CONFIGURATION, handleGetLocalConfiguration);
|
||||
ipcMain.handle(UPDATE_TEAMS, handleUpdateTeams);
|
||||
ipcMain.on(UPDATE_CONFIGURATION, updateConfiguration);
|
||||
}
|
||||
|
||||
function initializeAfterAppReady() {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import Config from 'common/config';
|
||||
import {getDefaultTeamWithTabsFromTeam} from 'common/tabs/TabView';
|
||||
import {getDefaultConfigTeamFromTeam} from 'common/tabs/TabView';
|
||||
|
||||
import {getLocalURLString, getLocalPreload} from 'main/utils';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
@@ -20,10 +20,10 @@ import {
|
||||
} from './intercom';
|
||||
|
||||
jest.mock('common/config', () => ({
|
||||
set: jest.fn(),
|
||||
setServers: jest.fn(),
|
||||
}));
|
||||
jest.mock('common/tabs/TabView', () => ({
|
||||
getDefaultTeamWithTabsFromTeam: jest.fn(),
|
||||
getDefaultConfigTeamFromTeam: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/notifications', () => ({}));
|
||||
jest.mock('main/utils', () => ({
|
||||
@@ -75,8 +75,8 @@ const teams = [
|
||||
describe('main/app/intercom', () => {
|
||||
describe('handleCloseTab', () => {
|
||||
beforeEach(() => {
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
Config.teams = JSON.parse(JSON.stringify(teams));
|
||||
});
|
||||
@@ -94,8 +94,8 @@ describe('main/app/intercom', () => {
|
||||
|
||||
describe('handleOpenTab', () => {
|
||||
beforeEach(() => {
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
Config.teams = JSON.parse(JSON.stringify(teams));
|
||||
});
|
||||
@@ -117,12 +117,12 @@ describe('main/app/intercom', () => {
|
||||
getLocalPreload.mockReturnValue('/some/preload.js');
|
||||
MainWindow.get.mockReturnValue({});
|
||||
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
Config.teams = JSON.parse(JSON.stringify(teams));
|
||||
|
||||
getDefaultTeamWithTabsFromTeam.mockImplementation((team) => ({
|
||||
getDefaultConfigTeamFromTeam.mockImplementation((team) => ({
|
||||
...team,
|
||||
tabs,
|
||||
}));
|
||||
@@ -156,8 +156,8 @@ describe('main/app/intercom', () => {
|
||||
getLocalPreload.mockReturnValue('/some/preload.js');
|
||||
MainWindow.get.mockReturnValue({});
|
||||
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
Config.teams = JSON.parse(JSON.stringify(teams));
|
||||
});
|
||||
@@ -199,8 +199,8 @@ describe('main/app/intercom', () => {
|
||||
getLocalPreload.mockReturnValue('/some/preload.js');
|
||||
MainWindow.get.mockReturnValue({});
|
||||
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
Config.teams = JSON.parse(JSON.stringify(teams));
|
||||
});
|
||||
@@ -248,8 +248,8 @@ describe('main/app/intercom', () => {
|
||||
getLocalPreload.mockReturnValue('/some/preload.js');
|
||||
MainWindow.get.mockReturnValue({});
|
||||
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
Config.teams = JSON.parse(JSON.stringify([]));
|
||||
});
|
||||
@@ -271,8 +271,8 @@ describe('main/app/intercom', () => {
|
||||
isVisible: () => true,
|
||||
});
|
||||
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
Config.registryConfigData = {
|
||||
teams: JSON.parse(JSON.stringify([{
|
||||
@@ -281,6 +281,7 @@ describe('main/app/intercom', () => {
|
||||
url: 'https://someurl.here',
|
||||
}])),
|
||||
};
|
||||
Config.teams = JSON.parse(JSON.stringify(teams));
|
||||
|
||||
handleMainWindowIsShown();
|
||||
expect(ModalManager.addModal).not.toHaveBeenCalled();
|
||||
|
@@ -8,7 +8,7 @@ import {MentionData} from 'types/notification';
|
||||
|
||||
import Config from 'common/config';
|
||||
import {Logger} from 'common/log';
|
||||
import {getDefaultTeamWithTabsFromTeam} from 'common/tabs/TabView';
|
||||
import {getDefaultConfigTeamFromTeam} from 'common/tabs/TabView';
|
||||
import {ping} from 'common/utils/requests';
|
||||
|
||||
import {displayMention} from 'main/notifications';
|
||||
@@ -69,7 +69,7 @@ export function handleCloseTab(event: IpcMainEvent, serverName: string, tabName:
|
||||
});
|
||||
const nextTab = teams.find((team) => team.name === serverName)!.tabs.filter((tab) => tab.isOpen)[0].name;
|
||||
WindowManager.switchTab(serverName, nextTab);
|
||||
Config.set('teams', teams);
|
||||
Config.setServers(teams);
|
||||
}
|
||||
|
||||
export function handleOpenTab(event: IpcMainEvent, serverName: string, tabName: string) {
|
||||
@@ -86,7 +86,7 @@ export function handleOpenTab(event: IpcMainEvent, serverName: string, tabName:
|
||||
}
|
||||
});
|
||||
WindowManager.switchTab(serverName, tabName);
|
||||
Config.set('teams', teams);
|
||||
Config.setServers(teams);
|
||||
}
|
||||
|
||||
export function handleShowOnboardingScreens(showWelcomeScreen: boolean, showNewServerModal: boolean, mainWindowIsVisible: boolean) {
|
||||
@@ -153,9 +153,9 @@ export function handleNewServerModal() {
|
||||
modalPromise.then((data) => {
|
||||
const teams = Config.teams;
|
||||
const order = teams.length;
|
||||
const newTeam = getDefaultTeamWithTabsFromTeam({...data, order});
|
||||
const newTeam = getDefaultConfigTeamFromTeam({...data, order});
|
||||
teams.push(newTeam);
|
||||
Config.set('teams', teams);
|
||||
Config.setServers(teams);
|
||||
updateServerInfos([newTeam]);
|
||||
WindowManager.switchServer(newTeam.name, true);
|
||||
}).catch((e) => {
|
||||
@@ -198,7 +198,7 @@ export function handleEditServerModal(e: IpcMainEvent, name: string) {
|
||||
const teams = Config.teams;
|
||||
teams[serverIndex].name = data.name;
|
||||
teams[serverIndex].url = data.url;
|
||||
Config.set('teams', teams);
|
||||
Config.setServers(teams);
|
||||
updateServerInfos([teams[serverIndex]]);
|
||||
}).catch((e) => {
|
||||
// e is undefined for user cancellation
|
||||
@@ -238,7 +238,7 @@ export function handleRemoveServerModal(e: IpcMainEvent, name: string) {
|
||||
value.order--;
|
||||
}
|
||||
});
|
||||
Config.set('teams', teams);
|
||||
Config.setServers(teams);
|
||||
}
|
||||
}).catch((e) => {
|
||||
// e is undefined for user cancellation
|
||||
@@ -267,9 +267,9 @@ export function handleWelcomeScreenModal() {
|
||||
modalPromise.then((data) => {
|
||||
const teams = Config.teams;
|
||||
const order = teams.length;
|
||||
const newTeam = getDefaultTeamWithTabsFromTeam({...data, order});
|
||||
const newTeam = getDefaultConfigTeamFromTeam({...data, order});
|
||||
teams.push(newTeam);
|
||||
Config.set('teams', teams);
|
||||
Config.setServers(teams);
|
||||
updateServerInfos([newTeam]);
|
||||
WindowManager.switchServer(newTeam.name, true);
|
||||
}).catch((e) => {
|
||||
@@ -324,10 +324,7 @@ export function handleUpdateLastActive(event: IpcMainEvent, serverName: string,
|
||||
team.lastActiveTab = viewOrder;
|
||||
}
|
||||
});
|
||||
Config.setMultiple({
|
||||
teams,
|
||||
lastActiveTeam: teams.find((team) => team.name === serverName)?.order || 0,
|
||||
});
|
||||
Config.setServers(teams, teams.find((team) => team.name === serverName)?.order || 0);
|
||||
}
|
||||
|
||||
export function handlePingDomain(event: IpcMainInvokeEvent, url: string): Promise<string> {
|
||||
|
@@ -40,7 +40,7 @@ jest.mock('electron', () => ({
|
||||
}));
|
||||
|
||||
jest.mock('common/config', () => ({
|
||||
set: jest.fn(),
|
||||
setServers: jest.fn(),
|
||||
}));
|
||||
jest.mock('common/JsonFileManager');
|
||||
jest.mock('common/utils/util', () => ({
|
||||
@@ -95,8 +95,8 @@ describe('main/app/utils', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
Utils.isVersionGreaterThanOrEqualTo.mockImplementation((version) => version === '6.0.0');
|
||||
Config.set.mockImplementation((name, value) => {
|
||||
Config[name] = value;
|
||||
Config.setServers.mockImplementation((value) => {
|
||||
Config.teams = value;
|
||||
});
|
||||
const teamsCopy = JSON.parse(JSON.stringify(teams));
|
||||
Config.teams = teamsCopy;
|
||||
|
@@ -47,8 +47,8 @@ export function openDeepLink(deeplinkingUrl: string) {
|
||||
}
|
||||
|
||||
export function updateSpellCheckerLocales() {
|
||||
if (Config.data?.spellCheckerLocales.length && app.isReady()) {
|
||||
session.defaultSession.setSpellCheckerLanguages(Config.data?.spellCheckerLocales);
|
||||
if (Config.spellCheckerLocales.length && app.isReady()) {
|
||||
session.defaultSession.setSpellCheckerLanguages(Config.spellCheckerLocales);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ export function updateServerInfos(teams: TeamWithTabs[]) {
|
||||
hasUpdates = hasUpdates || openExtraTabs(data, team);
|
||||
});
|
||||
if (hasUpdates) {
|
||||
Config.set('teams', teams);
|
||||
Config.setServers(teams);
|
||||
}
|
||||
}).catch((reason: any) => {
|
||||
log.error('Error getting server infos', reason);
|
||||
|
@@ -8,6 +8,8 @@ import {DiagnosticStepResponse} from 'types/diagnostics';
|
||||
import Config from 'common/config';
|
||||
import * as Validator from 'common/Validator';
|
||||
|
||||
import {configPath} from 'main/constants';
|
||||
|
||||
import DiagnosticsStep from '../DiagnosticStep';
|
||||
|
||||
const stepName = 'Step-2';
|
||||
@@ -15,13 +17,13 @@ const stepDescriptiveName = 'configValidation';
|
||||
|
||||
const run = async (logger: ElectronLog): Promise<DiagnosticStepResponse> => {
|
||||
try {
|
||||
const configData = JSON.parse(fs.readFileSync(Config.configFilePath, 'utf8'));
|
||||
const configData = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
|
||||
// validate based on config file version
|
||||
const validData = Validator.validateConfigData(configData);
|
||||
|
||||
if (!validData) {
|
||||
throw new Error(`Config validation failed. Config: ${JSON.stringify(Config.combinedData, null, 4)}`);
|
||||
throw new Error(`Config validation failed. Config: ${JSON.stringify(Config.data, null, 4)}`);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -15,7 +15,7 @@ const stepDescriptiveName = 'serverConnectivity';
|
||||
|
||||
const run = async (logger: ElectronLog): Promise<DiagnosticStepResponse> => {
|
||||
try {
|
||||
const teams = Config.combinedData?.teams || [];
|
||||
const teams = Config.teams || [];
|
||||
|
||||
await Promise.all(teams.map(async (team) => {
|
||||
logger.debug('Pinging server: ', team.url);
|
||||
|
@@ -65,55 +65,53 @@ jest.mock('common/tabs/TabView', () => ({
|
||||
|
||||
describe('main/menus/app', () => {
|
||||
const config = {
|
||||
data: {
|
||||
enableServerManagement: true,
|
||||
teams: [{
|
||||
name: 'example',
|
||||
url: 'http://example.com',
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
order: 0,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_FOCALBOARD',
|
||||
order: 1,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_PLAYBOOKS',
|
||||
order: 2,
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}, {
|
||||
name: 'github',
|
||||
url: 'https://github.com/',
|
||||
order: 1,
|
||||
tabs: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
order: 0,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_FOCALBOARD',
|
||||
order: 1,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_PLAYBOOKS',
|
||||
order: 2,
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}],
|
||||
helpLink: 'http://link-to-help.site.com',
|
||||
},
|
||||
enableServerManagement: true,
|
||||
teams: [{
|
||||
name: 'example',
|
||||
url: 'http://example.com',
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
order: 0,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_FOCALBOARD',
|
||||
order: 1,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_PLAYBOOKS',
|
||||
order: 2,
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}, {
|
||||
name: 'github',
|
||||
url: 'https://github.com/',
|
||||
order: 1,
|
||||
tabs: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
order: 0,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_FOCALBOARD',
|
||||
order: 1,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_PLAYBOOKS',
|
||||
order: 2,
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}],
|
||||
helpLink: 'http://link-to-help.site.com',
|
||||
};
|
||||
beforeEach(() => {
|
||||
getDarwinDoNotDisturb.mockReturnValue(false);
|
||||
@@ -218,7 +216,7 @@ describe('main/menus/app', () => {
|
||||
const menu = createTemplate(modifiedConfig);
|
||||
const fileMenu = menu.find((item) => item.label === '&AppName' || item.label === '&File');
|
||||
const signInOption = fileMenu.submenu.find((item) => item.label === 'Sign in to Another Server');
|
||||
expect(signInOption).not.toBe(undefined);
|
||||
expect(signInOption).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should not show `Sign in to Another Server` if no teams are configured', () => {
|
||||
@@ -239,7 +237,7 @@ describe('main/menus/app', () => {
|
||||
const menu = createTemplate(modifiedConfig);
|
||||
const fileMenu = menu.find((item) => item.label === '&AppName' || item.label === '&File');
|
||||
const signInOption = fileMenu.submenu.find((item) => item.label === 'Sign in to Another Server');
|
||||
expect(signInOption).not.toBe(undefined);
|
||||
expect(signInOption).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should show the first 9 servers (using order) in the Window menu', () => {
|
||||
@@ -250,21 +248,18 @@ describe('main/menus/app', () => {
|
||||
return id;
|
||||
});
|
||||
const modifiedConfig = {
|
||||
data: {
|
||||
...config.data,
|
||||
teams: [...Array(15).keys()].map((key) => ({
|
||||
name: `server-${key}`,
|
||||
url: `http://server-${key}.com`,
|
||||
order: (key + 5) % 15,
|
||||
lastActiveTab: 0,
|
||||
tab: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
})),
|
||||
},
|
||||
teams: [...Array(15).keys()].map((key) => ({
|
||||
name: `server-${key}`,
|
||||
url: `http://server-${key}.com`,
|
||||
order: (key + 5) % 15,
|
||||
lastActiveTab: 0,
|
||||
tab: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
})),
|
||||
};
|
||||
const menu = createTemplate(modifiedConfig);
|
||||
const windowMenu = menu.find((item) => item.label === '&Window');
|
||||
@@ -292,22 +287,19 @@ describe('main/menus/app', () => {
|
||||
}
|
||||
return id;
|
||||
});
|
||||
WindowManager.getCurrentTeamName.mockImplementation(() => config.data.teams[0].name);
|
||||
WindowManager.getCurrentTeamName.mockImplementation(() => config.teams[0].name);
|
||||
|
||||
const modifiedConfig = {
|
||||
data: {
|
||||
...config.data,
|
||||
teams: [
|
||||
{
|
||||
...config.data.teams[0],
|
||||
tabs: [...Array(15).keys()].map((key) => ({
|
||||
name: `tab-${key}`,
|
||||
isOpen: true,
|
||||
order: (key + 5) % 15,
|
||||
})),
|
||||
},
|
||||
],
|
||||
},
|
||||
teams: [
|
||||
{
|
||||
...config.teams[0],
|
||||
tabs: [...Array(15).keys()].map((key) => ({
|
||||
name: `tab-${key}`,
|
||||
isOpen: true,
|
||||
order: (key + 5) % 15,
|
||||
})),
|
||||
},
|
||||
],
|
||||
};
|
||||
const menu = createTemplate(modifiedConfig);
|
||||
const windowMenu = menu.find((item) => item.label === '&Window');
|
||||
|
@@ -49,7 +49,7 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
|
||||
},
|
||||
});
|
||||
|
||||
if (config.data?.enableServerManagement === true && config.data?.teams.length > 0) {
|
||||
if (config.enableServerManagement === true && config.teams.length > 0) {
|
||||
platformAppMenu.push({
|
||||
label: localizeMessage('main.menus.app.file.signInToAnotherServer', 'Sign in to Another Server'),
|
||||
click() {
|
||||
@@ -203,7 +203,7 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
|
||||
viewSubMenu.push({
|
||||
label: localizeMessage('main.menus.app.view.toggleDarkMode', 'Toggle Dark Mode'),
|
||||
click() {
|
||||
config.toggleDarkModeManually();
|
||||
config.set('darkMode', !config.darkMode);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -231,7 +231,7 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
|
||||
}],
|
||||
});
|
||||
|
||||
const teams = config.data?.teams || [];
|
||||
const teams = config.teams || [];
|
||||
const windowMenu = {
|
||||
id: 'window',
|
||||
label: localizeMessage('main.menus.app.window', '&Window'),
|
||||
@@ -251,7 +251,7 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
|
||||
label: isMac ? localizeMessage('main.menus.app.window.closeWindow', 'Close Window') : localizeMessage('main.menus.app.window.close', 'Close'),
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
}, separatorItem,
|
||||
...(config.data?.teams.length ? [{
|
||||
...(config.teams.length ? [{
|
||||
label: localizeMessage('main.menus.app.window.showServers', 'Show Servers'),
|
||||
accelerator: `${process.platform === 'darwin' ? 'Cmd+Ctrl' : 'Ctrl+Shift'}+S`,
|
||||
click() {
|
||||
@@ -325,11 +325,11 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
|
||||
});
|
||||
}
|
||||
}
|
||||
if (config.data?.helpLink) {
|
||||
if (config.helpLink) {
|
||||
submenu.push({
|
||||
label: localizeMessage('main.menus.app.help.learnMore', 'Learn More...'),
|
||||
click() {
|
||||
shell.openExternal(config.data!.helpLink);
|
||||
shell.openExternal(config.helpLink!);
|
||||
},
|
||||
});
|
||||
submenu.push(separatorItem);
|
||||
|
@@ -19,6 +19,7 @@ import {
|
||||
UPDATE_DOWNLOADS_DROPDOWN_MENU_ITEM,
|
||||
} from 'common/communication';
|
||||
import {Logger} from 'common/log';
|
||||
import Config from 'common/config';
|
||||
import {
|
||||
DOWNLOADS_DROPDOWN_FULL_WIDTH,
|
||||
DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT,
|
||||
@@ -26,10 +27,9 @@ import {
|
||||
TAB_BAR_HEIGHT,
|
||||
} from 'common/utils/constants';
|
||||
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||
|
||||
import WindowManager from '../windows/windowManager';
|
||||
import downloadsManager from 'main/downloadsManager';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
import WindowManager from 'main/windows/windowManager';
|
||||
|
||||
const log = new Logger('DownloadsDropdownMenuView');
|
||||
|
||||
@@ -42,11 +42,11 @@ export default class DownloadsDropdownMenuView {
|
||||
darkMode: boolean;
|
||||
windowBounds: Electron.Rectangle;
|
||||
|
||||
constructor(darkMode: boolean) {
|
||||
constructor() {
|
||||
this.open = false;
|
||||
this.item = undefined;
|
||||
this.coordinates = undefined;
|
||||
this.darkMode = darkMode;
|
||||
this.darkMode = Config.darkMode;
|
||||
|
||||
ipcMain.on(OPEN_DOWNLOADS_DROPDOWN_MENU, this.handleOpen);
|
||||
ipcMain.on(CLOSE_DOWNLOADS_DROPDOWN_MENU, this.handleClose);
|
||||
|
@@ -62,6 +62,7 @@ jest.mock('electron', () => {
|
||||
};
|
||||
});
|
||||
jest.mock('main/downloadsManager', () => ({
|
||||
getDownloads: jest.fn(),
|
||||
onOpen: jest.fn(),
|
||||
onClose: jest.fn(),
|
||||
}));
|
||||
|
@@ -19,11 +19,12 @@ import {
|
||||
DOWNLOADS_DROPDOWN_OPEN_FILE,
|
||||
} from 'common/communication';
|
||||
import {Logger} from 'common/log';
|
||||
import Config from 'common/config';
|
||||
import {TAB_BAR_HEIGHT, DOWNLOADS_DROPDOWN_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT, DOWNLOADS_DROPDOWN_FULL_WIDTH} from 'common/utils/constants';
|
||||
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||
|
||||
import WindowManager from '../windows/windowManager';
|
||||
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||
import downloadsManager from 'main/downloadsManager';
|
||||
import WindowManager from 'main/windows/windowManager';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
const log = new Logger('DownloadsDropdownView');
|
||||
@@ -36,9 +37,9 @@ export default class DownloadsDropdownView {
|
||||
view: BrowserView;
|
||||
windowBounds: Electron.Rectangle;
|
||||
|
||||
constructor(downloads: DownloadedItems, darkMode: boolean) {
|
||||
this.downloads = downloads;
|
||||
this.darkMode = darkMode;
|
||||
constructor() {
|
||||
this.downloads = downloadsManager.getDownloads();
|
||||
this.darkMode = Config.darkMode;
|
||||
|
||||
ipcMain.on(OPEN_DOWNLOADS_DROPDOWN, this.handleOpen);
|
||||
ipcMain.on(CLOSE_DOWNLOADS_DROPDOWN, this.handleClose);
|
||||
|
@@ -15,10 +15,6 @@ jest.mock('electron', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('common/config', () => ({
|
||||
teams: [],
|
||||
}));
|
||||
|
||||
jest.mock('main/views/webContentEvents', () => ({
|
||||
addWebContentsEventListeners: jest.fn(),
|
||||
}));
|
||||
|
@@ -17,7 +17,6 @@ import {
|
||||
GET_MODAL_UNCLOSEABLE,
|
||||
RESIZE_MODAL,
|
||||
} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
import {Logger} from 'common/log';
|
||||
|
||||
import {getAdjustedWindowBoundaries} from 'main/utils';
|
||||
@@ -91,7 +90,7 @@ export class ModalManager {
|
||||
if (index === 0) {
|
||||
WindowManager.sendToRenderer(MODAL_OPEN);
|
||||
modal.show(undefined, Boolean(withDevTools));
|
||||
WebContentsEventManager.addWebContentsEventListeners(modal.view.webContents, () => Config.teams.concat());
|
||||
WebContentsEventManager.addWebContentsEventListeners(modal.view.webContents);
|
||||
} else {
|
||||
WindowManager.sendToRenderer(MODAL_CLOSE);
|
||||
modal.hide();
|
||||
|
@@ -42,7 +42,7 @@ describe('main/views/teamDropdownView', () => {
|
||||
MainWindow.getBounds.mockReturnValue({width: 500, height: 400, x: 0, y: 0});
|
||||
});
|
||||
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
const teamDropdownView = new TeamDropdownView();
|
||||
if (process.platform === 'darwin') {
|
||||
it('should account for three dot menu, tab bar and shadow', () => {
|
||||
expect(teamDropdownView.getBounds(400, 300)).toStrictEqual({x: THREE_DOT_MENU_WIDTH_MAC - MENU_SHADOW_WIDTH, y: TAB_BAR_HEIGHT - MENU_SHADOW_WIDTH, width: 400, height: 300});
|
||||
@@ -55,7 +55,7 @@ describe('main/views/teamDropdownView', () => {
|
||||
});
|
||||
|
||||
it('should change the view bounds based on open/closed state', () => {
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
const teamDropdownView = new TeamDropdownView();
|
||||
teamDropdownView.bounds = {width: 400, height: 300};
|
||||
teamDropdownView.handleOpen();
|
||||
expect(teamDropdownView.view.setBounds).toBeCalledWith(teamDropdownView.bounds);
|
||||
@@ -65,7 +65,7 @@ describe('main/views/teamDropdownView', () => {
|
||||
|
||||
describe('addGpoToTeams', () => {
|
||||
it('should return teams with "isGPO": false when no config.registryTeams exist', () => {
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
const teamDropdownView = new TeamDropdownView();
|
||||
const teams = [{
|
||||
name: 'team-1',
|
||||
url: 'https://mattermost.team-1.com',
|
||||
@@ -86,7 +86,7 @@ describe('main/views/teamDropdownView', () => {
|
||||
}]);
|
||||
});
|
||||
it('should return teams with "isGPO": true if they exist in config.registryTeams', () => {
|
||||
const teamDropdownView = new TeamDropdownView([], false, true);
|
||||
const teamDropdownView = new TeamDropdownView();
|
||||
const teams = [{
|
||||
name: 'team-1',
|
||||
url: 'https://mattermost.team-1.com',
|
||||
|
@@ -15,9 +15,12 @@ import {
|
||||
RECEIVE_DROPDOWN_MENU_SIZE,
|
||||
SET_ACTIVE_VIEW,
|
||||
} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
import {Logger} from 'common/log';
|
||||
import {TAB_BAR_HEIGHT, THREE_DOT_MENU_WIDTH, THREE_DOT_MENU_WIDTH_MAC, MENU_SHADOW_WIDTH} from 'common/utils/constants';
|
||||
|
||||
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||
|
||||
import * as AppState from '../appState';
|
||||
import WindowManager from '../windows/windowManager';
|
||||
import MainWindow from '../windows/mainWindow';
|
||||
@@ -38,10 +41,10 @@ export default class TeamDropdownView {
|
||||
windowBounds?: Electron.Rectangle;
|
||||
isOpen: boolean;
|
||||
|
||||
constructor(teams: TeamWithTabs[], darkMode: boolean, enableServerManagement: boolean) {
|
||||
this.teams = this.addGpoToTeams(teams, []);
|
||||
this.darkMode = darkMode;
|
||||
this.enableServerManagement = enableServerManagement;
|
||||
constructor() {
|
||||
this.teams = this.addGpoToTeams(Config.teams, []);
|
||||
this.darkMode = Config.darkMode;
|
||||
this.enableServerManagement = Config.enableServerManagement;
|
||||
this.isOpen = false;
|
||||
|
||||
this.windowBounds = MainWindow.getBounds();
|
||||
|
@@ -36,7 +36,6 @@ import {SECOND} from 'common/utils/constants';
|
||||
import Config from 'common/config';
|
||||
import {getTabViewName} from 'common/tabs/TabView';
|
||||
|
||||
import downloadsManager from 'main/downloadsManager';
|
||||
import {MattermostView} from 'main/views/MattermostView';
|
||||
|
||||
import {
|
||||
@@ -208,9 +207,9 @@ export class WindowManager {
|
||||
mainWindow.on('enter-full-screen', () => this.sendToRenderer('enter-full-screen'));
|
||||
mainWindow.on('leave-full-screen', () => this.sendToRenderer('leave-full-screen'));
|
||||
|
||||
this.teamDropdown = new TeamDropdownView(Config.teams, Config.darkMode, Config.enableServerManagement);
|
||||
this.downloadsDropdown = new DownloadsDropdownView(downloadsManager.getDownloads(), Config.darkMode);
|
||||
this.downloadsDropdownMenu = new DownloadsDropdownMenuView(Config.darkMode);
|
||||
this.teamDropdown = new TeamDropdownView();
|
||||
this.downloadsDropdown = new DownloadsDropdownView();
|
||||
this.downloadsDropdownMenu = new DownloadsDropdownMenuView();
|
||||
|
||||
this.initializeViewManager();
|
||||
}
|
||||
|
Reference in New Issue
Block a user