diff --git a/src/common/config/RegistryConfig.test.js b/src/common/config/RegistryConfig.test.js index 6f3d082b..691bad02 100644 --- a/src/common/config/RegistryConfig.test.js +++ b/src/common/config/RegistryConfig.test.js @@ -49,10 +49,6 @@ jest.mock('winreg-utf8', () => { }); }); -jest.mock('electron-log', () => ({ - error: jest.fn(), -})); - describe('common/config/RegistryConfig', () => { it('should initialize correctly', async () => { const originalPlatform = process.platform; diff --git a/src/common/config/index.test.js b/src/common/config/index.test.js index 913777b1..0a087ff5 100644 --- a/src/common/config/index.test.js +++ b/src/common/config/index.test.js @@ -26,12 +26,6 @@ jest.mock('main/Validator', () => ({ 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', () => ({ getDefaultTeamWithTabsFromTeam: (value) => ({ ...value, diff --git a/src/common/config/index.ts b/src/common/config/index.ts index f6d4ec96..7cfb0d91 100644 --- a/src/common/config/index.ts +++ b/src/common/config/index.ts @@ -112,6 +112,8 @@ export class Config extends EventEmitter { */ loadRegistry = (registryData: Partial): void => { + log.verbose('Config.loadRegistry', {registryData}); + this.registryConfigData = registryData; if (this.registryConfigData.teams) { 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 */ setMultiple = (event: Electron.IpcMainEvent, properties: Array<{key: keyof ConfigType; data: ConfigType[keyof ConfigType]}> = []): Partial | undefined => { + log.debug('Config.setMultiple', properties); + if (properties.length) { this.localConfigData = Object.assign({}, this.localConfigData, ...properties.map(({key, data}) => ({[key]: data}))); this.regenerateCombinedConfigData(); @@ -550,6 +554,8 @@ export class Config extends EventEmitter { } handleGetConfiguration = (event: Electron.IpcMainInvokeEvent, option: keyof CombinedConfig) => { + log.debug('Config.handleGetConfiguration', option); + const config = {...this.combinedData}; if (option) { return config[option]; @@ -558,6 +564,8 @@ export class Config extends EventEmitter { } handleGetLocalConfiguration = (event: Electron.IpcMainInvokeEvent, option: keyof ConfigType) => { + log.debug('Config.handleGetLocalConfiguration', option); + const config: Partial = {...this.localConfigData}; config.appName = app.name; config.enableServerManagement = this.combinedData?.enableServerManagement; @@ -569,6 +577,9 @@ export class Config extends EventEmitter { } handleUpdateTeams = (event: Electron.IpcMainInvokeEvent, newTeams: TeamWithTabs[]) => { + log.debug('Config.handleUpdateTeams'); + log.silly('Config.handleUpdateTeams', newTeams); + this.set('teams', newTeams); return this.combinedData!.teams; } @@ -578,6 +589,8 @@ export class Config extends EventEmitter { * @emits 'darkModeChange' */ handleUpdateTheme = () => { + log.debug('Config.handleUpdateTheme'); + if (this.combinedData && this.combinedData.darkMode !== nativeTheme.shouldUseDarkColors) { this.combinedData.darkMode = nativeTheme.shouldUseDarkColors; this.emit('darkModeChange', this.combinedData.darkMode); @@ -602,6 +615,8 @@ const config = new Config(configPath); export default config; ipcMain.on(UPDATE_PATHS, () => { + log.debug('Config.UPDATE_PATHS'); + config.configFilePath = configPath; if (config.combinedData) { config.reload(); diff --git a/src/jestSetup.js b/src/jestSetup.js index babf7347..d52e28aa 100644 --- a/src/jestSetup.js +++ b/src/jestSetup.js @@ -11,3 +11,18 @@ jest.mock('main/constants', () => ({ 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: '', + }, + }, +})); + diff --git a/src/main/AutoLauncher.test.js b/src/main/AutoLauncher.test.js index ee49878d..a0faf8ba 100644 --- a/src/main/AutoLauncher.test.js +++ b/src/main/AutoLauncher.test.js @@ -13,7 +13,6 @@ jest.mock('electron', () => ({ })); jest.mock('electron-is-dev', () => false); -jest.mock('electron-log', () => ({})); describe('main/AutoLauncher', () => { let autoLauncher; diff --git a/src/main/CriticalErrorHandler.test.js b/src/main/CriticalErrorHandler.test.js index 5ba975ca..e9bc29b3 100644 --- a/src/main/CriticalErrorHandler.test.js +++ b/src/main/CriticalErrorHandler.test.js @@ -28,10 +28,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - error: jest.fn(), -})); - jest.mock('fs', () => ({ writeFileSync: jest.fn(), })); diff --git a/src/main/Validator.test.js b/src/main/Validator.test.js index 665144f3..d0ab3972 100644 --- a/src/main/Validator.test.js +++ b/src/main/Validator.test.js @@ -5,10 +5,6 @@ import * as Validator from './Validator'; -jest.mock('electron-log', () => ({ - error: jest.fn(), -})); - describe('main/Validator', () => { describe('validateV0ConfigData', () => { const config = {url: 'http://server-1.com'}; @@ -132,6 +128,7 @@ describe('main/Validator', () => { enableHardwareAcceleration: true, startInFullscreen: false, lastActiveTeam: 0, + logLevel: 'info', minimizeToTray: false, showTrayIcon: false, showUnreadBadge: true, diff --git a/src/main/Validator.ts b/src/main/Validator.ts index cb3275db..b5723f9f 100644 --- a/src/main/Validator.ts +++ b/src/main/Validator.ts @@ -130,6 +130,7 @@ const configDataSchemaV3 = Joi.object({ autoCheckForUpdates: Joi.boolean().default(true), alwaysMinimize: 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'}; diff --git a/src/main/allowProtocolDialog.test.js b/src/main/allowProtocolDialog.test.js index 698ee12c..06032eee 100644 --- a/src/main/allowProtocolDialog.test.js +++ b/src/main/allowProtocolDialog.test.js @@ -31,10 +31,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - error: jest.fn(), -})); - jest.mock('../../electron-builder.json', () => ({ protocols: [{ name: 'Mattermost', diff --git a/src/main/app/app.test.js b/src/main/app/app.test.js index 634d1f5c..35239096 100644 --- a/src/main/app/app.test.js +++ b/src/main/app/app.test.js @@ -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', () => ({ getDeeplinkingURL: jest.fn(), openDeepLink: jest.fn(), diff --git a/src/main/app/app.ts b/src/main/app/app.ts index e75d1ba3..16b0dd17 100644 --- a/src/main/app/app.ts +++ b/src/main/app/app.ts @@ -21,6 +21,8 @@ export const certificateErrorCallbacks = new Map(); // activate first app instance, subsequent instances will quit themselves export function handleAppSecondInstance(event: Event, argv: string[]) { + log.debug('App.handleAppSecondInstance', argv); + // Protocol handler for win32 // argv: An array of the second instance’s (command line / deep linked) arguments const deeplinkingUrl = getDeeplinkingURL(argv); @@ -28,6 +30,8 @@ export function handleAppSecondInstance(event: Event, argv: string[]) { } export function handleAppWindowAllClosed() { + log.debug('App.handleAppWindowAllClosed'); + // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { @@ -36,6 +40,8 @@ export function handleAppWindowAllClosed() { } export function handleAppBrowserWindowCreated(event: Event, newWindow: BrowserWindow) { + log.debug('App.handleAppBrowserWindowCreated'); + // Screen cannot be required before app is ready resizeScreen(newWindow); } @@ -57,6 +63,8 @@ export function handleAppWillFinishLaunching() { } export function handleAppBeforeQuit() { + log.debug('App.handleAppBeforeQuit'); + // Make sure tray icon gets removed if the user exits via CTRL-Q destroyTray(); 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) { + log.verbose('App.handleAppCertificateError', {url, error, certificate}); + const parsedURL = urlUtils.parseURL(url); if (!parsedURL) { return; diff --git a/src/main/app/config.test.js b/src/main/app/config.test.js index 48167f4f..d49c51d7 100644 --- a/src/main/app/config.test.js +++ b/src/main/app/config.test.js @@ -8,6 +8,8 @@ import Config from 'common/config'; import {handleConfigUpdate} from 'main/app/config'; import {addNewServerModalWhenMainWindowIsShown} from 'main/app/intercom'; +import {setLoggingLevel} from 'main/app/utils'; + import WindowManager from 'main/windows/windowManager'; import AutoLauncher from 'main/AutoLauncher'; @@ -22,15 +24,12 @@ jest.mock('electron', () => ({ on: jest.fn(), }, })); -jest.mock('electron-log', () => ({ - info: jest.fn(), - error: jest.fn(), -})); jest.mock('main/app/utils', () => ({ handleUpdateMenuEvent: jest.fn(), updateSpellCheckerLocales: jest.fn(), updateServerInfos: jest.fn(), + setLoggingLevel: jest.fn(), })); jest.mock('main/app/intercom', () => ({ addNewServerModalWhenMainWindowIsShown: jest.fn(), @@ -105,5 +104,12 @@ describe('main/app/config', () => { value: originalPlatform, }); }); + + it('should set logging level correctly', () => { + handleConfigUpdate({logLevel: 'info'}); + expect(setLoggingLevel).toBeCalledWith('info'); + handleConfigUpdate({logLevel: 'debug'}); + expect(setLoggingLevel).toBeCalledWith('debug'); + }); }); }); diff --git a/src/main/app/config.ts b/src/main/app/config.ts index 4b668ff7..20997536 100644 --- a/src/main/app/config.ts +++ b/src/main/app/config.ts @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import {app, ipcMain} from 'electron'; -import log from 'electron-log'; +import log, {LogLevel} from 'electron-log'; import {CombinedConfig} from 'types/config'; @@ -15,7 +15,7 @@ import {refreshTrayImages} from 'main/tray/tray'; import WindowManager from 'main/windows/windowManager'; import {addNewServerModalWhenMainWindowIsShown} from './intercom'; -import {handleUpdateMenuEvent, updateServerInfos, updateSpellCheckerLocales} from './utils'; +import {handleUpdateMenuEvent, setLoggingLevel, updateServerInfos, updateSpellCheckerLocales} from './utils'; let didCheckForAddServerModal = false; @@ -24,6 +24,9 @@ let didCheckForAddServerModal = false; // export function handleConfigUpdate(newConfig: CombinedConfig) { + log.debug('App.Config.handleConfigUpdate'); + log.silly('App.Config.handleConfigUpdate', newConfig); + if (!newConfig) { return; } @@ -62,11 +65,16 @@ export function handleConfigUpdate(newConfig: CombinedConfig) { } } + log.info('Log level set to:', newConfig.logLevel); + setLoggingLevel(newConfig.logLevel as LogLevel); + handleUpdateMenuEvent(); ipcMain.emit(EMIT_CONFIGURATION, true, newConfig); } export function handleDarkModeChange(darkMode: boolean) { + log.debug('App.Config.handleDarkModeChange', darkMode); + refreshTrayImages(Config.trayIconTheme); WindowManager.sendToRenderer(DARK_MODE_CHANGE, darkMode); WindowManager.updateLoadingScreenDarkMode(darkMode); diff --git a/src/main/app/initialize.test.js b/src/main/app/initialize.test.js index 36118235..b513f671 100644 --- a/src/main/app/initialize.test.js +++ b/src/main/app/initialize.test.js @@ -63,12 +63,6 @@ jest.mock('electron-devtools-installer', () => { const isDev = false; jest.mock('electron-is-dev', () => isDev); -jest.mock('electron-log', () => ({ - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), -})); - jest.mock('../../../electron-builder.json', () => ([ { name: 'Mattermost', @@ -245,7 +239,7 @@ describe('main/app/initialize', () => { path.resolve.mockImplementation((base, p) => `${base}/${p}`); session.defaultSession.on.mockImplementation((event, cb) => { if (event === 'will-download') { - cb(null, item, {id: 0}); + cb(null, item, {id: 0, getURL: jest.fn()}); } }); diff --git a/src/main/app/initialize.ts b/src/main/app/initialize.ts index 72975447..a63cbb21 100644 --- a/src/main/app/initialize.ts +++ b/src/main/app/initialize.ts @@ -295,6 +295,7 @@ function initializeAfterAppReady() { if (typeof Config.canUpgrade === 'undefined') { // windows might not be ready, so we have to wait until it is Config.once('update', () => { + log.debug('Initialize.checkForUpdates'); if (Config.canUpgrade && Config.autoCheckForUpdates) { setTimeout(() => { updateManager.checkForUpdates(false); @@ -342,6 +343,7 @@ function initializeAfterAppReady() { // listen for status updates and pass on to renderer UserActivityMonitor.on('status', (status) => { + log.debug('Initialize.UserActivityMonitor.on(status)', status); WindowManager.sendToMattermostViews(USER_ACTIVITY_UPDATE, status); }); @@ -354,6 +356,7 @@ function initializeAfterAppReady() { setupBadge(); defaultSession.on('will-download', (event, item, webContents) => { + log.debug('Initialize.will-download', {item, sourceURL: webContents.getURL()}); const filename = item.getFilename(); const fileElements = filename.split('.'); const filters = []; diff --git a/src/main/app/intercom.ts b/src/main/app/intercom.ts index 77bf75b2..2c9991a2 100644 --- a/src/main/app/intercom.ts +++ b/src/main/app/intercom.ts @@ -19,6 +19,8 @@ import {handleAppBeforeQuit} from './app'; import {updateServerInfos} from './utils'; export function handleReloadConfig() { + log.debug('Intercom.handleReloadConfig'); + Config.reload(); WindowManager.handleUpdateConfig(); } @@ -38,14 +40,18 @@ export function handleQuit(e: IpcMainEvent, reason: string, stack: string) { } export function handleSwitchServer(event: IpcMainEvent, serverName: string) { + log.silly('Intercom.handleSwitchServer', serverName); WindowManager.switchServer(serverName); } export function handleSwitchTab(event: IpcMainEvent, serverName: string, tabName: string) { + log.silly('Intercom.handleSwitchTab', {serverName, tabName}); WindowManager.switchTab(serverName, tabName); } export function handleCloseTab(event: IpcMainEvent, serverName: string, tabName: string) { + log.debug('Intercom.handleCloseTab', {serverName, tabName}); + const teams = Config.teams; teams.forEach((team) => { 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) { + log.debug('Intercom.handleOpenTab', {serverName, tabName}); + const teams = Config.teams; teams.forEach((team) => { if (team.name === serverName) { @@ -83,6 +91,7 @@ export function addNewServerModalWhenMainWindowIsShown() { handleNewServerModal(); } else { mainWindow.once('show', () => { + log.debug('Intercom.addNewServerModalWhenMainWindowIsShown.show'); handleNewServerModal(); }); } @@ -90,6 +99,8 @@ export function addNewServerModalWhenMainWindowIsShown() { } export function handleNewServerModal() { + log.debug('Intercom.handleNewServerModal'); + const html = getLocalURLString('newServer.html'); const modalPreload = getLocalPreload('modalPreload.js'); @@ -120,6 +131,8 @@ export function handleNewServerModal() { } export function handleEditServerModal(e: IpcMainEvent, name: string) { + log.debug('Intercom.handleEditServerModal', name); + const html = getLocalURLString('editServer.html'); const modalPreload = getLocalPreload('modalPreload.js'); @@ -151,6 +164,8 @@ export function handleEditServerModal(e: IpcMainEvent, name: string) { } export function handleRemoveServerModal(e: IpcMainEvent, name: string) { + log.debug('Intercom.handleRemoveServerModal', name); + const html = getLocalURLString('removeServer.html'); 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) { + log.debug('Intercom.handleMentionNotification', {title, body, channel, teamId, url, silent, data}); displayMention(title, body, channel, teamId, url, silent, event.sender, data); } export function handleOpenAppMenu() { + log.debug('Intercom.handleOpenAppMenu'); + const windowMenu = Menu.getApplicationMenu(); if (!windowMenu) { log.error('No application menu found'); @@ -206,6 +224,8 @@ export function handleOpenAppMenu() { } export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom: string) { + log.debug('Intercom.handleSelectDownload', startFrom); + const message = 'Specify the folder where files will download'; const result = await dialog.showOpenDialog({defaultPath: startFrom || Config.downloadLocation, message, @@ -215,6 +235,8 @@ export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom: } export function handleUpdateLastActive(event: IpcMainEvent, serverName: string, viewName: string) { + log.debug('Intercom.handleUpdateLastActive', {serverName, viewName}); + const teams = Config.teams; teams.forEach((team) => { if (team.name === serverName) { diff --git a/src/main/app/utils.test.js b/src/main/app/utils.test.js index 31367859..bf17e6a7 100644 --- a/src/main/app/utils.test.js +++ b/src/main/app/utils.test.js @@ -35,11 +35,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - info: jest.fn(), - error: jest.fn(), -})); - jest.mock('common/config', () => ({ set: jest.fn(), })); diff --git a/src/main/app/utils.ts b/src/main/app/utils.ts index 72c584f8..fa60616a 100644 --- a/src/main/app/utils.ts +++ b/src/main/app/utils.ts @@ -6,7 +6,7 @@ import fs from 'fs'; import path from 'path'; 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 {RemoteInfo} from 'types/server'; @@ -83,6 +83,8 @@ function openExtraTabs(data: Array, team: TeamW } export function handleUpdateMenuEvent() { + log.debug('Utils.handleUpdateMenuEvent'); + const aMenu = createAppMenu(Config, updateManager); Menu.setApplicationMenu(aMenu); aMenu.addListener('menu-will-close', WindowManager.focusBrowserView); @@ -152,6 +154,7 @@ function getValidWindowPosition(state: Rectangle) { export function resizeScreen(browserWindow: BrowserWindow) { function handle() { + log.debug('Utils.resizeScreen.handle'); const position = browserWindow.getPosition(); const size = browserWindow.getSize(); const validPosition = getValidWindowPosition({ @@ -172,6 +175,7 @@ export function resizeScreen(browserWindow: BrowserWindow) { } function flushCookiesStore(session: Session) { + log.debug('Utils.flushCookiesStore'); session.cookies.flushStore().catch((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); } } + +export function setLoggingLevel(level: LevelOption) { + log.transports.console.level = level; + log.transports.file.level = level; +} diff --git a/src/main/appState.ts b/src/main/appState.ts index 3996a7b8..e18836d6 100644 --- a/src/main/appState.ts +++ b/src/main/appState.ts @@ -4,6 +4,8 @@ import events from 'events'; 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 WindowManager from './windows/windowManager'; @@ -21,6 +23,7 @@ const emitMentions = (serverName: string) => { const isExpired = getIsExpired(serverName); WindowManager.sendToRenderer(UPDATE_MENTIONS, serverName, newMentions, newUnreads, isExpired); + log.silly('AppState.emitMentions', {serverName, isExpired, newMentions, newUnreads}); emitStatus(); }; @@ -117,5 +120,8 @@ const setSessionExpired = (serverName: string, expired: boolean) => { }; ipcMain.on(SESSION_EXPIRED, (event, isExpired, serverName) => { + if (isExpired) { + log.debug('SESSION_EXPIRED', {isExpired, serverName}); + } setSessionExpired(serverName, isExpired); }); diff --git a/src/main/authManager.test.js b/src/main/authManager.test.js index 4c346a44..a9f7c5a6 100644 --- a/src/main/authManager.test.js +++ b/src/main/authManager.test.js @@ -82,10 +82,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - error: jest.fn(), -})); - jest.mock('main/trustedOrigins', () => ({ addPermission: jest.fn(), checkPermission: (url) => { diff --git a/src/main/authManager.ts b/src/main/authManager.ts index 93057e7c..ecce0012 100644 --- a/src/main/authManager.ts +++ b/src/main/authManager.ts @@ -32,6 +32,8 @@ export class AuthManager { } handleAppLogin = (event: Event, webContents: WebContents, request: AuthenticationResponseDetails, authInfo: AuthInfo, callback?: (username?: string, password?: string) => void) => { + log.verbose('AuthManager.handleAppLogin', {request, authInfo}); + event.preventDefault(); const parsedURL = urlUtils.parseURL(request.url); if (!parsedURL) { diff --git a/src/main/autoUpdater.test.js b/src/main/autoUpdater.test.js index 1c908aec..aa86bbd5 100644 --- a/src/main/autoUpdater.test.js +++ b/src/main/autoUpdater.test.js @@ -22,15 +22,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - error: jest.fn(), - info: jest.fn(), - transports: { - file: { - level: '', - }, - }, -})); jest.mock('electron-updater', () => ({ autoUpdater: { on: jest.fn(), diff --git a/src/main/badge.ts b/src/main/badge.ts index 32f8102d..6d79fa67 100644 --- a/src/main/badge.ts +++ b/src/main/badge.ts @@ -3,6 +3,7 @@ // See LICENSE.txt for license information. import {app} from 'electron'; +import log from 'electron-log'; import {UPDATE_BADGE} from 'common/communication'; @@ -49,6 +50,8 @@ function showBadgeLinux(sessionExpired: boolean, mentionCount: number) { } function showBadge(sessionExpired: boolean, mentionCount: number, showUnreadBadge: boolean) { + log.silly('Badge.showBadge', {sessionExpired, mentionCount, showUnreadBadge}); + switch (process.platform) { case 'win32': showBadgeWindows(sessionExpired, mentionCount, showUnreadBadge); diff --git a/src/main/certificateManager.test.js b/src/main/certificateManager.test.js index 507fd875..d58e8bf9 100644 --- a/src/main/certificateManager.test.js +++ b/src/main/certificateManager.test.js @@ -6,11 +6,6 @@ import WindowManager from 'main/windows/windowManager'; import ModalManager from 'main/views/modalManager'; import {CertificateManager} from 'main/certificateManager'; -jest.mock('electron-log', () => ({ - info: jest.fn(), - error: jest.fn(), -})); - jest.mock('main/windows/windowManager', () => ({ getMainWindow: jest.fn().mockImplementation(() => ({})), })); diff --git a/src/main/certificateManager.ts b/src/main/certificateManager.ts index 7fe27cc5..efb36c2d 100644 --- a/src/main/certificateManager.ts +++ b/src/main/certificateManager.ts @@ -25,6 +25,8 @@ export class CertificateManager { } handleSelectCertificate = (event: Event, webContents: WebContents, url: string, list: Certificate[], callback: (certificate?: Certificate | undefined) => void) => { + log.verbose('CertificateManager.handleSelectCertificate', url, list); + if (list.length > 1) { event.preventDefault(); // prevent the app from getting the first certificate available diff --git a/src/main/certificateStore.ts b/src/main/certificateStore.ts index 986904dd..bf672710 100644 --- a/src/main/certificateStore.ts +++ b/src/main/certificateStore.ts @@ -6,6 +6,7 @@ import fs from 'fs'; import {Certificate, ipcMain} from 'electron'; +import log from 'electron-log'; import {ComparableCertificate} from 'types/certificate'; @@ -85,5 +86,6 @@ let certificateStore = new CertificateStore(certificateStorePath); export default certificateStore; ipcMain.on(UPDATE_PATHS, () => { + log.debug('certificateStore.UPDATE_PATHS'); certificateStore = new CertificateStore(certificateStorePath); }); diff --git a/src/main/notifications/index.test.js b/src/main/notifications/index.test.js index 30020bf7..052d495d 100644 --- a/src/main/notifications/index.test.js +++ b/src/main/notifications/index.test.js @@ -51,11 +51,6 @@ jest.mock('electron', () => { }; }); -jest.mock('electron-log', () => ({ - info: jest.fn(), - error: jest.fn(), -})); - jest.mock('../windows/windowManager', () => ({ getServerNameByWebContentsId: () => 'server_name', sendToRenderer: jest.fn(), diff --git a/src/main/notifications/index.ts b/src/main/notifications/index.ts index c94f0235..cf69a357 100644 --- a/src/main/notifications/index.ts +++ b/src/main/notifications/index.ts @@ -18,6 +18,8 @@ import {NewVersionNotification, UpgradeNotification} from './Upgrade'; 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) { + log.debug('Notifications.displayMention', {title, body, channel, teamId, url, silent, data}); + if (!Notification.isSupported()) { log.error('notification not supported'); return; @@ -35,6 +37,8 @@ export function displayMention(title: string, body: string, channel: {id: string const mentionKey = `${mention.teamId}:${mention.channel.id}`; mention.on('show', () => { + log.debug('Notifications.displayMention.show'); + // On Windows, manually dismiss notifications from the same channel and only show the latest one if (process.platform === 'win32') { 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) { + log.debug('Notifications.displayDownloadCompleted', {fileName, path, serverName}); + if (!Notification.isSupported()) { log.error('notification not supported'); return; diff --git a/src/main/server/serverAPI.test.js b/src/main/server/serverAPI.test.js index f500ff6b..c02f7123 100644 --- a/src/main/server/serverAPI.test.js +++ b/src/main/server/serverAPI.test.js @@ -14,10 +14,6 @@ const testData = { value: 'some more data', }; -jest.mock('electron-log', () => ({ - error: jest.fn(), -})); - jest.mock('electron', () => ({ net: { request: jest.fn().mockImplementation(({url}) => ({ diff --git a/src/main/server/serverAPI.ts b/src/main/server/serverAPI.ts index 6a2e86ac..4665d649 100644 --- a/src/main/server/serverAPI.ts +++ b/src/main/server/serverAPI.ts @@ -34,8 +34,10 @@ export async function getServerAPI(url: URL, isAuthenticated: boolean, onSucc if (onSuccess) { req.on('response', (response: Electron.IncomingMessage) => { + log.silly('getServerAPI.response', response); if (response.statusCode === 200) { response.on('data', (chunk: Buffer) => { + log.silly('getServerAPI.response.data', `${chunk}`); const raw = `${chunk}`; try { const data = JSON.parse(raw) as T; diff --git a/src/main/server/serverInfo.ts b/src/main/server/serverInfo.ts index 7d17e9e6..4ca80ca8 100644 --- a/src/main/server/serverInfo.ts +++ b/src/main/server/serverInfo.ts @@ -1,6 +1,8 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import log from 'electron-log'; + import {RemoteInfo} from 'types/server'; import {MattermostServer} from 'common/servers/MattermostServer'; @@ -53,6 +55,8 @@ export class ServerInfo { } trySendRemoteInfo = () => { + log.debug('ServerInfo.trySendRemoteInfo', this.server.name, this.remoteInfo); + if (this.isRemoteInfoRetrieved()) { this.onRetrievedRemoteInfo?.(this.remoteInfo); } diff --git a/src/main/trustedOrigins.test.js b/src/main/trustedOrigins.test.js index cdd3bb73..6b43e14f 100644 --- a/src/main/trustedOrigins.test.js +++ b/src/main/trustedOrigins.test.js @@ -18,10 +18,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - error: jest.fn(), -})); - function mockTOS(fileName, returnvalue) { const tos = new TrustedOriginsStore(fileName); tos.readFromFile = () => { diff --git a/src/main/trustedOrigins.ts b/src/main/trustedOrigins.ts index 376e8b4f..b45cc7de 100644 --- a/src/main/trustedOrigins.ts +++ b/src/main/trustedOrigins.ts @@ -117,6 +117,7 @@ const trustedOriginsStore = new TrustedOriginsStore(trustedOriginsStoreFile); export default trustedOriginsStore; ipcMain.on(UPDATE_PATHS, () => { + log.debug('trustedOriginsStore.UPDATE_PATHS'); trustedOriginsStore.storeFile = trustedOriginsStoreFile; if (trustedOriginsStore.data) { trustedOriginsStore.load(); diff --git a/src/main/views/MattermostView.test.js b/src/main/views/MattermostView.test.js index 481c31db..5f6c7fde 100644 --- a/src/main/views/MattermostView.test.js +++ b/src/main/views/MattermostView.test.js @@ -29,11 +29,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - info: jest.fn(), - error: jest.fn(), -})); - jest.mock('../windows/windowManager', () => ({ sendToRenderer: jest.fn(), focusThreeDotMenu: jest.fn(), diff --git a/src/main/views/MattermostView.ts b/src/main/views/MattermostView.ts index ce7317fc..9d2743fc 100644 --- a/src/main/views/MattermostView.ts +++ b/src/main/views/MattermostView.ts @@ -101,6 +101,8 @@ export class MattermostView extends EventEmitter { } 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 const timeout = setInterval(() => { if (!this.view.webContents.isLoading()) { @@ -327,6 +329,8 @@ export class MattermostView extends EventEmitter { }; handleInputEvents = (_: Event, input: Input) => { + log.silly('MattermostView.handleInputEvents', {tabName: this.tab.name, input}); + this.registerAltKeyPressed(input); if (this.isAltKeyReleased(input)) { @@ -335,6 +339,8 @@ export class MattermostView extends EventEmitter { } 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); if (isUrlTeamUrl) { this.setBounds(getWindowBoundaries(this.window)); @@ -348,6 +354,7 @@ export class MattermostView extends EventEmitter { } 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)) { this.emit(UPDATE_TARGET_URL, url); } @@ -356,6 +363,8 @@ export class MattermostView extends EventEmitter { titleParser = /(\((\d+)\) )?(\* )?/g handleTitleUpdate = (e: Event, title: string) => { + log.debug('MattermostView.handleTitleUpdate', {tabName: this.tab.name, title}); + this.updateMentionsFromTitle(title); } @@ -379,6 +388,8 @@ export class MattermostView extends EventEmitter { } handleFaviconUpdate = (e: Event, favicons: string[]) => { + log.silly('MattermostView.handleFaviconUpdate', {tabName: this.tab.name, favicons}); + if (!this.usesAsteriskForUnreads) { // if unread state is stored for that favicon, retrieve value. // 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, // 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) => { + log.silly('MattermostView.handleFaviconIsUnread', {favicon, viewName, result}); + if (this.tab && viewName === this.tab.name) { appState.updateUnreads(viewName, result); } diff --git a/src/main/views/modalManager.test.js b/src/main/views/modalManager.test.js index 1261c11d..76a33a9e 100644 --- a/src/main/views/modalManager.test.js +++ b/src/main/views/modalManager.test.js @@ -15,8 +15,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({})); - jest.mock('./modalView', () => ({ ModalView: jest.fn(), })); diff --git a/src/main/views/modalManager.ts b/src/main/views/modalManager.ts index 0c02d8c0..3019fa5d 100644 --- a/src/main/views/modalManager.ts +++ b/src/main/views/modalManager.ts @@ -4,6 +4,8 @@ import {BrowserWindow, ipcMain} from 'electron'; import {IpcMainEvent, IpcMainInvokeEvent} from 'electron/main'; +import log from 'electron-log'; + import {CombinedConfig} from 'types/config'; import { @@ -70,6 +72,8 @@ export class ModalManager { } handleInfoRequest = (event: IpcMainInvokeEvent) => { + log.debug('ModalManager.handleInfoRequest'); + const requestModal = this.findModalByCaller(event); if (requestModal) { return requestModal.handleInfoRequest(); @@ -91,6 +95,8 @@ export class ModalManager { } handleModalFinished = (mode: 'resolve' | 'reject', event: IpcMainEvent, data: unknown) => { + log.debug('ModalManager.handleModalFinished', {mode, data}); + const requestModal = this.findModalByCaller(event); if (requestModal) { if (mode === 'resolve') { @@ -122,6 +128,8 @@ export class ModalManager { } handleResizeModal = (event: IpcMainEvent, bounds: Electron.Rectangle) => { + log.debug('ModalManager.handleResizeModal', bounds); + if (this.modalQueue.length) { const currentModal = this.modalQueue[0]; currentModal.view.setBounds(getAdjustedWindowBoundaries(bounds.width, bounds.height)); @@ -135,6 +143,10 @@ export class ModalManager { } handleEmitConfiguration = (event: IpcMainEvent, config: CombinedConfig) => { + if (this.modalQueue.length) { + log.debug('ModalManager.handleEmitConfiguration'); + } + this.modalQueue.forEach((modal) => { modal.view.webContents.send(DARK_MODE_CHANGE, config.darkMode); }); diff --git a/src/main/views/modalView.test.js b/src/main/views/modalView.test.js index 6670ac33..ed78174e 100644 --- a/src/main/views/modalView.test.js +++ b/src/main/views/modalView.test.js @@ -22,10 +22,6 @@ jest.mock('electron', () => ({ })), })); -jest.mock('electron-log', () => ({ - info: jest.fn(), -})); - jest.mock('../contextMenu', () => jest.fn()); jest.mock('../utils', () => ({ diff --git a/src/main/views/teamDropdownView.ts b/src/main/views/teamDropdownView.ts index 445307e6..b293c8e2 100644 --- a/src/main/views/teamDropdownView.ts +++ b/src/main/views/teamDropdownView.ts @@ -2,6 +2,9 @@ // See LICENSE.txt for license information. import {BrowserView, BrowserWindow, ipcMain, IpcMainEvent} from 'electron'; + +import log from 'electron-log'; + import {CombinedConfig, TeamWithTabs} from 'types/config'; import { @@ -66,6 +69,8 @@ export default class TeamDropdownView { } updateConfig = (event: IpcMainEvent, config: CombinedConfig) => { + log.silly('TeamDropdownView.config', {config}); + this.teams = config.teams; this.darkMode = config.darkMode; this.enableServerManagement = config.enableServerManagement; @@ -74,11 +79,15 @@ export default class TeamDropdownView { } updateActiveTeam = (event: IpcMainEvent, name: string) => { + log.silly('TeamDropdownView.updateActiveTeam', {name}); + this.activeTeam = name; this.updateDropdown(); } updateMentions = (expired: Map, mentions: Map, unreads: Map) => { + log.silly('TeamDropdownView.updateMentions', {expired, mentions, unreads}); + this.unreads = unreads; this.mentions = mentions; this.expired = expired; @@ -91,6 +100,8 @@ export default class TeamDropdownView { } updateDropdown = () => { + log.silly('TeamDropdownView.updateDropdown'); + this.view.webContents.send( UPDATE_TEAMS_DROPDOWN, this.teams, @@ -106,6 +117,8 @@ export default class TeamDropdownView { } handleOpen = () => { + log.debug('TeamDropdownView.handleOpen'); + if (!this.bounds) { return; } @@ -117,12 +130,16 @@ export default class TeamDropdownView { } handleClose = () => { + log.debug('TeamDropdownView.handleClose'); + this.view.setBounds(this.getBounds(0, 0)); WindowManager.sendToRenderer(CLOSE_TEAMS_DROPDOWN); this.isOpen = false; } handleReceivedMenuSize = (event: IpcMainEvent, width: number, height: number) => { + log.silly('TeamDropdownView.handleReceivedMenuSize', {width, height}); + this.bounds = this.getBounds(width, height); if (this.isOpen) { this.view.setBounds(this.bounds); diff --git a/src/main/views/viewManager.test.js b/src/main/views/viewManager.test.js index 446ee620..4a79ef8c 100644 --- a/src/main/views/viewManager.test.js +++ b/src/main/views/viewManager.test.js @@ -27,11 +27,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - warn: jest.fn(), - error: jest.fn(), -})); - jest.mock('common/tabs/TabView', () => ({ getServerView: jest.fn(), getTabViewName: jest.fn(), diff --git a/src/main/views/viewManager.ts b/src/main/views/viewManager.ts index bbd998c4..f44a556f 100644 --- a/src/main/views/viewManager.ts +++ b/src/main/views/viewManager.ts @@ -173,6 +173,8 @@ export class ViewManager { } showByName = (name: string) => { + log.debug('viewManager.showByName', name); + const newView = this.views.get(name); if (newView) { if (newView.isVisible) { @@ -218,6 +220,8 @@ export class ViewManager { } activateView = (viewName: string) => { + log.debug('viewManager.activateView', viewName); + if (this.currentView === viewName) { this.showByName(this.currentView); } @@ -230,6 +234,8 @@ export class ViewManager { } finishLoading = (server: string) => { + log.debug('viewManager.finishLoading', server); + const view = this.views.get(server); if (view && this.getCurrentView() === view) { this.showByName(this.currentView!); @@ -255,6 +261,8 @@ export class ViewManager { } failLoading = (tabName: string) => { + log.debug('viewManager.failLoading', tabName); + this.fadeLoadingScreen(); if (this.currentView === tabName) { this.getCurrentView()?.hide(); @@ -293,6 +301,8 @@ export class ViewManager { } showURLView = (url: URL | string) => { + log.silly('viewManager.showURLView', url); + if (this.urlViewCancel) { this.urlViewCancel(); } @@ -326,6 +336,8 @@ export class ViewManager { }; const adjustWidth = (event: IpcMainEvent, width: number) => { + log.silly('showURLView.adjustWidth', width); + urlView.setBounds({ x: 0, y: boundaries.height - URL_VIEW_HEIGHT, @@ -422,6 +434,8 @@ export class ViewManager { } deeplinkSuccess = (viewName: string) => { + log.debug('viewManager.deeplinkSuccess', viewName); + const view = this.views.get(viewName); if (!view) { return; diff --git a/src/main/views/webContentEvents.test.js b/src/main/views/webContentEvents.test.js index a1f54550..a480a2a4 100644 --- a/src/main/views/webContentEvents.test.js +++ b/src/main/views/webContentEvents.test.js @@ -27,11 +27,6 @@ jest.mock('electron', () => ({ })), })); -jest.mock('electron-log', () => ({ - info: jest.fn(), - warn: jest.fn(), -})); - jest.mock('../allowProtocolDialog', () => ({})); jest.mock('../windows/windowManager', () => ({ showMainWindow: jest.fn(), diff --git a/src/main/views/webContentEvents.ts b/src/main/views/webContentEvents.ts index db5d9786..675a52bc 100644 --- a/src/main/views/webContentEvents.ts +++ b/src/main/views/webContentEvents.ts @@ -47,6 +47,8 @@ export class WebContentsEventManager { generateWillNavigate = (getServersFunction: () => TeamWithTabs[]) => { return (event: Event & {sender: WebContents}, url: string) => { + log.debug('webContentEvents.will-navigate', {webContentsId: event.sender.id, url}); + const contentID = event.sender.id; const parsedURL = urlUtils.parseURL(url)!; const configServers = getServersFunction(); @@ -77,6 +79,8 @@ export class WebContentsEventManager { generateDidStartNavigation = (getServersFunction: () => TeamWithTabs[]) => { return (event: Event & {sender: WebContents}, url: string) => { + log.debug('webContentEvents.did-start-navigation', {webContentsId: event.sender.id, url}); + const serverList = getServersFunction(); const contentID = event.sender.id; const parsedURL = urlUtils.parseURL(url)!; @@ -103,6 +107,8 @@ export class WebContentsEventManager { generateNewWindowListener = (getServersFunction: () => TeamWithTabs[], spellcheck?: boolean) => { return (details: Electron.HandlerDetails): {action: 'deny' | 'allow'} => { + log.debug('webContentEvents.new-window', details.url); + const parsedURL = urlUtils.parseURL(details.url); if (!parsedURL) { log.warn(`Ignoring non-url ${details.url}`); diff --git a/src/main/windows/mainWindow.test.js b/src/main/windows/mainWindow.test.js index 3483768d..a44b7045 100644 --- a/src/main/windows/mainWindow.test.js +++ b/src/main/windows/mainWindow.test.js @@ -49,8 +49,6 @@ jest.mock('common/utils/util', () => ({ isVersionGreaterThanOrEqualTo: jest.fn(), })); -jest.mock('electron-log', () => ({})); - jest.mock('global', () => ({ willAppQuit: false, })); diff --git a/src/main/windows/mainWindow.ts b/src/main/windows/mainWindow.ts index 3b82fe8a..c9e83a62 100644 --- a/src/main/windows/mainWindow.ts +++ b/src/main/windows/mainWindow.ts @@ -142,6 +142,8 @@ function createMainWindow(options: {linuxAppIcon: string; fullscreen?: boolean}) }); mainWindow.on('close', (event) => { + log.debug('MainWindow.on.close'); + if (global.willAppQuit) { // when [Ctrl|Cmd]+Q saveWindowState(boundsInfoPath, mainWindow); } else { // Minimize or hide the window for close button. diff --git a/src/main/windows/windowManager.test.js b/src/main/windows/windowManager.test.js index dcbaf00b..2ef14543 100644 --- a/src/main/windows/windowManager.test.js +++ b/src/main/windows/windowManager.test.js @@ -40,11 +40,6 @@ jest.mock('electron', () => ({ }, })); -jest.mock('electron-log', () => ({ - error: jest.fn(), - info: jest.fn(), -})); - jest.mock('common/config', () => ({})); jest.mock('common/utils/url', () => ({ diff --git a/src/main/windows/windowManager.ts b/src/main/windows/windowManager.ts index abdd5d39..8ef00e96 100644 --- a/src/main/windows/windowManager.ts +++ b/src/main/windows/windowManager.ts @@ -79,6 +79,8 @@ export class WindowManager { } showSettingsWindow = () => { + log.debug('WindowManager.showSettingsWindow'); + if (this.settingsWindow) { this.settingsWindow.show(); } else { @@ -95,6 +97,8 @@ export class WindowManager { } showMainWindow = (deeplinkingURL?: string | URL) => { + log.debug('WindowManager.showMainWindow', deeplinkingURL); + if (this.mainWindow) { if (this.mainWindow.isVisible()) { this.mainWindow.focus(); @@ -169,6 +173,8 @@ export class WindowManager { } handleResizeMainWindow = () => { + log.debug('WindowManager.handleResizeMainWindow'); + if (!(this.viewManager && this.mainWindow)) { return; } @@ -350,6 +356,8 @@ export class WindowManager { } handleDoubleClick = (e: IpcMainEvent, windowType?: string) => { + log.debug('WindowManager.handleDoubleClick', windowType); + let action = 'Maximize'; if (process.platform === 'darwin') { action = systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string'); @@ -426,6 +434,8 @@ export class WindowManager { } focusBrowserView = () => { + log.debug('WindowManager.focusBrowserView'); + if (this.viewManager) { this.viewManager.focus(); } else { @@ -453,12 +463,16 @@ export class WindowManager { } handleReactAppInitialized = (e: IpcMainEvent, view: string) => { + log.debug('WindowManager.handleReactAppInitialized', view); + if (this.viewManager) { this.viewManager.setServerInitialized(view); } } handleLoadingScreenAnimationFinished = () => { + log.debug('WindowManager.handleLoadingScreenAnimationFinished'); + if (this.viewManager) { this.viewManager.hideLoadingScreen(); } @@ -522,6 +536,8 @@ export class WindowManager { } handleHistory = (event: IpcMainEvent, offset: number) => { + log.debug('WindowManager.handleHistory', offset); + if (this.viewManager) { const activeView = this.viewManager.getCurrentView(); if (activeView && activeView.view.webContents.canGoToOffset(offset)) { @@ -573,6 +589,8 @@ export class WindowManager { } handleBrowserHistoryPush = (e: IpcMainEvent, viewName: string, pathName: string) => { + log.debug('WwindowManager.handleBrowserHistoryPush', {viewName, pathName}); + const currentView = this.viewManager?.views.get(viewName); 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; @@ -597,6 +615,8 @@ export class WindowManager { } handleBrowserHistoryButton = (e: IpcMainEvent, viewName: string) => { + log.debug('EindowManager.handleBrowserHistoryButton', viewName); + const currentView = this.viewManager?.views.get(viewName); if (currentView) { if (currentView.view.webContents.getURL() === currentView.tab.url.toString()) { @@ -614,6 +634,8 @@ export class WindowManager { } handleAppLoggedIn = (event: IpcMainEvent, viewName: string) => { + log.debug('WindowManager.handleAppLoggedIn', viewName); + const view = this.viewManager?.views.get(viewName); if (view) { view.isLoggedIn = true; @@ -622,6 +644,8 @@ export class WindowManager { } handleAppLoggedOut = (event: IpcMainEvent, viewName: string) => { + log.debug('WindowManager.handleAppLoggedOut', viewName); + const view = this.viewManager?.views.get(viewName); if (view) { view.isLoggedIn = false; @@ -637,6 +661,8 @@ export class WindowManager { } handleGetDesktopSources = async (event: IpcMainEvent, viewName: string, opts: Electron.SourcesOptions) => { + log.debug('WindowManager.handleGetDesktopSources', {viewName, opts}); + const view = this.viewManager?.views.get(viewName); if (!view) { return; @@ -654,6 +680,8 @@ export class WindowManager { } handleReloadCurrentView = () => { + log.debug('WindowManager.handleReloadCurrentView'); + const view = this.viewManager?.getCurrentView(); if (!view) { return; diff --git a/src/renderer/components/SettingsPage.tsx b/src/renderer/components/SettingsPage.tsx index 642befc9..22f2915d 100644 --- a/src/renderer/components/SettingsPage.tsx +++ b/src/renderer/components/SettingsPage.tsx @@ -7,7 +7,7 @@ import 'renderer/css/settings.css'; 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 {debounce} from 'underscore'; @@ -70,6 +70,7 @@ export default class SettingsPage extends React.PureComponent; startInFullscreenRef: React.RefObject; autoCheckForUpdatesRef: React.RefObject; + logLevelRef: React.RefObject; saveQueue: SaveQueueItem[]; @@ -103,6 +104,7 @@ export default class SettingsPage extends React.PureComponent { + window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_APP_OPTIONS, {key: 'logLevel', data: this.logLevelRef.current?.value}); + this.setState({ + logLevel: this.logLevelRef.current?.value, + }); + } + handleChangeAutoCheckForUpdates = () => { window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_UPDATES, {key: 'autoCheckForUpdates', data: this.autoCheckForUpdatesRef.current?.checked}); this.setState({ @@ -432,6 +441,17 @@ export default class SettingsPage extends React.PureComponent {'Specify the folder where files will download.'} +
+ {'Logging level'} + + + + + + + + + + {'Logging is helpful for developers and support to isolate issues you may be encountering with the desktop app.'} +
{'Increasing the log level increases disk space usage and can impact performance. We recommend only increasing the log level if you are having issues.'} +
, ); diff --git a/src/types/config.ts b/src/types/config.ts index 7738f3f7..12c3a11c 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -44,6 +44,7 @@ export type ConfigV3 = { autoCheckForUpdates?: boolean; alwaysMinimize?: boolean; alwaysClose?: boolean; + logLevel?: string; } export type ConfigV2 = {