[MM-41999] Add additional logging for debugging, allow users to change log level (#2031)
* Add debug logging switch * Add tests * Mock electron-log globally in jest * New logs for debugging * Switch to a dropdown to choose log levels * Fix tests * Update wording
This commit is contained in:
@@ -49,10 +49,6 @@ jest.mock('winreg-utf8', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('common/config/RegistryConfig', () => {
|
describe('common/config/RegistryConfig', () => {
|
||||||
it('should initialize correctly', async () => {
|
it('should initialize correctly', async () => {
|
||||||
const originalPlatform = process.platform;
|
const originalPlatform = process.platform;
|
||||||
|
@@ -26,12 +26,6 @@ jest.mock('main/Validator', () => ({
|
|||||||
validateV3ConfigData: (configData) => (configData.version === 3 ? configData : null),
|
validateV3ConfigData: (configData) => (configData.version === 3 ? configData : null),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
warn: jest.fn(),
|
|
||||||
info: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('common/tabs/TabView', () => ({
|
jest.mock('common/tabs/TabView', () => ({
|
||||||
getDefaultTeamWithTabsFromTeam: (value) => ({
|
getDefaultTeamWithTabsFromTeam: (value) => ({
|
||||||
...value,
|
...value,
|
||||||
|
@@ -112,6 +112,8 @@ export class Config extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
loadRegistry = (registryData: Partial<RegistryConfigType>): void => {
|
loadRegistry = (registryData: Partial<RegistryConfigType>): void => {
|
||||||
|
log.verbose('Config.loadRegistry', {registryData});
|
||||||
|
|
||||||
this.registryConfigData = registryData;
|
this.registryConfigData = registryData;
|
||||||
if (this.registryConfigData.teams) {
|
if (this.registryConfigData.teams) {
|
||||||
this.predefinedTeams.push(...this.registryConfigData.teams.map((team) => getDefaultTeamWithTabsFromTeam(team)));
|
this.predefinedTeams.push(...this.registryConfigData.teams.map((team) => getDefaultTeamWithTabsFromTeam(team)));
|
||||||
@@ -161,6 +163,8 @@ export class Config extends EventEmitter {
|
|||||||
* @param {array} properties an array of config properties to save
|
* @param {array} properties an array of config properties to save
|
||||||
*/
|
*/
|
||||||
setMultiple = (event: Electron.IpcMainEvent, properties: Array<{key: keyof ConfigType; data: ConfigType[keyof ConfigType]}> = []): Partial<ConfigType> | undefined => {
|
setMultiple = (event: Electron.IpcMainEvent, properties: Array<{key: keyof ConfigType; data: ConfigType[keyof ConfigType]}> = []): Partial<ConfigType> | undefined => {
|
||||||
|
log.debug('Config.setMultiple', properties);
|
||||||
|
|
||||||
if (properties.length) {
|
if (properties.length) {
|
||||||
this.localConfigData = Object.assign({}, this.localConfigData, ...properties.map(({key, data}) => ({[key]: data})));
|
this.localConfigData = Object.assign({}, this.localConfigData, ...properties.map(({key, data}) => ({[key]: data})));
|
||||||
this.regenerateCombinedConfigData();
|
this.regenerateCombinedConfigData();
|
||||||
@@ -550,6 +554,8 @@ export class Config extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleGetConfiguration = (event: Electron.IpcMainInvokeEvent, option: keyof CombinedConfig) => {
|
handleGetConfiguration = (event: Electron.IpcMainInvokeEvent, option: keyof CombinedConfig) => {
|
||||||
|
log.debug('Config.handleGetConfiguration', option);
|
||||||
|
|
||||||
const config = {...this.combinedData};
|
const config = {...this.combinedData};
|
||||||
if (option) {
|
if (option) {
|
||||||
return config[option];
|
return config[option];
|
||||||
@@ -558,6 +564,8 @@ export class Config extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleGetLocalConfiguration = (event: Electron.IpcMainInvokeEvent, option: keyof ConfigType) => {
|
handleGetLocalConfiguration = (event: Electron.IpcMainInvokeEvent, option: keyof ConfigType) => {
|
||||||
|
log.debug('Config.handleGetLocalConfiguration', option);
|
||||||
|
|
||||||
const config: Partial<LocalConfiguration> = {...this.localConfigData};
|
const config: Partial<LocalConfiguration> = {...this.localConfigData};
|
||||||
config.appName = app.name;
|
config.appName = app.name;
|
||||||
config.enableServerManagement = this.combinedData?.enableServerManagement;
|
config.enableServerManagement = this.combinedData?.enableServerManagement;
|
||||||
@@ -569,6 +577,9 @@ export class Config extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleUpdateTeams = (event: Electron.IpcMainInvokeEvent, newTeams: TeamWithTabs[]) => {
|
handleUpdateTeams = (event: Electron.IpcMainInvokeEvent, newTeams: TeamWithTabs[]) => {
|
||||||
|
log.debug('Config.handleUpdateTeams');
|
||||||
|
log.silly('Config.handleUpdateTeams', newTeams);
|
||||||
|
|
||||||
this.set('teams', newTeams);
|
this.set('teams', newTeams);
|
||||||
return this.combinedData!.teams;
|
return this.combinedData!.teams;
|
||||||
}
|
}
|
||||||
@@ -578,6 +589,8 @@ export class Config extends EventEmitter {
|
|||||||
* @emits 'darkModeChange'
|
* @emits 'darkModeChange'
|
||||||
*/
|
*/
|
||||||
handleUpdateTheme = () => {
|
handleUpdateTheme = () => {
|
||||||
|
log.debug('Config.handleUpdateTheme');
|
||||||
|
|
||||||
if (this.combinedData && this.combinedData.darkMode !== nativeTheme.shouldUseDarkColors) {
|
if (this.combinedData && this.combinedData.darkMode !== nativeTheme.shouldUseDarkColors) {
|
||||||
this.combinedData.darkMode = nativeTheme.shouldUseDarkColors;
|
this.combinedData.darkMode = nativeTheme.shouldUseDarkColors;
|
||||||
this.emit('darkModeChange', this.combinedData.darkMode);
|
this.emit('darkModeChange', this.combinedData.darkMode);
|
||||||
@@ -602,6 +615,8 @@ const config = new Config(configPath);
|
|||||||
export default config;
|
export default config;
|
||||||
|
|
||||||
ipcMain.on(UPDATE_PATHS, () => {
|
ipcMain.on(UPDATE_PATHS, () => {
|
||||||
|
log.debug('Config.UPDATE_PATHS');
|
||||||
|
|
||||||
config.configFilePath = configPath;
|
config.configFilePath = configPath;
|
||||||
if (config.combinedData) {
|
if (config.combinedData) {
|
||||||
config.reload();
|
config.reload();
|
||||||
|
@@ -11,3 +11,18 @@ jest.mock('main/constants', () => ({
|
|||||||
|
|
||||||
updatePaths: jest.fn(),
|
updatePaths: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('electron-log', () => ({
|
||||||
|
error: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
info: jest.fn(),
|
||||||
|
verbose: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
silly: jest.fn(),
|
||||||
|
transports: {
|
||||||
|
file: {
|
||||||
|
level: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
@@ -13,7 +13,6 @@ jest.mock('electron', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-is-dev', () => false);
|
jest.mock('electron-is-dev', () => false);
|
||||||
jest.mock('electron-log', () => ({}));
|
|
||||||
|
|
||||||
describe('main/AutoLauncher', () => {
|
describe('main/AutoLauncher', () => {
|
||||||
let autoLauncher;
|
let autoLauncher;
|
||||||
|
@@ -28,10 +28,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('fs', () => ({
|
jest.mock('fs', () => ({
|
||||||
writeFileSync: jest.fn(),
|
writeFileSync: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
@@ -5,10 +5,6 @@
|
|||||||
|
|
||||||
import * as Validator from './Validator';
|
import * as Validator from './Validator';
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('main/Validator', () => {
|
describe('main/Validator', () => {
|
||||||
describe('validateV0ConfigData', () => {
|
describe('validateV0ConfigData', () => {
|
||||||
const config = {url: 'http://server-1.com'};
|
const config = {url: 'http://server-1.com'};
|
||||||
@@ -132,6 +128,7 @@ describe('main/Validator', () => {
|
|||||||
enableHardwareAcceleration: true,
|
enableHardwareAcceleration: true,
|
||||||
startInFullscreen: false,
|
startInFullscreen: false,
|
||||||
lastActiveTeam: 0,
|
lastActiveTeam: 0,
|
||||||
|
logLevel: 'info',
|
||||||
minimizeToTray: false,
|
minimizeToTray: false,
|
||||||
showTrayIcon: false,
|
showTrayIcon: false,
|
||||||
showUnreadBadge: true,
|
showUnreadBadge: true,
|
||||||
|
@@ -130,6 +130,7 @@ const configDataSchemaV3 = Joi.object<ConfigV3>({
|
|||||||
autoCheckForUpdates: Joi.boolean().default(true),
|
autoCheckForUpdates: Joi.boolean().default(true),
|
||||||
alwaysMinimize: Joi.boolean(),
|
alwaysMinimize: Joi.boolean(),
|
||||||
alwaysClose: Joi.boolean(),
|
alwaysClose: Joi.boolean(),
|
||||||
|
logLevel: Joi.string().default('info'),
|
||||||
});
|
});
|
||||||
|
|
||||||
// eg. data['community.mattermost.com'] = { data: 'certificate data', issuerName: 'COMODO RSA Domain Validation Secure Server CA'};
|
// eg. data['community.mattermost.com'] = { data: 'certificate data', issuerName: 'COMODO RSA Domain Validation Secure Server CA'};
|
||||||
|
@@ -31,10 +31,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../../electron-builder.json', () => ({
|
jest.mock('../../electron-builder.json', () => ({
|
||||||
protocols: [{
|
protocols: [{
|
||||||
name: 'Mattermost',
|
name: 'Mattermost',
|
||||||
|
@@ -20,12 +20,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
warn: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('main/app/utils', () => ({
|
jest.mock('main/app/utils', () => ({
|
||||||
getDeeplinkingURL: jest.fn(),
|
getDeeplinkingURL: jest.fn(),
|
||||||
openDeepLink: jest.fn(),
|
openDeepLink: jest.fn(),
|
||||||
|
@@ -21,6 +21,8 @@ export const certificateErrorCallbacks = new Map();
|
|||||||
|
|
||||||
// activate first app instance, subsequent instances will quit themselves
|
// activate first app instance, subsequent instances will quit themselves
|
||||||
export function handleAppSecondInstance(event: Event, argv: string[]) {
|
export function handleAppSecondInstance(event: Event, argv: string[]) {
|
||||||
|
log.debug('App.handleAppSecondInstance', argv);
|
||||||
|
|
||||||
// Protocol handler for win32
|
// Protocol handler for win32
|
||||||
// argv: An array of the second instance’s (command line / deep linked) arguments
|
// argv: An array of the second instance’s (command line / deep linked) arguments
|
||||||
const deeplinkingUrl = getDeeplinkingURL(argv);
|
const deeplinkingUrl = getDeeplinkingURL(argv);
|
||||||
@@ -28,6 +30,8 @@ export function handleAppSecondInstance(event: Event, argv: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleAppWindowAllClosed() {
|
export function handleAppWindowAllClosed() {
|
||||||
|
log.debug('App.handleAppWindowAllClosed');
|
||||||
|
|
||||||
// On OS X it is common for applications and their menu bar
|
// On OS X it is common for applications and their menu bar
|
||||||
// to stay active until the user quits explicitly with Cmd + Q
|
// to stay active until the user quits explicitly with Cmd + Q
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
@@ -36,6 +40,8 @@ export function handleAppWindowAllClosed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleAppBrowserWindowCreated(event: Event, newWindow: BrowserWindow) {
|
export function handleAppBrowserWindowCreated(event: Event, newWindow: BrowserWindow) {
|
||||||
|
log.debug('App.handleAppBrowserWindowCreated');
|
||||||
|
|
||||||
// Screen cannot be required before app is ready
|
// Screen cannot be required before app is ready
|
||||||
resizeScreen(newWindow);
|
resizeScreen(newWindow);
|
||||||
}
|
}
|
||||||
@@ -57,6 +63,8 @@ export function handleAppWillFinishLaunching() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleAppBeforeQuit() {
|
export function handleAppBeforeQuit() {
|
||||||
|
log.debug('App.handleAppBeforeQuit');
|
||||||
|
|
||||||
// Make sure tray icon gets removed if the user exits via CTRL-Q
|
// Make sure tray icon gets removed if the user exits via CTRL-Q
|
||||||
destroyTray();
|
destroyTray();
|
||||||
global.willAppQuit = true;
|
global.willAppQuit = true;
|
||||||
@@ -64,6 +72,8 @@ export function handleAppBeforeQuit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function handleAppCertificateError(event: Event, webContents: WebContents, url: string, error: string, certificate: Certificate, callback: (isTrusted: boolean) => void) {
|
export async function handleAppCertificateError(event: Event, webContents: WebContents, url: string, error: string, certificate: Certificate, callback: (isTrusted: boolean) => void) {
|
||||||
|
log.verbose('App.handleAppCertificateError', {url, error, certificate});
|
||||||
|
|
||||||
const parsedURL = urlUtils.parseURL(url);
|
const parsedURL = urlUtils.parseURL(url);
|
||||||
if (!parsedURL) {
|
if (!parsedURL) {
|
||||||
return;
|
return;
|
||||||
|
@@ -8,6 +8,8 @@ import Config from 'common/config';
|
|||||||
|
|
||||||
import {handleConfigUpdate} from 'main/app/config';
|
import {handleConfigUpdate} from 'main/app/config';
|
||||||
import {addNewServerModalWhenMainWindowIsShown} from 'main/app/intercom';
|
import {addNewServerModalWhenMainWindowIsShown} from 'main/app/intercom';
|
||||||
|
import {setLoggingLevel} from 'main/app/utils';
|
||||||
|
|
||||||
import WindowManager from 'main/windows/windowManager';
|
import WindowManager from 'main/windows/windowManager';
|
||||||
import AutoLauncher from 'main/AutoLauncher';
|
import AutoLauncher from 'main/AutoLauncher';
|
||||||
|
|
||||||
@@ -22,15 +24,12 @@ jest.mock('electron', () => ({
|
|||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('main/app/utils', () => ({
|
jest.mock('main/app/utils', () => ({
|
||||||
handleUpdateMenuEvent: jest.fn(),
|
handleUpdateMenuEvent: jest.fn(),
|
||||||
updateSpellCheckerLocales: jest.fn(),
|
updateSpellCheckerLocales: jest.fn(),
|
||||||
updateServerInfos: jest.fn(),
|
updateServerInfos: jest.fn(),
|
||||||
|
setLoggingLevel: jest.fn(),
|
||||||
}));
|
}));
|
||||||
jest.mock('main/app/intercom', () => ({
|
jest.mock('main/app/intercom', () => ({
|
||||||
addNewServerModalWhenMainWindowIsShown: jest.fn(),
|
addNewServerModalWhenMainWindowIsShown: jest.fn(),
|
||||||
@@ -105,5 +104,12 @@ describe('main/app/config', () => {
|
|||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should set logging level correctly', () => {
|
||||||
|
handleConfigUpdate({logLevel: 'info'});
|
||||||
|
expect(setLoggingLevel).toBeCalledWith('info');
|
||||||
|
handleConfigUpdate({logLevel: 'debug'});
|
||||||
|
expect(setLoggingLevel).toBeCalledWith('debug');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {app, ipcMain} from 'electron';
|
import {app, ipcMain} from 'electron';
|
||||||
import log from 'electron-log';
|
import log, {LogLevel} from 'electron-log';
|
||||||
|
|
||||||
import {CombinedConfig} from 'types/config';
|
import {CombinedConfig} from 'types/config';
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ import {refreshTrayImages} from 'main/tray/tray';
|
|||||||
import WindowManager from 'main/windows/windowManager';
|
import WindowManager from 'main/windows/windowManager';
|
||||||
|
|
||||||
import {addNewServerModalWhenMainWindowIsShown} from './intercom';
|
import {addNewServerModalWhenMainWindowIsShown} from './intercom';
|
||||||
import {handleUpdateMenuEvent, updateServerInfos, updateSpellCheckerLocales} from './utils';
|
import {handleUpdateMenuEvent, setLoggingLevel, updateServerInfos, updateSpellCheckerLocales} from './utils';
|
||||||
|
|
||||||
let didCheckForAddServerModal = false;
|
let didCheckForAddServerModal = false;
|
||||||
|
|
||||||
@@ -24,6 +24,9 @@ let didCheckForAddServerModal = false;
|
|||||||
//
|
//
|
||||||
|
|
||||||
export function handleConfigUpdate(newConfig: CombinedConfig) {
|
export function handleConfigUpdate(newConfig: CombinedConfig) {
|
||||||
|
log.debug('App.Config.handleConfigUpdate');
|
||||||
|
log.silly('App.Config.handleConfigUpdate', newConfig);
|
||||||
|
|
||||||
if (!newConfig) {
|
if (!newConfig) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -62,11 +65,16 @@ export function handleConfigUpdate(newConfig: CombinedConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info('Log level set to:', newConfig.logLevel);
|
||||||
|
setLoggingLevel(newConfig.logLevel as LogLevel);
|
||||||
|
|
||||||
handleUpdateMenuEvent();
|
handleUpdateMenuEvent();
|
||||||
ipcMain.emit(EMIT_CONFIGURATION, true, newConfig);
|
ipcMain.emit(EMIT_CONFIGURATION, true, newConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleDarkModeChange(darkMode: boolean) {
|
export function handleDarkModeChange(darkMode: boolean) {
|
||||||
|
log.debug('App.Config.handleDarkModeChange', darkMode);
|
||||||
|
|
||||||
refreshTrayImages(Config.trayIconTheme);
|
refreshTrayImages(Config.trayIconTheme);
|
||||||
WindowManager.sendToRenderer(DARK_MODE_CHANGE, darkMode);
|
WindowManager.sendToRenderer(DARK_MODE_CHANGE, darkMode);
|
||||||
WindowManager.updateLoadingScreenDarkMode(darkMode);
|
WindowManager.updateLoadingScreenDarkMode(darkMode);
|
||||||
|
@@ -63,12 +63,6 @@ jest.mock('electron-devtools-installer', () => {
|
|||||||
const isDev = false;
|
const isDev = false;
|
||||||
jest.mock('electron-is-dev', () => isDev);
|
jest.mock('electron-is-dev', () => isDev);
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
warn: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../../../electron-builder.json', () => ([
|
jest.mock('../../../electron-builder.json', () => ([
|
||||||
{
|
{
|
||||||
name: 'Mattermost',
|
name: 'Mattermost',
|
||||||
@@ -245,7 +239,7 @@ describe('main/app/initialize', () => {
|
|||||||
path.resolve.mockImplementation((base, p) => `${base}/${p}`);
|
path.resolve.mockImplementation((base, p) => `${base}/${p}`);
|
||||||
session.defaultSession.on.mockImplementation((event, cb) => {
|
session.defaultSession.on.mockImplementation((event, cb) => {
|
||||||
if (event === 'will-download') {
|
if (event === 'will-download') {
|
||||||
cb(null, item, {id: 0});
|
cb(null, item, {id: 0, getURL: jest.fn()});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -295,6 +295,7 @@ function initializeAfterAppReady() {
|
|||||||
if (typeof Config.canUpgrade === 'undefined') {
|
if (typeof Config.canUpgrade === 'undefined') {
|
||||||
// windows might not be ready, so we have to wait until it is
|
// windows might not be ready, so we have to wait until it is
|
||||||
Config.once('update', () => {
|
Config.once('update', () => {
|
||||||
|
log.debug('Initialize.checkForUpdates');
|
||||||
if (Config.canUpgrade && Config.autoCheckForUpdates) {
|
if (Config.canUpgrade && Config.autoCheckForUpdates) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
updateManager.checkForUpdates(false);
|
updateManager.checkForUpdates(false);
|
||||||
@@ -342,6 +343,7 @@ function initializeAfterAppReady() {
|
|||||||
|
|
||||||
// listen for status updates and pass on to renderer
|
// listen for status updates and pass on to renderer
|
||||||
UserActivityMonitor.on('status', (status) => {
|
UserActivityMonitor.on('status', (status) => {
|
||||||
|
log.debug('Initialize.UserActivityMonitor.on(status)', status);
|
||||||
WindowManager.sendToMattermostViews(USER_ACTIVITY_UPDATE, status);
|
WindowManager.sendToMattermostViews(USER_ACTIVITY_UPDATE, status);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -354,6 +356,7 @@ function initializeAfterAppReady() {
|
|||||||
setupBadge();
|
setupBadge();
|
||||||
|
|
||||||
defaultSession.on('will-download', (event, item, webContents) => {
|
defaultSession.on('will-download', (event, item, webContents) => {
|
||||||
|
log.debug('Initialize.will-download', {item, sourceURL: webContents.getURL()});
|
||||||
const filename = item.getFilename();
|
const filename = item.getFilename();
|
||||||
const fileElements = filename.split('.');
|
const fileElements = filename.split('.');
|
||||||
const filters = [];
|
const filters = [];
|
||||||
|
@@ -19,6 +19,8 @@ import {handleAppBeforeQuit} from './app';
|
|||||||
import {updateServerInfos} from './utils';
|
import {updateServerInfos} from './utils';
|
||||||
|
|
||||||
export function handleReloadConfig() {
|
export function handleReloadConfig() {
|
||||||
|
log.debug('Intercom.handleReloadConfig');
|
||||||
|
|
||||||
Config.reload();
|
Config.reload();
|
||||||
WindowManager.handleUpdateConfig();
|
WindowManager.handleUpdateConfig();
|
||||||
}
|
}
|
||||||
@@ -38,14 +40,18 @@ export function handleQuit(e: IpcMainEvent, reason: string, stack: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleSwitchServer(event: IpcMainEvent, serverName: string) {
|
export function handleSwitchServer(event: IpcMainEvent, serverName: string) {
|
||||||
|
log.silly('Intercom.handleSwitchServer', serverName);
|
||||||
WindowManager.switchServer(serverName);
|
WindowManager.switchServer(serverName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleSwitchTab(event: IpcMainEvent, serverName: string, tabName: string) {
|
export function handleSwitchTab(event: IpcMainEvent, serverName: string, tabName: string) {
|
||||||
|
log.silly('Intercom.handleSwitchTab', {serverName, tabName});
|
||||||
WindowManager.switchTab(serverName, tabName);
|
WindowManager.switchTab(serverName, tabName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleCloseTab(event: IpcMainEvent, serverName: string, tabName: string) {
|
export function handleCloseTab(event: IpcMainEvent, serverName: string, tabName: string) {
|
||||||
|
log.debug('Intercom.handleCloseTab', {serverName, tabName});
|
||||||
|
|
||||||
const teams = Config.teams;
|
const teams = Config.teams;
|
||||||
teams.forEach((team) => {
|
teams.forEach((team) => {
|
||||||
if (team.name === serverName) {
|
if (team.name === serverName) {
|
||||||
@@ -62,6 +68,8 @@ export function handleCloseTab(event: IpcMainEvent, serverName: string, tabName:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleOpenTab(event: IpcMainEvent, serverName: string, tabName: string) {
|
export function handleOpenTab(event: IpcMainEvent, serverName: string, tabName: string) {
|
||||||
|
log.debug('Intercom.handleOpenTab', {serverName, tabName});
|
||||||
|
|
||||||
const teams = Config.teams;
|
const teams = Config.teams;
|
||||||
teams.forEach((team) => {
|
teams.forEach((team) => {
|
||||||
if (team.name === serverName) {
|
if (team.name === serverName) {
|
||||||
@@ -83,6 +91,7 @@ export function addNewServerModalWhenMainWindowIsShown() {
|
|||||||
handleNewServerModal();
|
handleNewServerModal();
|
||||||
} else {
|
} else {
|
||||||
mainWindow.once('show', () => {
|
mainWindow.once('show', () => {
|
||||||
|
log.debug('Intercom.addNewServerModalWhenMainWindowIsShown.show');
|
||||||
handleNewServerModal();
|
handleNewServerModal();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -90,6 +99,8 @@ export function addNewServerModalWhenMainWindowIsShown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleNewServerModal() {
|
export function handleNewServerModal() {
|
||||||
|
log.debug('Intercom.handleNewServerModal');
|
||||||
|
|
||||||
const html = getLocalURLString('newServer.html');
|
const html = getLocalURLString('newServer.html');
|
||||||
|
|
||||||
const modalPreload = getLocalPreload('modalPreload.js');
|
const modalPreload = getLocalPreload('modalPreload.js');
|
||||||
@@ -120,6 +131,8 @@ export function handleNewServerModal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleEditServerModal(e: IpcMainEvent, name: string) {
|
export function handleEditServerModal(e: IpcMainEvent, name: string) {
|
||||||
|
log.debug('Intercom.handleEditServerModal', name);
|
||||||
|
|
||||||
const html = getLocalURLString('editServer.html');
|
const html = getLocalURLString('editServer.html');
|
||||||
|
|
||||||
const modalPreload = getLocalPreload('modalPreload.js');
|
const modalPreload = getLocalPreload('modalPreload.js');
|
||||||
@@ -151,6 +164,8 @@ export function handleEditServerModal(e: IpcMainEvent, name: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleRemoveServerModal(e: IpcMainEvent, name: string) {
|
export function handleRemoveServerModal(e: IpcMainEvent, name: string) {
|
||||||
|
log.debug('Intercom.handleRemoveServerModal', name);
|
||||||
|
|
||||||
const html = getLocalURLString('removeServer.html');
|
const html = getLocalURLString('removeServer.html');
|
||||||
|
|
||||||
const modalPreload = getLocalPreload('modalPreload.js');
|
const modalPreload = getLocalPreload('modalPreload.js');
|
||||||
@@ -189,10 +204,13 @@ export function handleRemoveServerModal(e: IpcMainEvent, name: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleMentionNotification(event: IpcMainEvent, title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, data: MentionData) {
|
export function handleMentionNotification(event: IpcMainEvent, title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, data: MentionData) {
|
||||||
|
log.debug('Intercom.handleMentionNotification', {title, body, channel, teamId, url, silent, data});
|
||||||
displayMention(title, body, channel, teamId, url, silent, event.sender, data);
|
displayMention(title, body, channel, teamId, url, silent, event.sender, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleOpenAppMenu() {
|
export function handleOpenAppMenu() {
|
||||||
|
log.debug('Intercom.handleOpenAppMenu');
|
||||||
|
|
||||||
const windowMenu = Menu.getApplicationMenu();
|
const windowMenu = Menu.getApplicationMenu();
|
||||||
if (!windowMenu) {
|
if (!windowMenu) {
|
||||||
log.error('No application menu found');
|
log.error('No application menu found');
|
||||||
@@ -206,6 +224,8 @@ export function handleOpenAppMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom: string) {
|
export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom: string) {
|
||||||
|
log.debug('Intercom.handleSelectDownload', startFrom);
|
||||||
|
|
||||||
const message = 'Specify the folder where files will download';
|
const message = 'Specify the folder where files will download';
|
||||||
const result = await dialog.showOpenDialog({defaultPath: startFrom || Config.downloadLocation,
|
const result = await dialog.showOpenDialog({defaultPath: startFrom || Config.downloadLocation,
|
||||||
message,
|
message,
|
||||||
@@ -215,6 +235,8 @@ export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleUpdateLastActive(event: IpcMainEvent, serverName: string, viewName: string) {
|
export function handleUpdateLastActive(event: IpcMainEvent, serverName: string, viewName: string) {
|
||||||
|
log.debug('Intercom.handleUpdateLastActive', {serverName, viewName});
|
||||||
|
|
||||||
const teams = Config.teams;
|
const teams = Config.teams;
|
||||||
teams.forEach((team) => {
|
teams.forEach((team) => {
|
||||||
if (team.name === serverName) {
|
if (team.name === serverName) {
|
||||||
|
@@ -35,11 +35,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('common/config', () => ({
|
jest.mock('common/config', () => ({
|
||||||
set: jest.fn(),
|
set: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
@@ -6,7 +6,7 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import {app, BrowserWindow, Menu, Rectangle, Session, session, dialog, nativeImage} from 'electron';
|
import {app, BrowserWindow, Menu, Rectangle, Session, session, dialog, nativeImage} from 'electron';
|
||||||
import log from 'electron-log';
|
import log, {LevelOption} from 'electron-log';
|
||||||
|
|
||||||
import {MigrationInfo, TeamWithTabs} from 'types/config';
|
import {MigrationInfo, TeamWithTabs} from 'types/config';
|
||||||
import {RemoteInfo} from 'types/server';
|
import {RemoteInfo} from 'types/server';
|
||||||
@@ -83,6 +83,8 @@ function openExtraTabs(data: Array<RemoteInfo | string | undefined>, team: TeamW
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleUpdateMenuEvent() {
|
export function handleUpdateMenuEvent() {
|
||||||
|
log.debug('Utils.handleUpdateMenuEvent');
|
||||||
|
|
||||||
const aMenu = createAppMenu(Config, updateManager);
|
const aMenu = createAppMenu(Config, updateManager);
|
||||||
Menu.setApplicationMenu(aMenu);
|
Menu.setApplicationMenu(aMenu);
|
||||||
aMenu.addListener('menu-will-close', WindowManager.focusBrowserView);
|
aMenu.addListener('menu-will-close', WindowManager.focusBrowserView);
|
||||||
@@ -152,6 +154,7 @@ function getValidWindowPosition(state: Rectangle) {
|
|||||||
|
|
||||||
export function resizeScreen(browserWindow: BrowserWindow) {
|
export function resizeScreen(browserWindow: BrowserWindow) {
|
||||||
function handle() {
|
function handle() {
|
||||||
|
log.debug('Utils.resizeScreen.handle');
|
||||||
const position = browserWindow.getPosition();
|
const position = browserWindow.getPosition();
|
||||||
const size = browserWindow.getSize();
|
const size = browserWindow.getSize();
|
||||||
const validPosition = getValidWindowPosition({
|
const validPosition = getValidWindowPosition({
|
||||||
@@ -172,6 +175,7 @@ export function resizeScreen(browserWindow: BrowserWindow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function flushCookiesStore(session: Session) {
|
function flushCookiesStore(session: Session) {
|
||||||
|
log.debug('Utils.flushCookiesStore');
|
||||||
session.cookies.flushStore().catch((err) => {
|
session.cookies.flushStore().catch((err) => {
|
||||||
log.error(`There was a problem flushing cookies:\n${err}`);
|
log.error(`There was a problem flushing cookies:\n${err}`);
|
||||||
});
|
});
|
||||||
@@ -248,3 +252,8 @@ export function migrateMacAppStore() {
|
|||||||
log.error('MAS: An error occurred importing the existing configuration', e);
|
log.error('MAS: An error occurred importing the existing configuration', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setLoggingLevel(level: LevelOption) {
|
||||||
|
log.transports.console.level = level;
|
||||||
|
log.transports.file.level = level;
|
||||||
|
}
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
import events from 'events';
|
import events from 'events';
|
||||||
import {ipcMain} from 'electron';
|
import {ipcMain} from 'electron';
|
||||||
|
|
||||||
|
import log from 'electron-log';
|
||||||
|
|
||||||
import {UPDATE_MENTIONS, UPDATE_TRAY, UPDATE_BADGE, SESSION_EXPIRED, UPDATE_DROPDOWN_MENTIONS} from 'common/communication';
|
import {UPDATE_MENTIONS, UPDATE_TRAY, UPDATE_BADGE, SESSION_EXPIRED, UPDATE_DROPDOWN_MENTIONS} from 'common/communication';
|
||||||
|
|
||||||
import WindowManager from './windows/windowManager';
|
import WindowManager from './windows/windowManager';
|
||||||
@@ -21,6 +23,7 @@ const emitMentions = (serverName: string) => {
|
|||||||
const isExpired = getIsExpired(serverName);
|
const isExpired = getIsExpired(serverName);
|
||||||
|
|
||||||
WindowManager.sendToRenderer(UPDATE_MENTIONS, serverName, newMentions, newUnreads, isExpired);
|
WindowManager.sendToRenderer(UPDATE_MENTIONS, serverName, newMentions, newUnreads, isExpired);
|
||||||
|
log.silly('AppState.emitMentions', {serverName, isExpired, newMentions, newUnreads});
|
||||||
emitStatus();
|
emitStatus();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,5 +120,8 @@ const setSessionExpired = (serverName: string, expired: boolean) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ipcMain.on(SESSION_EXPIRED, (event, isExpired, serverName) => {
|
ipcMain.on(SESSION_EXPIRED, (event, isExpired, serverName) => {
|
||||||
|
if (isExpired) {
|
||||||
|
log.debug('SESSION_EXPIRED', {isExpired, serverName});
|
||||||
|
}
|
||||||
setSessionExpired(serverName, isExpired);
|
setSessionExpired(serverName, isExpired);
|
||||||
});
|
});
|
||||||
|
@@ -82,10 +82,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('main/trustedOrigins', () => ({
|
jest.mock('main/trustedOrigins', () => ({
|
||||||
addPermission: jest.fn(),
|
addPermission: jest.fn(),
|
||||||
checkPermission: (url) => {
|
checkPermission: (url) => {
|
||||||
|
@@ -32,6 +32,8 @@ export class AuthManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleAppLogin = (event: Event, webContents: WebContents, request: AuthenticationResponseDetails, authInfo: AuthInfo, callback?: (username?: string, password?: string) => void) => {
|
handleAppLogin = (event: Event, webContents: WebContents, request: AuthenticationResponseDetails, authInfo: AuthInfo, callback?: (username?: string, password?: string) => void) => {
|
||||||
|
log.verbose('AuthManager.handleAppLogin', {request, authInfo});
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const parsedURL = urlUtils.parseURL(request.url);
|
const parsedURL = urlUtils.parseURL(request.url);
|
||||||
if (!parsedURL) {
|
if (!parsedURL) {
|
||||||
|
@@ -22,15 +22,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
info: jest.fn(),
|
|
||||||
transports: {
|
|
||||||
file: {
|
|
||||||
level: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
jest.mock('electron-updater', () => ({
|
jest.mock('electron-updater', () => ({
|
||||||
autoUpdater: {
|
autoUpdater: {
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {app} from 'electron';
|
import {app} from 'electron';
|
||||||
|
import log from 'electron-log';
|
||||||
|
|
||||||
import {UPDATE_BADGE} from 'common/communication';
|
import {UPDATE_BADGE} from 'common/communication';
|
||||||
|
|
||||||
@@ -49,6 +50,8 @@ function showBadgeLinux(sessionExpired: boolean, mentionCount: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showBadge(sessionExpired: boolean, mentionCount: number, showUnreadBadge: boolean) {
|
function showBadge(sessionExpired: boolean, mentionCount: number, showUnreadBadge: boolean) {
|
||||||
|
log.silly('Badge.showBadge', {sessionExpired, mentionCount, showUnreadBadge});
|
||||||
|
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case 'win32':
|
case 'win32':
|
||||||
showBadgeWindows(sessionExpired, mentionCount, showUnreadBadge);
|
showBadgeWindows(sessionExpired, mentionCount, showUnreadBadge);
|
||||||
|
@@ -6,11 +6,6 @@ import WindowManager from 'main/windows/windowManager';
|
|||||||
import ModalManager from 'main/views/modalManager';
|
import ModalManager from 'main/views/modalManager';
|
||||||
import {CertificateManager} from 'main/certificateManager';
|
import {CertificateManager} from 'main/certificateManager';
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('main/windows/windowManager', () => ({
|
jest.mock('main/windows/windowManager', () => ({
|
||||||
getMainWindow: jest.fn().mockImplementation(() => ({})),
|
getMainWindow: jest.fn().mockImplementation(() => ({})),
|
||||||
}));
|
}));
|
||||||
|
@@ -25,6 +25,8 @@ export class CertificateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSelectCertificate = (event: Event, webContents: WebContents, url: string, list: Certificate[], callback: (certificate?: Certificate | undefined) => void) => {
|
handleSelectCertificate = (event: Event, webContents: WebContents, url: string, list: Certificate[], callback: (certificate?: Certificate | undefined) => void) => {
|
||||||
|
log.verbose('CertificateManager.handleSelectCertificate', url, list);
|
||||||
|
|
||||||
if (list.length > 1) {
|
if (list.length > 1) {
|
||||||
event.preventDefault(); // prevent the app from getting the first certificate available
|
event.preventDefault(); // prevent the app from getting the first certificate available
|
||||||
|
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
import {Certificate, ipcMain} from 'electron';
|
import {Certificate, ipcMain} from 'electron';
|
||||||
|
import log from 'electron-log';
|
||||||
|
|
||||||
import {ComparableCertificate} from 'types/certificate';
|
import {ComparableCertificate} from 'types/certificate';
|
||||||
|
|
||||||
@@ -85,5 +86,6 @@ let certificateStore = new CertificateStore(certificateStorePath);
|
|||||||
export default certificateStore;
|
export default certificateStore;
|
||||||
|
|
||||||
ipcMain.on(UPDATE_PATHS, () => {
|
ipcMain.on(UPDATE_PATHS, () => {
|
||||||
|
log.debug('certificateStore.UPDATE_PATHS');
|
||||||
certificateStore = new CertificateStore(certificateStorePath);
|
certificateStore = new CertificateStore(certificateStorePath);
|
||||||
});
|
});
|
||||||
|
@@ -51,11 +51,6 @@ jest.mock('electron', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../windows/windowManager', () => ({
|
jest.mock('../windows/windowManager', () => ({
|
||||||
getServerNameByWebContentsId: () => 'server_name',
|
getServerNameByWebContentsId: () => 'server_name',
|
||||||
sendToRenderer: jest.fn(),
|
sendToRenderer: jest.fn(),
|
||||||
|
@@ -18,6 +18,8 @@ import {NewVersionNotification, UpgradeNotification} from './Upgrade';
|
|||||||
export const currentNotifications = new Map();
|
export const currentNotifications = new Map();
|
||||||
|
|
||||||
export function displayMention(title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, webcontents: Electron.WebContents, data: MentionData) {
|
export function displayMention(title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, webcontents: Electron.WebContents, data: MentionData) {
|
||||||
|
log.debug('Notifications.displayMention', {title, body, channel, teamId, url, silent, data});
|
||||||
|
|
||||||
if (!Notification.isSupported()) {
|
if (!Notification.isSupported()) {
|
||||||
log.error('notification not supported');
|
log.error('notification not supported');
|
||||||
return;
|
return;
|
||||||
@@ -35,6 +37,8 @@ export function displayMention(title: string, body: string, channel: {id: string
|
|||||||
const mentionKey = `${mention.teamId}:${mention.channel.id}`;
|
const mentionKey = `${mention.teamId}:${mention.channel.id}`;
|
||||||
|
|
||||||
mention.on('show', () => {
|
mention.on('show', () => {
|
||||||
|
log.debug('Notifications.displayMention.show');
|
||||||
|
|
||||||
// On Windows, manually dismiss notifications from the same channel and only show the latest one
|
// On Windows, manually dismiss notifications from the same channel and only show the latest one
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
if (currentNotifications.has(mentionKey)) {
|
if (currentNotifications.has(mentionKey)) {
|
||||||
@@ -62,6 +66,8 @@ export function displayMention(title: string, body: string, channel: {id: string
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function displayDownloadCompleted(fileName: string, path: string, serverName: string) {
|
export function displayDownloadCompleted(fileName: string, path: string, serverName: string) {
|
||||||
|
log.debug('Notifications.displayDownloadCompleted', {fileName, path, serverName});
|
||||||
|
|
||||||
if (!Notification.isSupported()) {
|
if (!Notification.isSupported()) {
|
||||||
log.error('notification not supported');
|
log.error('notification not supported');
|
||||||
return;
|
return;
|
||||||
|
@@ -14,10 +14,6 @@ const testData = {
|
|||||||
value: 'some more data',
|
value: 'some more data',
|
||||||
};
|
};
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('electron', () => ({
|
jest.mock('electron', () => ({
|
||||||
net: {
|
net: {
|
||||||
request: jest.fn().mockImplementation(({url}) => ({
|
request: jest.fn().mockImplementation(({url}) => ({
|
||||||
|
@@ -34,8 +34,10 @@ export async function getServerAPI<T>(url: URL, isAuthenticated: boolean, onSucc
|
|||||||
|
|
||||||
if (onSuccess) {
|
if (onSuccess) {
|
||||||
req.on('response', (response: Electron.IncomingMessage) => {
|
req.on('response', (response: Electron.IncomingMessage) => {
|
||||||
|
log.silly('getServerAPI.response', response);
|
||||||
if (response.statusCode === 200) {
|
if (response.statusCode === 200) {
|
||||||
response.on('data', (chunk: Buffer) => {
|
response.on('data', (chunk: Buffer) => {
|
||||||
|
log.silly('getServerAPI.response.data', `${chunk}`);
|
||||||
const raw = `${chunk}`;
|
const raw = `${chunk}`;
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(raw) as T;
|
const data = JSON.parse(raw) as T;
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
|
import log from 'electron-log';
|
||||||
|
|
||||||
import {RemoteInfo} from 'types/server';
|
import {RemoteInfo} from 'types/server';
|
||||||
|
|
||||||
import {MattermostServer} from 'common/servers/MattermostServer';
|
import {MattermostServer} from 'common/servers/MattermostServer';
|
||||||
@@ -53,6 +55,8 @@ export class ServerInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trySendRemoteInfo = () => {
|
trySendRemoteInfo = () => {
|
||||||
|
log.debug('ServerInfo.trySendRemoteInfo', this.server.name, this.remoteInfo);
|
||||||
|
|
||||||
if (this.isRemoteInfoRetrieved()) {
|
if (this.isRemoteInfoRetrieved()) {
|
||||||
this.onRetrievedRemoteInfo?.(this.remoteInfo);
|
this.onRetrievedRemoteInfo?.(this.remoteInfo);
|
||||||
}
|
}
|
||||||
|
@@ -18,10 +18,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
function mockTOS(fileName, returnvalue) {
|
function mockTOS(fileName, returnvalue) {
|
||||||
const tos = new TrustedOriginsStore(fileName);
|
const tos = new TrustedOriginsStore(fileName);
|
||||||
tos.readFromFile = () => {
|
tos.readFromFile = () => {
|
||||||
|
@@ -117,6 +117,7 @@ const trustedOriginsStore = new TrustedOriginsStore(trustedOriginsStoreFile);
|
|||||||
export default trustedOriginsStore;
|
export default trustedOriginsStore;
|
||||||
|
|
||||||
ipcMain.on(UPDATE_PATHS, () => {
|
ipcMain.on(UPDATE_PATHS, () => {
|
||||||
|
log.debug('trustedOriginsStore.UPDATE_PATHS');
|
||||||
trustedOriginsStore.storeFile = trustedOriginsStoreFile;
|
trustedOriginsStore.storeFile = trustedOriginsStoreFile;
|
||||||
if (trustedOriginsStore.data) {
|
if (trustedOriginsStore.data) {
|
||||||
trustedOriginsStore.load();
|
trustedOriginsStore.load();
|
||||||
|
@@ -29,11 +29,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../windows/windowManager', () => ({
|
jest.mock('../windows/windowManager', () => ({
|
||||||
sendToRenderer: jest.fn(),
|
sendToRenderer: jest.fn(),
|
||||||
focusThreeDotMenu: jest.fn(),
|
focusThreeDotMenu: jest.fn(),
|
||||||
|
@@ -101,6 +101,8 @@ export class MattermostView extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.view.webContents.on('did-finish-load', () => {
|
this.view.webContents.on('did-finish-load', () => {
|
||||||
|
log.debug('MattermostView.did-finish-load', this.tab.name);
|
||||||
|
|
||||||
// wait for screen to truly finish loading before sending the message down
|
// wait for screen to truly finish loading before sending the message down
|
||||||
const timeout = setInterval(() => {
|
const timeout = setInterval(() => {
|
||||||
if (!this.view.webContents.isLoading()) {
|
if (!this.view.webContents.isLoading()) {
|
||||||
@@ -327,6 +329,8 @@ export class MattermostView extends EventEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleInputEvents = (_: Event, input: Input) => {
|
handleInputEvents = (_: Event, input: Input) => {
|
||||||
|
log.silly('MattermostView.handleInputEvents', {tabName: this.tab.name, input});
|
||||||
|
|
||||||
this.registerAltKeyPressed(input);
|
this.registerAltKeyPressed(input);
|
||||||
|
|
||||||
if (this.isAltKeyReleased(input)) {
|
if (this.isAltKeyReleased(input)) {
|
||||||
@@ -335,6 +339,8 @@ export class MattermostView extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleDidNavigate = (event: Event, url: string) => {
|
handleDidNavigate = (event: Event, url: string) => {
|
||||||
|
log.debug('MattermostView.handleDidNavigate', {tabName: this.tab.name, url});
|
||||||
|
|
||||||
const isUrlTeamUrl = urlUtils.isTeamUrl(this.tab.url || '', url) || urlUtils.isAdminUrl(this.tab.url || '', url);
|
const isUrlTeamUrl = urlUtils.isTeamUrl(this.tab.url || '', url) || urlUtils.isAdminUrl(this.tab.url || '', url);
|
||||||
if (isUrlTeamUrl) {
|
if (isUrlTeamUrl) {
|
||||||
this.setBounds(getWindowBoundaries(this.window));
|
this.setBounds(getWindowBoundaries(this.window));
|
||||||
@@ -348,6 +354,7 @@ export class MattermostView extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleUpdateTarget = (e: Event, url: string) => {
|
handleUpdateTarget = (e: Event, url: string) => {
|
||||||
|
log.silly('MattermostView.handleUpdateTarget', {tabName: this.tab.name, url});
|
||||||
if (url && !urlUtils.isInternalURL(urlUtils.parseURL(url), this.tab.server.url)) {
|
if (url && !urlUtils.isInternalURL(urlUtils.parseURL(url), this.tab.server.url)) {
|
||||||
this.emit(UPDATE_TARGET_URL, url);
|
this.emit(UPDATE_TARGET_URL, url);
|
||||||
}
|
}
|
||||||
@@ -356,6 +363,8 @@ export class MattermostView extends EventEmitter {
|
|||||||
titleParser = /(\((\d+)\) )?(\* )?/g
|
titleParser = /(\((\d+)\) )?(\* )?/g
|
||||||
|
|
||||||
handleTitleUpdate = (e: Event, title: string) => {
|
handleTitleUpdate = (e: Event, title: string) => {
|
||||||
|
log.debug('MattermostView.handleTitleUpdate', {tabName: this.tab.name, title});
|
||||||
|
|
||||||
this.updateMentionsFromTitle(title);
|
this.updateMentionsFromTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,6 +388,8 @@ export class MattermostView extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleFaviconUpdate = (e: Event, favicons: string[]) => {
|
handleFaviconUpdate = (e: Event, favicons: string[]) => {
|
||||||
|
log.silly('MattermostView.handleFaviconUpdate', {tabName: this.tab.name, favicons});
|
||||||
|
|
||||||
if (!this.usesAsteriskForUnreads) {
|
if (!this.usesAsteriskForUnreads) {
|
||||||
// if unread state is stored for that favicon, retrieve value.
|
// if unread state is stored for that favicon, retrieve value.
|
||||||
// if not, get related info from preload and store it for future changes
|
// if not, get related info from preload and store it for future changes
|
||||||
@@ -400,6 +411,8 @@ export class MattermostView extends EventEmitter {
|
|||||||
// if favicon is null, it means it is the initial load,
|
// if favicon is null, it means it is the initial load,
|
||||||
// so don't memoize as we don't have the favicons and there is no rush to find out.
|
// so don't memoize as we don't have the favicons and there is no rush to find out.
|
||||||
handleFaviconIsUnread = (e: Event, favicon: string, viewName: string, result: boolean) => {
|
handleFaviconIsUnread = (e: Event, favicon: string, viewName: string, result: boolean) => {
|
||||||
|
log.silly('MattermostView.handleFaviconIsUnread', {favicon, viewName, result});
|
||||||
|
|
||||||
if (this.tab && viewName === this.tab.name) {
|
if (this.tab && viewName === this.tab.name) {
|
||||||
appState.updateUnreads(viewName, result);
|
appState.updateUnreads(viewName, result);
|
||||||
}
|
}
|
||||||
|
@@ -15,8 +15,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({}));
|
|
||||||
|
|
||||||
jest.mock('./modalView', () => ({
|
jest.mock('./modalView', () => ({
|
||||||
ModalView: jest.fn(),
|
ModalView: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
import {BrowserWindow, ipcMain} from 'electron';
|
import {BrowserWindow, ipcMain} from 'electron';
|
||||||
import {IpcMainEvent, IpcMainInvokeEvent} from 'electron/main';
|
import {IpcMainEvent, IpcMainInvokeEvent} from 'electron/main';
|
||||||
|
|
||||||
|
import log from 'electron-log';
|
||||||
|
|
||||||
import {CombinedConfig} from 'types/config';
|
import {CombinedConfig} from 'types/config';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -70,6 +72,8 @@ export class ModalManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleInfoRequest = (event: IpcMainInvokeEvent) => {
|
handleInfoRequest = (event: IpcMainInvokeEvent) => {
|
||||||
|
log.debug('ModalManager.handleInfoRequest');
|
||||||
|
|
||||||
const requestModal = this.findModalByCaller(event);
|
const requestModal = this.findModalByCaller(event);
|
||||||
if (requestModal) {
|
if (requestModal) {
|
||||||
return requestModal.handleInfoRequest();
|
return requestModal.handleInfoRequest();
|
||||||
@@ -91,6 +95,8 @@ export class ModalManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleModalFinished = (mode: 'resolve' | 'reject', event: IpcMainEvent, data: unknown) => {
|
handleModalFinished = (mode: 'resolve' | 'reject', event: IpcMainEvent, data: unknown) => {
|
||||||
|
log.debug('ModalManager.handleModalFinished', {mode, data});
|
||||||
|
|
||||||
const requestModal = this.findModalByCaller(event);
|
const requestModal = this.findModalByCaller(event);
|
||||||
if (requestModal) {
|
if (requestModal) {
|
||||||
if (mode === 'resolve') {
|
if (mode === 'resolve') {
|
||||||
@@ -122,6 +128,8 @@ export class ModalManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleResizeModal = (event: IpcMainEvent, bounds: Electron.Rectangle) => {
|
handleResizeModal = (event: IpcMainEvent, bounds: Electron.Rectangle) => {
|
||||||
|
log.debug('ModalManager.handleResizeModal', bounds);
|
||||||
|
|
||||||
if (this.modalQueue.length) {
|
if (this.modalQueue.length) {
|
||||||
const currentModal = this.modalQueue[0];
|
const currentModal = this.modalQueue[0];
|
||||||
currentModal.view.setBounds(getAdjustedWindowBoundaries(bounds.width, bounds.height));
|
currentModal.view.setBounds(getAdjustedWindowBoundaries(bounds.width, bounds.height));
|
||||||
@@ -135,6 +143,10 @@ export class ModalManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleEmitConfiguration = (event: IpcMainEvent, config: CombinedConfig) => {
|
handleEmitConfiguration = (event: IpcMainEvent, config: CombinedConfig) => {
|
||||||
|
if (this.modalQueue.length) {
|
||||||
|
log.debug('ModalManager.handleEmitConfiguration');
|
||||||
|
}
|
||||||
|
|
||||||
this.modalQueue.forEach((modal) => {
|
this.modalQueue.forEach((modal) => {
|
||||||
modal.view.webContents.send(DARK_MODE_CHANGE, config.darkMode);
|
modal.view.webContents.send(DARK_MODE_CHANGE, config.darkMode);
|
||||||
});
|
});
|
||||||
|
@@ -22,10 +22,6 @@ jest.mock('electron', () => ({
|
|||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../contextMenu', () => jest.fn());
|
jest.mock('../contextMenu', () => jest.fn());
|
||||||
|
|
||||||
jest.mock('../utils', () => ({
|
jest.mock('../utils', () => ({
|
||||||
|
@@ -2,6 +2,9 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {BrowserView, BrowserWindow, ipcMain, IpcMainEvent} from 'electron';
|
import {BrowserView, BrowserWindow, ipcMain, IpcMainEvent} from 'electron';
|
||||||
|
|
||||||
|
import log from 'electron-log';
|
||||||
|
|
||||||
import {CombinedConfig, TeamWithTabs} from 'types/config';
|
import {CombinedConfig, TeamWithTabs} from 'types/config';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -66,6 +69,8 @@ export default class TeamDropdownView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateConfig = (event: IpcMainEvent, config: CombinedConfig) => {
|
updateConfig = (event: IpcMainEvent, config: CombinedConfig) => {
|
||||||
|
log.silly('TeamDropdownView.config', {config});
|
||||||
|
|
||||||
this.teams = config.teams;
|
this.teams = config.teams;
|
||||||
this.darkMode = config.darkMode;
|
this.darkMode = config.darkMode;
|
||||||
this.enableServerManagement = config.enableServerManagement;
|
this.enableServerManagement = config.enableServerManagement;
|
||||||
@@ -74,11 +79,15 @@ export default class TeamDropdownView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateActiveTeam = (event: IpcMainEvent, name: string) => {
|
updateActiveTeam = (event: IpcMainEvent, name: string) => {
|
||||||
|
log.silly('TeamDropdownView.updateActiveTeam', {name});
|
||||||
|
|
||||||
this.activeTeam = name;
|
this.activeTeam = name;
|
||||||
this.updateDropdown();
|
this.updateDropdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMentions = (expired: Map<string, boolean>, mentions: Map<string, number>, unreads: Map<string, boolean>) => {
|
updateMentions = (expired: Map<string, boolean>, mentions: Map<string, number>, unreads: Map<string, boolean>) => {
|
||||||
|
log.silly('TeamDropdownView.updateMentions', {expired, mentions, unreads});
|
||||||
|
|
||||||
this.unreads = unreads;
|
this.unreads = unreads;
|
||||||
this.mentions = mentions;
|
this.mentions = mentions;
|
||||||
this.expired = expired;
|
this.expired = expired;
|
||||||
@@ -91,6 +100,8 @@ export default class TeamDropdownView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateDropdown = () => {
|
updateDropdown = () => {
|
||||||
|
log.silly('TeamDropdownView.updateDropdown');
|
||||||
|
|
||||||
this.view.webContents.send(
|
this.view.webContents.send(
|
||||||
UPDATE_TEAMS_DROPDOWN,
|
UPDATE_TEAMS_DROPDOWN,
|
||||||
this.teams,
|
this.teams,
|
||||||
@@ -106,6 +117,8 @@ export default class TeamDropdownView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleOpen = () => {
|
handleOpen = () => {
|
||||||
|
log.debug('TeamDropdownView.handleOpen');
|
||||||
|
|
||||||
if (!this.bounds) {
|
if (!this.bounds) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -117,12 +130,16 @@ export default class TeamDropdownView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleClose = () => {
|
handleClose = () => {
|
||||||
|
log.debug('TeamDropdownView.handleClose');
|
||||||
|
|
||||||
this.view.setBounds(this.getBounds(0, 0));
|
this.view.setBounds(this.getBounds(0, 0));
|
||||||
WindowManager.sendToRenderer(CLOSE_TEAMS_DROPDOWN);
|
WindowManager.sendToRenderer(CLOSE_TEAMS_DROPDOWN);
|
||||||
this.isOpen = false;
|
this.isOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleReceivedMenuSize = (event: IpcMainEvent, width: number, height: number) => {
|
handleReceivedMenuSize = (event: IpcMainEvent, width: number, height: number) => {
|
||||||
|
log.silly('TeamDropdownView.handleReceivedMenuSize', {width, height});
|
||||||
|
|
||||||
this.bounds = this.getBounds(width, height);
|
this.bounds = this.getBounds(width, height);
|
||||||
if (this.isOpen) {
|
if (this.isOpen) {
|
||||||
this.view.setBounds(this.bounds);
|
this.view.setBounds(this.bounds);
|
||||||
|
@@ -27,11 +27,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
warn: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('common/tabs/TabView', () => ({
|
jest.mock('common/tabs/TabView', () => ({
|
||||||
getServerView: jest.fn(),
|
getServerView: jest.fn(),
|
||||||
getTabViewName: jest.fn(),
|
getTabViewName: jest.fn(),
|
||||||
|
@@ -173,6 +173,8 @@ export class ViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showByName = (name: string) => {
|
showByName = (name: string) => {
|
||||||
|
log.debug('viewManager.showByName', name);
|
||||||
|
|
||||||
const newView = this.views.get(name);
|
const newView = this.views.get(name);
|
||||||
if (newView) {
|
if (newView) {
|
||||||
if (newView.isVisible) {
|
if (newView.isVisible) {
|
||||||
@@ -218,6 +220,8 @@ export class ViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
activateView = (viewName: string) => {
|
activateView = (viewName: string) => {
|
||||||
|
log.debug('viewManager.activateView', viewName);
|
||||||
|
|
||||||
if (this.currentView === viewName) {
|
if (this.currentView === viewName) {
|
||||||
this.showByName(this.currentView);
|
this.showByName(this.currentView);
|
||||||
}
|
}
|
||||||
@@ -230,6 +234,8 @@ export class ViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
finishLoading = (server: string) => {
|
finishLoading = (server: string) => {
|
||||||
|
log.debug('viewManager.finishLoading', server);
|
||||||
|
|
||||||
const view = this.views.get(server);
|
const view = this.views.get(server);
|
||||||
if (view && this.getCurrentView() === view) {
|
if (view && this.getCurrentView() === view) {
|
||||||
this.showByName(this.currentView!);
|
this.showByName(this.currentView!);
|
||||||
@@ -255,6 +261,8 @@ export class ViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
failLoading = (tabName: string) => {
|
failLoading = (tabName: string) => {
|
||||||
|
log.debug('viewManager.failLoading', tabName);
|
||||||
|
|
||||||
this.fadeLoadingScreen();
|
this.fadeLoadingScreen();
|
||||||
if (this.currentView === tabName) {
|
if (this.currentView === tabName) {
|
||||||
this.getCurrentView()?.hide();
|
this.getCurrentView()?.hide();
|
||||||
@@ -293,6 +301,8 @@ export class ViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showURLView = (url: URL | string) => {
|
showURLView = (url: URL | string) => {
|
||||||
|
log.silly('viewManager.showURLView', url);
|
||||||
|
|
||||||
if (this.urlViewCancel) {
|
if (this.urlViewCancel) {
|
||||||
this.urlViewCancel();
|
this.urlViewCancel();
|
||||||
}
|
}
|
||||||
@@ -326,6 +336,8 @@ export class ViewManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const adjustWidth = (event: IpcMainEvent, width: number) => {
|
const adjustWidth = (event: IpcMainEvent, width: number) => {
|
||||||
|
log.silly('showURLView.adjustWidth', width);
|
||||||
|
|
||||||
urlView.setBounds({
|
urlView.setBounds({
|
||||||
x: 0,
|
x: 0,
|
||||||
y: boundaries.height - URL_VIEW_HEIGHT,
|
y: boundaries.height - URL_VIEW_HEIGHT,
|
||||||
@@ -422,6 +434,8 @@ export class ViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deeplinkSuccess = (viewName: string) => {
|
deeplinkSuccess = (viewName: string) => {
|
||||||
|
log.debug('viewManager.deeplinkSuccess', viewName);
|
||||||
|
|
||||||
const view = this.views.get(viewName);
|
const view = this.views.get(viewName);
|
||||||
if (!view) {
|
if (!view) {
|
||||||
return;
|
return;
|
||||||
|
@@ -27,11 +27,6 @@ jest.mock('electron', () => ({
|
|||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
info: jest.fn(),
|
|
||||||
warn: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../allowProtocolDialog', () => ({}));
|
jest.mock('../allowProtocolDialog', () => ({}));
|
||||||
jest.mock('../windows/windowManager', () => ({
|
jest.mock('../windows/windowManager', () => ({
|
||||||
showMainWindow: jest.fn(),
|
showMainWindow: jest.fn(),
|
||||||
|
@@ -47,6 +47,8 @@ export class WebContentsEventManager {
|
|||||||
|
|
||||||
generateWillNavigate = (getServersFunction: () => TeamWithTabs[]) => {
|
generateWillNavigate = (getServersFunction: () => TeamWithTabs[]) => {
|
||||||
return (event: Event & {sender: WebContents}, url: string) => {
|
return (event: Event & {sender: WebContents}, url: string) => {
|
||||||
|
log.debug('webContentEvents.will-navigate', {webContentsId: event.sender.id, url});
|
||||||
|
|
||||||
const contentID = event.sender.id;
|
const contentID = event.sender.id;
|
||||||
const parsedURL = urlUtils.parseURL(url)!;
|
const parsedURL = urlUtils.parseURL(url)!;
|
||||||
const configServers = getServersFunction();
|
const configServers = getServersFunction();
|
||||||
@@ -77,6 +79,8 @@ export class WebContentsEventManager {
|
|||||||
|
|
||||||
generateDidStartNavigation = (getServersFunction: () => TeamWithTabs[]) => {
|
generateDidStartNavigation = (getServersFunction: () => TeamWithTabs[]) => {
|
||||||
return (event: Event & {sender: WebContents}, url: string) => {
|
return (event: Event & {sender: WebContents}, url: string) => {
|
||||||
|
log.debug('webContentEvents.did-start-navigation', {webContentsId: event.sender.id, url});
|
||||||
|
|
||||||
const serverList = getServersFunction();
|
const serverList = getServersFunction();
|
||||||
const contentID = event.sender.id;
|
const contentID = event.sender.id;
|
||||||
const parsedURL = urlUtils.parseURL(url)!;
|
const parsedURL = urlUtils.parseURL(url)!;
|
||||||
@@ -103,6 +107,8 @@ export class WebContentsEventManager {
|
|||||||
|
|
||||||
generateNewWindowListener = (getServersFunction: () => TeamWithTabs[], spellcheck?: boolean) => {
|
generateNewWindowListener = (getServersFunction: () => TeamWithTabs[], spellcheck?: boolean) => {
|
||||||
return (details: Electron.HandlerDetails): {action: 'deny' | 'allow'} => {
|
return (details: Electron.HandlerDetails): {action: 'deny' | 'allow'} => {
|
||||||
|
log.debug('webContentEvents.new-window', details.url);
|
||||||
|
|
||||||
const parsedURL = urlUtils.parseURL(details.url);
|
const parsedURL = urlUtils.parseURL(details.url);
|
||||||
if (!parsedURL) {
|
if (!parsedURL) {
|
||||||
log.warn(`Ignoring non-url ${details.url}`);
|
log.warn(`Ignoring non-url ${details.url}`);
|
||||||
|
@@ -49,8 +49,6 @@ jest.mock('common/utils/util', () => ({
|
|||||||
isVersionGreaterThanOrEqualTo: jest.fn(),
|
isVersionGreaterThanOrEqualTo: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({}));
|
|
||||||
|
|
||||||
jest.mock('global', () => ({
|
jest.mock('global', () => ({
|
||||||
willAppQuit: false,
|
willAppQuit: false,
|
||||||
}));
|
}));
|
||||||
|
@@ -142,6 +142,8 @@ function createMainWindow(options: {linuxAppIcon: string; fullscreen?: boolean})
|
|||||||
});
|
});
|
||||||
|
|
||||||
mainWindow.on('close', (event) => {
|
mainWindow.on('close', (event) => {
|
||||||
|
log.debug('MainWindow.on.close');
|
||||||
|
|
||||||
if (global.willAppQuit) { // when [Ctrl|Cmd]+Q
|
if (global.willAppQuit) { // when [Ctrl|Cmd]+Q
|
||||||
saveWindowState(boundsInfoPath, mainWindow);
|
saveWindowState(boundsInfoPath, mainWindow);
|
||||||
} else { // Minimize or hide the window for close button.
|
} else { // Minimize or hide the window for close button.
|
||||||
|
@@ -40,11 +40,6 @@ jest.mock('electron', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log', () => ({
|
|
||||||
error: jest.fn(),
|
|
||||||
info: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('common/config', () => ({}));
|
jest.mock('common/config', () => ({}));
|
||||||
|
|
||||||
jest.mock('common/utils/url', () => ({
|
jest.mock('common/utils/url', () => ({
|
||||||
|
@@ -79,6 +79,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showSettingsWindow = () => {
|
showSettingsWindow = () => {
|
||||||
|
log.debug('WindowManager.showSettingsWindow');
|
||||||
|
|
||||||
if (this.settingsWindow) {
|
if (this.settingsWindow) {
|
||||||
this.settingsWindow.show();
|
this.settingsWindow.show();
|
||||||
} else {
|
} else {
|
||||||
@@ -95,6 +97,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showMainWindow = (deeplinkingURL?: string | URL) => {
|
showMainWindow = (deeplinkingURL?: string | URL) => {
|
||||||
|
log.debug('WindowManager.showMainWindow', deeplinkingURL);
|
||||||
|
|
||||||
if (this.mainWindow) {
|
if (this.mainWindow) {
|
||||||
if (this.mainWindow.isVisible()) {
|
if (this.mainWindow.isVisible()) {
|
||||||
this.mainWindow.focus();
|
this.mainWindow.focus();
|
||||||
@@ -169,6 +173,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleResizeMainWindow = () => {
|
handleResizeMainWindow = () => {
|
||||||
|
log.debug('WindowManager.handleResizeMainWindow');
|
||||||
|
|
||||||
if (!(this.viewManager && this.mainWindow)) {
|
if (!(this.viewManager && this.mainWindow)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -350,6 +356,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleDoubleClick = (e: IpcMainEvent, windowType?: string) => {
|
handleDoubleClick = (e: IpcMainEvent, windowType?: string) => {
|
||||||
|
log.debug('WindowManager.handleDoubleClick', windowType);
|
||||||
|
|
||||||
let action = 'Maximize';
|
let action = 'Maximize';
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
action = systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string');
|
action = systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string');
|
||||||
@@ -426,6 +434,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
focusBrowserView = () => {
|
focusBrowserView = () => {
|
||||||
|
log.debug('WindowManager.focusBrowserView');
|
||||||
|
|
||||||
if (this.viewManager) {
|
if (this.viewManager) {
|
||||||
this.viewManager.focus();
|
this.viewManager.focus();
|
||||||
} else {
|
} else {
|
||||||
@@ -453,12 +463,16 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleReactAppInitialized = (e: IpcMainEvent, view: string) => {
|
handleReactAppInitialized = (e: IpcMainEvent, view: string) => {
|
||||||
|
log.debug('WindowManager.handleReactAppInitialized', view);
|
||||||
|
|
||||||
if (this.viewManager) {
|
if (this.viewManager) {
|
||||||
this.viewManager.setServerInitialized(view);
|
this.viewManager.setServerInitialized(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLoadingScreenAnimationFinished = () => {
|
handleLoadingScreenAnimationFinished = () => {
|
||||||
|
log.debug('WindowManager.handleLoadingScreenAnimationFinished');
|
||||||
|
|
||||||
if (this.viewManager) {
|
if (this.viewManager) {
|
||||||
this.viewManager.hideLoadingScreen();
|
this.viewManager.hideLoadingScreen();
|
||||||
}
|
}
|
||||||
@@ -522,6 +536,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleHistory = (event: IpcMainEvent, offset: number) => {
|
handleHistory = (event: IpcMainEvent, offset: number) => {
|
||||||
|
log.debug('WindowManager.handleHistory', offset);
|
||||||
|
|
||||||
if (this.viewManager) {
|
if (this.viewManager) {
|
||||||
const activeView = this.viewManager.getCurrentView();
|
const activeView = this.viewManager.getCurrentView();
|
||||||
if (activeView && activeView.view.webContents.canGoToOffset(offset)) {
|
if (activeView && activeView.view.webContents.canGoToOffset(offset)) {
|
||||||
@@ -573,6 +589,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleBrowserHistoryPush = (e: IpcMainEvent, viewName: string, pathName: string) => {
|
handleBrowserHistoryPush = (e: IpcMainEvent, viewName: string, pathName: string) => {
|
||||||
|
log.debug('WwindowManager.handleBrowserHistoryPush', {viewName, pathName});
|
||||||
|
|
||||||
const currentView = this.viewManager?.views.get(viewName);
|
const currentView = this.viewManager?.views.get(viewName);
|
||||||
const cleanedPathName = currentView?.tab.server.url.pathname === '/' ? pathName : pathName.replace(currentView?.tab.server.url.pathname || '', '');
|
const cleanedPathName = currentView?.tab.server.url.pathname === '/' ? pathName : pathName.replace(currentView?.tab.server.url.pathname || '', '');
|
||||||
const redirectedViewName = urlUtils.getView(`${currentView?.tab.server.url}${cleanedPathName}`, Config.teams)?.name || viewName;
|
const redirectedViewName = urlUtils.getView(`${currentView?.tab.server.url}${cleanedPathName}`, Config.teams)?.name || viewName;
|
||||||
@@ -597,6 +615,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleBrowserHistoryButton = (e: IpcMainEvent, viewName: string) => {
|
handleBrowserHistoryButton = (e: IpcMainEvent, viewName: string) => {
|
||||||
|
log.debug('EindowManager.handleBrowserHistoryButton', viewName);
|
||||||
|
|
||||||
const currentView = this.viewManager?.views.get(viewName);
|
const currentView = this.viewManager?.views.get(viewName);
|
||||||
if (currentView) {
|
if (currentView) {
|
||||||
if (currentView.view.webContents.getURL() === currentView.tab.url.toString()) {
|
if (currentView.view.webContents.getURL() === currentView.tab.url.toString()) {
|
||||||
@@ -614,6 +634,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleAppLoggedIn = (event: IpcMainEvent, viewName: string) => {
|
handleAppLoggedIn = (event: IpcMainEvent, viewName: string) => {
|
||||||
|
log.debug('WindowManager.handleAppLoggedIn', viewName);
|
||||||
|
|
||||||
const view = this.viewManager?.views.get(viewName);
|
const view = this.viewManager?.views.get(viewName);
|
||||||
if (view) {
|
if (view) {
|
||||||
view.isLoggedIn = true;
|
view.isLoggedIn = true;
|
||||||
@@ -622,6 +644,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleAppLoggedOut = (event: IpcMainEvent, viewName: string) => {
|
handleAppLoggedOut = (event: IpcMainEvent, viewName: string) => {
|
||||||
|
log.debug('WindowManager.handleAppLoggedOut', viewName);
|
||||||
|
|
||||||
const view = this.viewManager?.views.get(viewName);
|
const view = this.viewManager?.views.get(viewName);
|
||||||
if (view) {
|
if (view) {
|
||||||
view.isLoggedIn = false;
|
view.isLoggedIn = false;
|
||||||
@@ -637,6 +661,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleGetDesktopSources = async (event: IpcMainEvent, viewName: string, opts: Electron.SourcesOptions) => {
|
handleGetDesktopSources = async (event: IpcMainEvent, viewName: string, opts: Electron.SourcesOptions) => {
|
||||||
|
log.debug('WindowManager.handleGetDesktopSources', {viewName, opts});
|
||||||
|
|
||||||
const view = this.viewManager?.views.get(viewName);
|
const view = this.viewManager?.views.get(viewName);
|
||||||
if (!view) {
|
if (!view) {
|
||||||
return;
|
return;
|
||||||
@@ -654,6 +680,8 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleReloadCurrentView = () => {
|
handleReloadCurrentView = () => {
|
||||||
|
log.debug('WindowManager.handleReloadCurrentView');
|
||||||
|
|
||||||
const view = this.viewManager?.getCurrentView();
|
const view = this.viewManager?.getCurrentView();
|
||||||
if (!view) {
|
if (!view) {
|
||||||
return;
|
return;
|
||||||
|
@@ -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} from 'react-bootstrap';
|
import {FormCheck, Col, FormGroup, FormText, Container, Row, Button, FormControl} from 'react-bootstrap';
|
||||||
import ReactSelect, {ActionMeta, OptionsType} from 'react-select';
|
import ReactSelect, {ActionMeta, OptionsType} from 'react-select';
|
||||||
|
|
||||||
import {debounce} from 'underscore';
|
import {debounce} from 'underscore';
|
||||||
@@ -70,6 +70,7 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
enableHardwareAccelerationRef: React.RefObject<HTMLInputElement>;
|
enableHardwareAccelerationRef: React.RefObject<HTMLInputElement>;
|
||||||
startInFullscreenRef: React.RefObject<HTMLInputElement>;
|
startInFullscreenRef: React.RefObject<HTMLInputElement>;
|
||||||
autoCheckForUpdatesRef: React.RefObject<HTMLInputElement>;
|
autoCheckForUpdatesRef: React.RefObject<HTMLInputElement>;
|
||||||
|
logLevelRef: React.RefObject<HTMLSelectElement>;
|
||||||
|
|
||||||
saveQueue: SaveQueueItem[];
|
saveQueue: SaveQueueItem[];
|
||||||
|
|
||||||
@@ -103,6 +104,7 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
this.startInFullscreenRef = React.createRef();
|
this.startInFullscreenRef = React.createRef();
|
||||||
this.spellCheckerURLRef = React.createRef();
|
this.spellCheckerURLRef = React.createRef();
|
||||||
this.autoCheckForUpdatesRef = React.createRef();
|
this.autoCheckForUpdatesRef = React.createRef();
|
||||||
|
this.logLevelRef = React.createRef();
|
||||||
|
|
||||||
this.saveQueue = [];
|
this.saveQueue = [];
|
||||||
this.selectedSpellCheckerLocales = [];
|
this.selectedSpellCheckerLocales = [];
|
||||||
@@ -290,6 +292,13 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleChangeLogLevel = () => {
|
||||||
|
window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_APP_OPTIONS, {key: 'logLevel', data: this.logLevelRef.current?.value});
|
||||||
|
this.setState({
|
||||||
|
logLevel: this.logLevelRef.current?.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
handleChangeAutoCheckForUpdates = () => {
|
handleChangeAutoCheckForUpdates = () => {
|
||||||
window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_UPDATES, {key: 'autoCheckForUpdates', data: this.autoCheckForUpdatesRef.current?.checked});
|
window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_UPDATES, {key: 'autoCheckForUpdates', data: this.autoCheckForUpdatesRef.current?.checked});
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -432,6 +441,17 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
marginBottom: '4px',
|
marginBottom: '4px',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
logLevelInput: {
|
||||||
|
marginRight: '3px',
|
||||||
|
marginTop: '8px',
|
||||||
|
width: '320px',
|
||||||
|
height: '34px',
|
||||||
|
padding: '0 12px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
fontWeight: 500,
|
||||||
|
},
|
||||||
|
|
||||||
container: {
|
container: {
|
||||||
paddingBottom: '40px',
|
paddingBottom: '40px',
|
||||||
},
|
},
|
||||||
@@ -800,6 +820,27 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
|||||||
<FormText>
|
<FormText>
|
||||||
{'Specify the folder where files will download.'}
|
{'Specify the folder where files will download.'}
|
||||||
</FormText>
|
</FormText>
|
||||||
|
<br/>
|
||||||
|
{'Logging level'}
|
||||||
|
<FormControl
|
||||||
|
style={settingsPage.logLevelInput}
|
||||||
|
as='select'
|
||||||
|
id='inputLogLevel'
|
||||||
|
ref={this.logLevelRef}
|
||||||
|
value={this.state.logLevel}
|
||||||
|
onChange={this.handleChangeLogLevel}
|
||||||
|
>
|
||||||
|
<option value='error'>{'Errors (error)'}</option>
|
||||||
|
<option value='warn'>{'Errors and Warnings (warn)'}</option>
|
||||||
|
<option value='info'>{'Info (info)'}</option>
|
||||||
|
<option value='verbose'>{'Verbose (verbose)'}</option>
|
||||||
|
<option value='debug'>{'Debug (debug)'}</option>
|
||||||
|
<option value='silly'>{'Finest (silly)'}</option>
|
||||||
|
</FormControl>
|
||||||
|
<FormText>
|
||||||
|
{'Logging is helpful for developers and support to isolate issues you may be encountering with the desktop app.'}
|
||||||
|
<br/>{'Increasing the log level increases disk space usage and can impact performance. We recommend only increasing the log level if you are having issues.'}
|
||||||
|
</FormText>
|
||||||
</div>,
|
</div>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -44,6 +44,7 @@ export type ConfigV3 = {
|
|||||||
autoCheckForUpdates?: boolean;
|
autoCheckForUpdates?: boolean;
|
||||||
alwaysMinimize?: boolean;
|
alwaysMinimize?: boolean;
|
||||||
alwaysClose?: boolean;
|
alwaysClose?: boolean;
|
||||||
|
logLevel?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConfigV2 = {
|
export type ConfigV2 = {
|
||||||
|
Reference in New Issue
Block a user