mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-12-27 17:31:36 -06:00
feat: SDA-2559: clean app cache on install & crash (#1091)
* SDA-2559: clean app cache on install - Clean app cache on a fresh install of SDA to avoid upgradation problems - Clean app cache and restart SDA when it crashes or is unresponsive * SDA-2559: fix failing unit test * SDA-2559: add dialog before restarting the app * SDA-2559: add translations * SDA-2559: fix failing unit tests and refactor code
This commit is contained in:
parent
c13a6a16ad
commit
e3720c22f6
@ -118,6 +118,7 @@
|
||||
"@types/react": "16.8.3",
|
||||
"@types/react-dom": "16.0.9",
|
||||
"@types/ref-napi": "1.4.0",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
"ava": "2.4.0",
|
||||
"browserify": "16.5.1",
|
||||
"cross-env": "5.2.0",
|
||||
@ -161,6 +162,7 @@
|
||||
"react": "16.13.0",
|
||||
"react-dom": "16.13.0",
|
||||
"ref-napi": "1.4.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"shell-path": "2.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
@ -1,12 +1,27 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { cleanUpAppCache, createAppCacheFile } from '../src/app/app-cache-handler';
|
||||
import * as rimraf from 'rimraf';
|
||||
import { cleanAppCacheOnInstall, cleanUpAppCache, createAppCacheFile } from '../src/app/app-cache-handler';
|
||||
import { app, session } from './__mocks__/electron';
|
||||
|
||||
jest.mock('fs', () => ({
|
||||
writeFileSync: jest.fn(),
|
||||
existsSync: jest.fn(() => true),
|
||||
unlinkSync: jest.fn(),
|
||||
writeFileSync: jest.fn(),
|
||||
existsSync: jest.fn(() => true),
|
||||
unlinkSync: jest.fn(),
|
||||
readdirSync: jest.fn(() => ['fake1', 'fake2', 'Symphony.config', 'cloudConfig.config']),
|
||||
lstatSync: jest.fn(() => {
|
||||
return {
|
||||
isDirectory: jest.fn(() => true),
|
||||
};
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('path', () => ({
|
||||
join: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('rimraf', () => ({
|
||||
sync: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../src/common/logger', () => {
|
||||
@ -19,27 +34,53 @@ jest.mock('../src/common/logger', () => {
|
||||
});
|
||||
|
||||
describe('app cache handler', () => {
|
||||
const cachePathExpected = path.join(app.getPath('userData'), 'CacheCheck');
|
||||
describe('check app cache file', () => {
|
||||
const cachePathExpected = path.join(app.getPath('userData'), 'CacheCheck');
|
||||
|
||||
it('should call `cleanUpAppCache` correctly', () => {
|
||||
const spyFn = 'unlinkSync';
|
||||
const spy = jest.spyOn(fs, spyFn);
|
||||
cleanUpAppCache();
|
||||
expect(spy).toBeCalledWith(cachePathExpected);
|
||||
it('should call `cleanUpAppCache` correctly', () => {
|
||||
const spyFn = 'unlinkSync';
|
||||
const spy = jest.spyOn(fs, spyFn);
|
||||
cleanUpAppCache();
|
||||
expect(spy).toBeCalledWith(cachePathExpected);
|
||||
});
|
||||
|
||||
it('should call `clearCache` when `session.defaultSession` is not null', () => {
|
||||
jest.spyOn(fs, 'existsSync').mockImplementation(() => false);
|
||||
const spyFn = 'clearCache';
|
||||
const spy = jest.spyOn(session.defaultSession, spyFn);
|
||||
cleanUpAppCache();
|
||||
expect(spy).toBeCalled();
|
||||
});
|
||||
|
||||
it('should call `createAppCacheFile` correctly', () => {
|
||||
const spyFn = 'writeFileSync';
|
||||
const spy = jest.spyOn(fs, spyFn);
|
||||
createAppCacheFile();
|
||||
expect(spy).lastCalledWith(cachePathExpected, '');
|
||||
});
|
||||
});
|
||||
|
||||
it('should call `clearCache` when `session.defaultSession` is not null', () => {
|
||||
jest.spyOn(fs, 'existsSync').mockImplementation(() => false);
|
||||
const spyFn = 'clearCache';
|
||||
const spy = jest.spyOn(session.defaultSession, spyFn);
|
||||
cleanUpAppCache();
|
||||
expect(spy).toBeCalled();
|
||||
describe('clean app cache on install', () => {
|
||||
it('should clean app cache and cookies on install', () => {
|
||||
|
||||
const pathSpy = jest.spyOn(path, 'join');
|
||||
|
||||
const fsReadDirSpy = jest.spyOn(fs, 'readdirSync');
|
||||
const fsStatSpy = jest.spyOn(fs, 'lstatSync');
|
||||
const fsUnlinkSpy = jest.spyOn(fs, 'unlinkSync');
|
||||
|
||||
const rimrafSpy = jest.spyOn(rimraf, 'sync');
|
||||
|
||||
cleanAppCacheOnInstall();
|
||||
|
||||
expect(pathSpy).toBeCalled();
|
||||
|
||||
expect(fsReadDirSpy).toBeCalled();
|
||||
expect(fsStatSpy).toBeCalled();
|
||||
expect(fsUnlinkSpy).toBeCalled();
|
||||
|
||||
expect(rimrafSpy).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should call `createAppCacheFile` correctly', () => {
|
||||
const spyFn = 'writeFileSync';
|
||||
const spy = jest.spyOn(fs, spyFn);
|
||||
createAppCacheFile();
|
||||
expect(spy).lastCalledWith(cachePathExpected, '');
|
||||
});
|
||||
});
|
||||
|
@ -1,11 +1,37 @@
|
||||
import { app, session } from 'electron';
|
||||
import { app, BrowserWindow, dialog, session } from 'electron';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as rimraf from 'rimraf';
|
||||
import { i18n } from '../common/i18n';
|
||||
|
||||
import { logger } from '../common/logger';
|
||||
|
||||
// Cache check file path
|
||||
const cacheCheckFilePath: string = path.join(app.getPath('userData'), 'CacheCheck');
|
||||
const userDataPath: string = app.getPath('userData');
|
||||
const cacheCheckFilePath: string = path.join(userDataPath, 'CacheCheck');
|
||||
|
||||
/**
|
||||
* Cleans old cache
|
||||
*/
|
||||
const cleanOldCache = (): void => {
|
||||
const configFilename = 'Symphony.config';
|
||||
const cloudConfigFilename = 'cloudConfig.config';
|
||||
|
||||
const files = fs.readdirSync(userDataPath);
|
||||
|
||||
files.forEach((file) => {
|
||||
const filePath = path.join(userDataPath, file);
|
||||
if (file === configFilename || file === cloudConfigFilename) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fs.lstatSync(filePath).isDirectory()) {
|
||||
rimraf.sync(filePath);
|
||||
return;
|
||||
}
|
||||
fs.unlinkSync(filePath);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes app cache file if exists or clears
|
||||
@ -30,3 +56,45 @@ export const createAppCacheFile = (): void => {
|
||||
logger.info(`app-cache-handler: this is a clean exit, creating app cache file`);
|
||||
fs.writeFileSync(cacheCheckFilePath, '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Cleans the app cache on new install
|
||||
*/
|
||||
export const cleanAppCacheOnInstall = (): void => {
|
||||
logger.info(`app-cache-handler: cleaning app cache and cookies on new install`);
|
||||
cleanOldCache();
|
||||
};
|
||||
|
||||
/**
|
||||
* Cleans app cache and restarts the app on crash or unresponsive events
|
||||
* @param window Browser window to listen to for crash events
|
||||
*/
|
||||
export const cleanAppCacheOnCrash = (window: BrowserWindow): void => {
|
||||
logger.info(`app-cache-handler: listening to crash events & cleaning app cache`);
|
||||
const events = ['unresponsive', 'crashed', 'plugin-crashed'];
|
||||
|
||||
events.forEach((windowEvent: any) => {
|
||||
window.webContents.on(windowEvent, async () => {
|
||||
logger.info(`app-cache-handler: Window Event '${windowEvent}' occurred. Clearing cache & restarting app`);
|
||||
const focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (!focusedWindow || (typeof focusedWindow.isDestroyed === 'function' && focusedWindow.isDestroyed())) {
|
||||
return;
|
||||
}
|
||||
const options = {
|
||||
type: 'question',
|
||||
title: i18n.t('Relaunch Application')(),
|
||||
message: i18n.t('Oops! Something went wrong. Would you like to restart the app?')(),
|
||||
buttons: [i18n.t('Restart')(), i18n.t('Cancel')()],
|
||||
cancelId: 1,
|
||||
};
|
||||
|
||||
const { response } = await dialog.showMessageBox(focusedWindow, options);
|
||||
|
||||
if (response === 0) {
|
||||
cleanOldCache();
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -68,7 +68,7 @@ electron.app.on('certificate-error', async (event, webContents, url, error, _cer
|
||||
|
||||
const browserWin = electron.BrowserWindow.fromWebContents(webContents);
|
||||
if (browserWin && windowExists(browserWin)) {
|
||||
const {response} = await electron.dialog.showMessageBox(browserWin, {
|
||||
const { response } = await electron.dialog.showMessageBox(browserWin, {
|
||||
type: 'warning',
|
||||
buttons: [
|
||||
i18n.t('Allow')(),
|
||||
@ -111,7 +111,7 @@ export const showLoadFailure = async (browserWindow: Electron.BrowserWindow, url
|
||||
if (showDialog) {
|
||||
const { response } = await electron.dialog.showMessageBox(browserWindow, {
|
||||
type: 'error',
|
||||
buttons: [ i18n.t('Reload')(), i18n.t('Ignore')() ],
|
||||
buttons: [i18n.t('Reload')(), i18n.t('Ignore')()],
|
||||
defaultId: 0,
|
||||
cancelId: 1,
|
||||
noLink: true,
|
||||
@ -157,13 +157,13 @@ export const titleBarChangeDialog = async (isNativeStyle: CloudConfigDataTypes)
|
||||
title: i18n.t('Relaunch Application')(),
|
||||
message: i18n.t('Updating Title bar style requires Symphony to relaunch.')(),
|
||||
detail: i18n.t('Note: When Hamburger menu is disabled, you can trigger the main menu by pressing the Alt key.')(),
|
||||
buttons: [ i18n.t('Relaunch')(), i18n.t('Cancel')() ],
|
||||
buttons: [i18n.t('Relaunch')(), i18n.t('Cancel')()],
|
||||
cancelId: 1,
|
||||
};
|
||||
const { response } = await electron.dialog.showMessageBox(focusedWindow, options);
|
||||
if (response === 0) {
|
||||
logger.error(`test`, isNativeStyle);
|
||||
await config.updateUserConfig({ isCustomTitleBar: isNativeStyle });
|
||||
await config.updateUserConfig({ isCustomTitleBar: isNativeStyle });
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
}
|
||||
@ -182,7 +182,7 @@ export const gpuRestartDialog = async (disableGpu: boolean) => {
|
||||
type: 'question',
|
||||
title: i18n.t('Relaunch Application')(),
|
||||
message: i18n.t('Would you like to restart and apply these new settings now?')(),
|
||||
buttons: [ i18n.t('Restart')(), i18n.t('Later')() ],
|
||||
buttons: [i18n.t('Restart')(), i18n.t('Later')()],
|
||||
cancelId: 1,
|
||||
};
|
||||
const { response } = await electron.dialog.showMessageBox(focusedWindow, options);
|
||||
|
@ -5,7 +5,7 @@ import * as shellPath from 'shell-path';
|
||||
import { isDevEnv, isElectronQA, isLinux, isMac } from '../common/env';
|
||||
import { logger } from '../common/logger';
|
||||
import { getCommandLineArgs } from '../common/utils';
|
||||
import { cleanUpAppCache, createAppCacheFile } from './app-cache-handler';
|
||||
import { cleanAppCacheOnInstall, cleanUpAppCache, createAppCacheFile } from './app-cache-handler';
|
||||
import { autoLaunchInstance } from './auto-launch-controller';
|
||||
import { setChromeFlags, setSessionProperties } from './chrome-flags';
|
||||
import { config } from './config-handler';
|
||||
@ -81,6 +81,7 @@ const startApplication = async () => {
|
||||
createAppCacheFile();
|
||||
if (config.isFirstTimeLaunch()) {
|
||||
logger.info(`main: This is a first time launch! will update config and handle auto launch`);
|
||||
cleanAppCacheOnInstall();
|
||||
await config.setUpFirstTimeLaunch();
|
||||
if (!isLinux) {
|
||||
await autoLaunchInstance.handleAutoLaunch();
|
||||
@ -142,7 +143,7 @@ app.on('window-all-closed', () => {
|
||||
/**
|
||||
* Creates a new empty cache file when the app is quit
|
||||
*/
|
||||
app.on('quit', () => {
|
||||
app.on('quit', () => {
|
||||
logger.info(`main: quitting the app!`);
|
||||
cleanUpAppCache();
|
||||
});
|
||||
|
@ -19,6 +19,7 @@ import { i18n, LocaleType } from '../common/i18n';
|
||||
import { logger } from '../common/logger';
|
||||
import { getCommandLineArgs, getGuid } from '../common/utils';
|
||||
import { notification } from '../renderer/notification';
|
||||
import { cleanAppCacheOnCrash } from './app-cache-handler';
|
||||
import { AppMenu } from './app-menu';
|
||||
import { handleChildWindow } from './child-window-handler';
|
||||
import { CloudConfigDataTypes, config, IConfig, IGlobalConfig } from './config-handler';
|
||||
@ -114,14 +115,14 @@ export class WindowHandler {
|
||||
|
||||
constructor(opts?: Electron.BrowserViewConstructorOptions) {
|
||||
// Use these variables only on initial setup
|
||||
this.config = config.getConfigFields([ 'isCustomTitleBar', 'mainWinPos', 'minimizeOnClose', 'notificationSettings', 'alwaysOnTop', 'locale', 'customFlags', 'clientSwitch', 'enableRendererLogs' ]);
|
||||
this.config = config.getConfigFields(['isCustomTitleBar', 'mainWinPos', 'minimizeOnClose', 'notificationSettings', 'alwaysOnTop', 'locale', 'customFlags', 'clientSwitch', 'enableRendererLogs']);
|
||||
logger.info(`window-handler: main windows initialized with following config data`, this.config);
|
||||
|
||||
this.globalConfig = config.getGlobalConfigFields([ 'url', 'contextIsolation', 'contextOriginUrl' ]);
|
||||
this.userConfig = config.getUserConfigFields([ 'url' ]);
|
||||
this.globalConfig = config.getGlobalConfigFields(['url', 'contextIsolation', 'contextOriginUrl']);
|
||||
this.userConfig = config.getUserConfigFields(['url']);
|
||||
|
||||
const { customFlags } = this.config;
|
||||
const { disableThrottling } = config.getCloudConfigFields([ 'disableThrottling' ]) as any;
|
||||
const { disableThrottling } = config.getCloudConfigFields(['disableThrottling']) as any;
|
||||
|
||||
this.windows = {};
|
||||
this.contextIsolation = this.globalConfig.contextIsolation || false;
|
||||
@ -159,9 +160,9 @@ export class WindowHandler {
|
||||
i18n.setLocale(locale);
|
||||
|
||||
try {
|
||||
const extra = {podUrl: this.userConfig.url ? this.userConfig.url : this.globalConfig.url, process: 'main'};
|
||||
const defaultOpts = {uploadToServer: false, companyName: 'Symphony', submitURL: ''};
|
||||
crashReporter.start({...defaultOpts, extra});
|
||||
const extra = { podUrl: this.userConfig.url ? this.userConfig.url : this.globalConfig.url, process: 'main' };
|
||||
const defaultOpts = { uploadToServer: false, companyName: 'Symphony', submitURL: '' };
|
||||
crashReporter.start({ ...defaultOpts, extra });
|
||||
} catch (e) {
|
||||
throw new Error('failed to init crash report');
|
||||
}
|
||||
@ -178,7 +179,7 @@ export class WindowHandler {
|
||||
|
||||
logger.info('window-handler: createApplication mainWinPos: ' + JSON.stringify(this.config.mainWinPos));
|
||||
|
||||
let {isFullScreen, isMaximized} = this.config.mainWinPos ? this.config.mainWinPos : {isFullScreen: false, isMaximized: false};
|
||||
let { isFullScreen, isMaximized } = this.config.mainWinPos ? this.config.mainWinPos : { isFullScreen: false, isMaximized: false };
|
||||
|
||||
this.url = WindowHandler.getValidUrl(this.userConfig.url ? this.userConfig.url : this.globalConfig.url);
|
||||
logger.info(`window-handler: setting url ${this.url} from config file!`);
|
||||
@ -219,7 +220,7 @@ export class WindowHandler {
|
||||
logger.info('window-handler: windowSize: sizes: ' + JSON.stringify(sizes));
|
||||
DEFAULT_WIDTH = Number(sizes[0]);
|
||||
DEFAULT_HEIGHT = Number(sizes[1]);
|
||||
if (this.config.mainWinPos ) {
|
||||
if (this.config.mainWinPos) {
|
||||
this.config.mainWinPos.width = DEFAULT_WIDTH;
|
||||
this.config.mainWinPos.height = DEFAULT_HEIGHT;
|
||||
}
|
||||
@ -245,7 +246,7 @@ export class WindowHandler {
|
||||
if (urlFromCmd) {
|
||||
const commandLineUrl = urlFromCmd.substr(6);
|
||||
logger.info(`window-handler: trying to set url ${commandLineUrl} from command line.`);
|
||||
const { podWhitelist } = config.getConfigFields([ 'podWhitelist' ]);
|
||||
const { podWhitelist } = config.getConfigFields(['podWhitelist']);
|
||||
logger.info(`window-handler: checking pod whitelist.`);
|
||||
if (podWhitelist.length > 0) {
|
||||
logger.info(`window-handler: pod whitelist is not empty ${podWhitelist}`);
|
||||
@ -289,6 +290,7 @@ export class WindowHandler {
|
||||
this.handleWelcomeScreen();
|
||||
}
|
||||
|
||||
cleanAppCacheOnCrash(this.mainWindow);
|
||||
// loads the main window with url from config/cmd line
|
||||
this.mainWindow.loadURL(this.url);
|
||||
// check for build expiry in case of test builds
|
||||
@ -337,7 +339,7 @@ export class WindowHandler {
|
||||
isMainWindow: true,
|
||||
});
|
||||
this.appMenu = new AppMenu();
|
||||
const { permissions } = config.getConfigFields([ 'permissions' ]);
|
||||
const { permissions } = config.getConfigFields(['permissions']);
|
||||
this.mainWindow.webContents.send('is-screen-share-enabled', permissions.media);
|
||||
});
|
||||
|
||||
@ -357,7 +359,7 @@ export class WindowHandler {
|
||||
if (href === 'data:text/html,chromewebdata' || href === 'chrome-error://chromewebdata/') {
|
||||
if (this.mainWindow && windowExists(this.mainWindow)) {
|
||||
this.mainWindow.webContents.insertCSS(fs.readFileSync(path.join(__dirname, '..', '/renderer/styles/network-error.css'), 'utf8').toString());
|
||||
this.mainWindow.webContents.send('network-error', {error: this.loadFailError});
|
||||
this.mainWindow.webContents.send('network-error', { error: this.loadFailError });
|
||||
isSymphonyReachable(this.mainWindow, this.url || this.userConfig.url || this.globalConfig.url);
|
||||
}
|
||||
}
|
||||
@ -399,7 +401,7 @@ export class WindowHandler {
|
||||
return this.destroyAllWindows();
|
||||
}
|
||||
|
||||
const { minimizeOnClose } = config.getConfigFields([ 'minimizeOnClose' ]);
|
||||
const { minimizeOnClose } = config.getConfigFields(['minimizeOnClose']);
|
||||
if (minimizeOnClose === CloudConfigDataTypes.ENABLED) {
|
||||
event.preventDefault();
|
||||
this.mainWindow.minimize();
|
||||
@ -496,7 +498,7 @@ export class WindowHandler {
|
||||
resource: i18n.loadedResources,
|
||||
});
|
||||
const userConfigUrl = this.userConfig.url
|
||||
&& this.userConfig.url.indexOf('/login/sso/initsso') > -1 ?
|
||||
&& this.userConfig.url.indexOf('/login/sso/initsso') > -1 ?
|
||||
this.userConfig.url.slice(0, this.userConfig.url.indexOf('/login/sso/initsso'))
|
||||
: this.userConfig.url;
|
||||
|
||||
@ -510,7 +512,7 @@ export class WindowHandler {
|
||||
});
|
||||
|
||||
ipcMain.on('set-pod-url', async (_event, newPodUrl: string) => {
|
||||
await config.updateUserConfig({url: newPodUrl});
|
||||
await config.updateUserConfig({ url: newPodUrl });
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
});
|
||||
@ -777,14 +779,14 @@ export class WindowHandler {
|
||||
this.screenPickerWindow.webContents.setZoomFactor(1);
|
||||
this.screenPickerWindow.webContents.setVisualZoomLevelLimits(1, 1);
|
||||
|
||||
this.screenPickerWindow.webContents.send('screen-picker-data', {sources, id});
|
||||
this.screenPickerWindow.webContents.send('screen-picker-data', { sources, id });
|
||||
this.addWindow(opts.winKey, this.screenPickerWindow);
|
||||
});
|
||||
ipcMain.once('screen-source-selected', (_event, source) => {
|
||||
const displays = electron.screen.getAllDisplays();
|
||||
logger.info('window-utils: displays.length: ' + displays.length);
|
||||
for (let i = 0, len = displays.length; i < len; i++) {
|
||||
logger.info('window-utils: display[' + i + ']: ' + JSON.stringify(displays[ i ]));
|
||||
logger.info('window-utils: display[' + i + ']: ' + JSON.stringify(displays[i]));
|
||||
}
|
||||
|
||||
if (source != null) {
|
||||
@ -793,22 +795,22 @@ export class WindowHandler {
|
||||
const type = source.id.split(':')[0];
|
||||
if (type === 'window') {
|
||||
const hwnd = source.id.split(':')[1];
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [ hwnd ]);
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [hwnd]);
|
||||
} else if (isMac && type === 'screen') {
|
||||
const dispId = source.id.split(':')[1];
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [ dispId ]);
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [dispId]);
|
||||
} else if (isWindowsOS && type === 'screen') {
|
||||
logger.info('window-handler: source.display_id: ' + source.display_id);
|
||||
if (source.display_id !== '') {
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [ source.display_id ]);
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [source.display_id]);
|
||||
} else {
|
||||
const dispId = source.id.split(':')[1];
|
||||
const clampedDispId = Math.min(dispId, displays.length - 1);
|
||||
const keyId = 'id';
|
||||
logger.info('window-utils: dispId: ' + dispId);
|
||||
logger.info('window-utils: clampedDispId: ' + clampedDispId);
|
||||
logger.info('window-utils: displays [' + clampedDispId + '] [id]: ' + displays [clampedDispId] [ keyId ]);
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [ displays [clampedDispId] [ keyId ].toString() ]);
|
||||
logger.info('window-utils: displays [' + clampedDispId + '] [id]: ' + displays[clampedDispId][keyId]);
|
||||
this.execCmd(this.screenShareIndicatorFrameUtil, [displays[clampedDispId][keyId].toString()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -856,7 +858,7 @@ export class WindowHandler {
|
||||
if (!this.basicAuthWindow || !windowExists(this.basicAuthWindow)) {
|
||||
return;
|
||||
}
|
||||
this.basicAuthWindow.webContents.send('basic-auth-data', {hostname, isValidCredentials: isMultipleTries});
|
||||
this.basicAuthWindow.webContents.send('basic-auth-data', { hostname, isValidCredentials: isMultipleTries });
|
||||
});
|
||||
const closeBasicAuth = (_event, shouldClearSettings = true) => {
|
||||
if (shouldClearSettings) {
|
||||
@ -869,7 +871,7 @@ export class WindowHandler {
|
||||
};
|
||||
|
||||
const login = (_event, arg) => {
|
||||
const {username, password} = arg;
|
||||
const { username, password } = arg;
|
||||
callback(username, password);
|
||||
closeBasicAuth(null, false);
|
||||
};
|
||||
@ -921,17 +923,17 @@ export class WindowHandler {
|
||||
if (app.isReady()) {
|
||||
screens = electron.screen.getAllDisplays();
|
||||
}
|
||||
const { position, display } = config.getConfigFields([ 'notificationSettings' ]).notificationSettings;
|
||||
this.notificationSettingsWindow.webContents.send('notification-settings-data', {screens, position, display});
|
||||
const { position, display } = config.getConfigFields(['notificationSettings']).notificationSettings;
|
||||
this.notificationSettingsWindow.webContents.send('notification-settings-data', { screens, position, display });
|
||||
}
|
||||
});
|
||||
|
||||
this.addWindow(opts.winKey, this.notificationSettingsWindow);
|
||||
|
||||
ipcMain.once('notification-settings-update', async (_event, args) => {
|
||||
const {display, position} = args;
|
||||
const { display, position } = args;
|
||||
try {
|
||||
await config.updateUserConfig({notificationSettings: {display, position}});
|
||||
await config.updateUserConfig({ notificationSettings: { display, position } });
|
||||
} catch (e) {
|
||||
logger.error(`NotificationSettings: Could not update user config file error`, e);
|
||||
}
|
||||
@ -991,7 +993,7 @@ export class WindowHandler {
|
||||
closable: false,
|
||||
}, {
|
||||
devTools: false,
|
||||
}), ...{winKey: streamId},
|
||||
}), ...{ winKey: streamId },
|
||||
};
|
||||
if (opts.width && opts.height) {
|
||||
opts = Object.assign({}, opts, {
|
||||
@ -1008,7 +1010,7 @@ export class WindowHandler {
|
||||
logger.info('window-handler: element.id.toString(): ' + element.id.toString());
|
||||
if (displayId === element.id.toString()) {
|
||||
logger.info(`window-handler: element:`, element);
|
||||
this.createScreenSharingFrameWindow('screen-sharing-frame',
|
||||
this.createScreenSharingFrameWindow('screen-sharing-frame',
|
||||
element.workArea.width,
|
||||
element.workArea.height,
|
||||
element.workArea.x,
|
||||
@ -1027,7 +1029,7 @@ export class WindowHandler {
|
||||
if (!this.screenSharingIndicatorWindow || !windowExists(this.screenSharingIndicatorWindow)) {
|
||||
return;
|
||||
}
|
||||
this.screenSharingIndicatorWindow.webContents.send('screen-sharing-indicator-data', {id, streamId});
|
||||
this.screenSharingIndicatorWindow.webContents.send('screen-sharing-indicator-data', { id, streamId });
|
||||
});
|
||||
const stopScreenSharing = (_event, indicatorId) => {
|
||||
if (id === indicatorId) {
|
||||
@ -1229,7 +1231,7 @@ export class WindowHandler {
|
||||
if (!focusedWindow || !windowExists(focusedWindow)) {
|
||||
return;
|
||||
}
|
||||
const { devToolsEnabled } = config.getConfigFields([ 'devToolsEnabled' ]);
|
||||
const { devToolsEnabled } = config.getConfigFields(['devToolsEnabled']);
|
||||
if (devToolsEnabled) {
|
||||
focusedWindow.webContents.toggleDevTools();
|
||||
return;
|
||||
@ -1333,7 +1335,7 @@ export class WindowHandler {
|
||||
type: 'error',
|
||||
title: i18n.t('Build expired')(),
|
||||
message: i18n.t('Sorry, this is a test build and it has expired. Please contact your administrator to get a production build.')(),
|
||||
buttons: [ i18n.t('Quit')() ],
|
||||
buttons: [i18n.t('Quit')()],
|
||||
cancelId: 0,
|
||||
};
|
||||
|
||||
@ -1364,7 +1366,7 @@ export class WindowHandler {
|
||||
winKey: getGuid(),
|
||||
};
|
||||
|
||||
return {...defaultWindowOpts, ...windowOpts};
|
||||
return { ...defaultWindowOpts, ...windowOpts };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,7 @@
|
||||
},
|
||||
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
||||
"Oops! Something went wrong. Would you like to restart the app?": "Oops! Something went wrong. Would you like to restart the app?",
|
||||
"Paste": "Paste",
|
||||
"Paste and Match Style": "Paste and Match Style",
|
||||
"Permission Denied": "Permission Denied",
|
||||
|
@ -111,6 +111,7 @@
|
||||
},
|
||||
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
||||
"Oops! Something went wrong. Would you like to restart the app?": "Oops! Something went wrong. Would you like to restart the app?",
|
||||
"Paste": "Paste",
|
||||
"Paste and Match Style": "Paste and Match Style",
|
||||
"Permission Denied": "Permission Denied",
|
||||
|
@ -112,6 +112,7 @@
|
||||
},
|
||||
"Oops! Looks like we have had a crash.": "Oops! On dirait que nous avons eu un crash.",
|
||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! On dirait que nous avons eu un crash. Veuillez recharger ou fermer cette fenêtre.",
|
||||
"Oops! Something went wrong. Would you like to restart the app?": "Oups ! Quelque chose s'est mal passé. Voulez-vous redémarrer l'application ?",
|
||||
"Paste": "Coller",
|
||||
"Paste and Match Style": "Coller et appliquer le style",
|
||||
"Permission Denied": "Permission refusée",
|
||||
|
@ -111,6 +111,7 @@
|
||||
},
|
||||
"Oops! Looks like we have had a crash.": "Oops! On dirait que nous avons eu un crash.",
|
||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! On dirait que nous avons eu un crash. Veuillez recharger ou fermer cette fenêtre.",
|
||||
"Oops! Something went wrong. Would you like to restart the app?": "Oups ! Quelque chose s'est mal passé. Voulez-vous redémarrer l'application ?",
|
||||
"Paste": "Coller",
|
||||
"Paste and Match Style": "Coller et appliquer le style",
|
||||
"Permission Denied": "Permission refusée",
|
||||
|
@ -111,6 +111,7 @@
|
||||
},
|
||||
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウを再度読み込むか閉じてください。",
|
||||
"Oops! Something went wrong. Would you like to restart the app?": "おっと!何か問題が起こった。アプリを再開しますか?",
|
||||
"Paste": "貼り付け",
|
||||
"Paste and Match Style": "貼り付けでスタイルを合わせる",
|
||||
"Permission Denied": "アクセス許可が拒否されています",
|
||||
|
@ -111,6 +111,7 @@
|
||||
},
|
||||
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
||||
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウを再度読み込むか閉じてください。",
|
||||
"Oops! Something went wrong. Would you like to restart the app?": "おっと!何か問題が起こった。アプリを再開しますか?",
|
||||
"Paste": "貼り付け",
|
||||
"Paste and Match Style": "貼り付けでスタイルを合わせる",
|
||||
"Permission Denied": "アクセス許可が拒否されています",
|
||||
|
Loading…
Reference in New Issue
Block a user