diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/electron/Settings.ts (renamed from src/electron/Settings.js) | 11 | ||||
-rw-r--r-- | src/electron/deepLinking.ts (renamed from src/electron/deepLinking.js) | 0 | ||||
-rw-r--r-- | src/electron/exception.ts (renamed from src/electron/exception.js) | 0 | ||||
-rw-r--r-- | src/electron/ipc-api/appIndicator.ts (renamed from src/electron/ipc-api/appIndicator.js) | 42 | ||||
-rw-r--r-- | src/electron/ipc-api/autoUpdate.ts (renamed from src/electron/ipc-api/autoUpdate.js) | 16 | ||||
-rw-r--r-- | src/electron/ipc-api/cld.ts (renamed from src/electron/ipc-api/cld.js) | 7 | ||||
-rw-r--r-- | src/electron/ipc-api/dnd.ts (renamed from src/electron/ipc-api/dnd.js) | 0 | ||||
-rw-r--r-- | src/electron/ipc-api/download.js | 51 | ||||
-rw-r--r-- | src/electron/ipc-api/download.ts | 59 | ||||
-rw-r--r-- | src/electron/ipc-api/focusState.ts (renamed from src/electron/ipc-api/focusState.js) | 4 | ||||
-rw-r--r-- | src/electron/ipc-api/index.ts (renamed from src/electron/ipc-api/index.js) | 9 | ||||
-rw-r--r-- | src/electron/ipc-api/localServer.ts (renamed from src/electron/ipc-api/localServer.js) | 11 | ||||
-rw-r--r-- | src/electron/ipc-api/settings.js | 14 | ||||
-rw-r--r-- | src/electron/ipc-api/settings.ts | 14 | ||||
-rw-r--r-- | src/electron/macOSPermissions.ts (renamed from src/electron/macOSPermissions.js) | 17 | ||||
-rw-r--r-- | src/electron/webview-ime-focus.js | 41 | ||||
-rw-r--r-- | src/electron/windowUtils.js | 11 | ||||
-rw-r--r-- | src/electron/windowUtils.ts | 13 |
18 files changed, 160 insertions, 160 deletions
diff --git a/src/electron/Settings.js b/src/electron/Settings.ts index 3e11bb175..a1344aa97 100644 --- a/src/electron/Settings.js +++ b/src/electron/Settings.ts | |||
@@ -7,9 +7,11 @@ const debug = require('debug')('Ferdi:Settings'); | |||
7 | export default class Settings { | 7 | export default class Settings { |
8 | type = ''; | 8 | type = ''; |
9 | 9 | ||
10 | defaultState: {}; | ||
11 | |||
10 | @observable store = {}; | 12 | @observable store = {}; |
11 | 13 | ||
12 | constructor(type, defaultState = {}) { | 14 | constructor(type: string, defaultState = {}) { |
13 | this.type = type; | 15 | this.type = type; |
14 | this.store = defaultState; | 16 | this.store = defaultState; |
15 | this.defaultState = defaultState; | 17 | this.defaultState = defaultState; |
@@ -35,7 +37,7 @@ export default class Settings { | |||
35 | return toJS(this.store); | 37 | return toJS(this.store); |
36 | } | 38 | } |
37 | 39 | ||
38 | get(key) { | 40 | get(key: string | number) { |
39 | return this.store[key]; | 41 | return this.store[key]; |
40 | } | 42 | } |
41 | 43 | ||
@@ -56,6 +58,9 @@ export default class Settings { | |||
56 | } | 58 | } |
57 | 59 | ||
58 | get settingsFile() { | 60 | get settingsFile() { |
59 | return userDataPath('config', `${this.type === 'app' ? 'settings' : this.type}.json`); | 61 | return userDataPath( |
62 | 'config', | ||
63 | `${this.type === 'app' ? 'settings' : this.type}.json`, | ||
64 | ); | ||
60 | } | 65 | } |
61 | } | 66 | } |
diff --git a/src/electron/deepLinking.js b/src/electron/deepLinking.ts index 70e5cfb6f..70e5cfb6f 100644 --- a/src/electron/deepLinking.js +++ b/src/electron/deepLinking.ts | |||
diff --git a/src/electron/exception.js b/src/electron/exception.ts index 0065e2604..0065e2604 100644 --- a/src/electron/exception.js +++ b/src/electron/exception.ts | |||
diff --git a/src/electron/ipc-api/appIndicator.js b/src/electron/ipc-api/appIndicator.ts index c6c261d0f..5b5f2bac7 100644 --- a/src/electron/ipc-api/appIndicator.js +++ b/src/electron/ipc-api/appIndicator.ts | |||
@@ -6,15 +6,22 @@ import { isMac, isWindows, isLinux } from '../../environment'; | |||
6 | const INDICATOR_TASKBAR = 'taskbar'; | 6 | const INDICATOR_TASKBAR = 'taskbar'; |
7 | const FILE_EXTENSION = isWindows ? 'ico' : 'png'; | 7 | const FILE_EXTENSION = isWindows ? 'ico' : 'png'; |
8 | 8 | ||
9 | let isTrayIconEnabled; | 9 | let isTrayIconEnabled: boolean; |
10 | 10 | ||
11 | function getAsset(type, asset) { | 11 | function getAsset(type: 'tray' | 'taskbar', asset: string) { |
12 | return join( | 12 | return join( |
13 | __dirname, '..', '..', 'assets', 'images', type, process.platform, `${asset}.${FILE_EXTENSION}`, | 13 | __dirname, |
14 | '..', | ||
15 | '..', | ||
16 | 'assets', | ||
17 | 'images', | ||
18 | type, | ||
19 | process.platform, | ||
20 | `${asset}.${FILE_EXTENSION}`, | ||
14 | ); | 21 | ); |
15 | } | 22 | } |
16 | 23 | ||
17 | export default (params) => { | 24 | export default params => { |
18 | autorun(() => { | 25 | autorun(() => { |
19 | isTrayIconEnabled = params.settings.app.get('enableSystemTray'); | 26 | isTrayIconEnabled = params.settings.app.get('enableSystemTray'); |
20 | 27 | ||
@@ -25,13 +32,15 @@ export default (params) => { | |||
25 | } | 32 | } |
26 | }); | 33 | }); |
27 | 34 | ||
28 | ipcMain.on('updateAppIndicator', (event, args) => { | 35 | ipcMain.on('updateAppIndicator', (_event, args) => { |
29 | // Flash TaskBar for windows, bounce Dock on Mac | 36 | // Flash TaskBar for windows, bounce Dock on Mac |
30 | if (!app.mainWindow.isFocused()) { | 37 | if (!(app as any).mainWindow.isFocused()) { |
31 | if (params.settings.app.get('notifyTaskBarOnMessage')) { | 38 | if (params.settings.app.get('notifyTaskBarOnMessage')) { |
32 | if (isWindows) { | 39 | if (isWindows) { |
33 | app.mainWindow.flashFrame(true); | 40 | (app as any).mainWindow.flashFrame(true); |
34 | app.mainWindow.once('focus', () => app.mainWindow.flashFrame(false)); | 41 | (app as any).mainWindow.once('focus', () => |
42 | (app as any).mainWindow.flashFrame(false), | ||
43 | ); | ||
35 | } else if (isMac) { | 44 | } else if (isMac) { |
36 | app.dock.bounce('informational'); | 45 | app.dock.bounce('informational'); |
37 | } | 46 | } |
@@ -39,22 +48,23 @@ export default (params) => { | |||
39 | } | 48 | } |
40 | 49 | ||
41 | // Update badge | 50 | // Update badge |
42 | if (isMac | 51 | if (isMac && typeof args.indicator === 'string') { |
43 | && typeof (args.indicator) === 'string') { | ||
44 | app.dock.setBadge(args.indicator); | 52 | app.dock.setBadge(args.indicator); |
45 | } | 53 | } |
46 | 54 | ||
47 | if ((isMac || isLinux) | 55 | if ((isMac || isLinux) && typeof args.indicator === 'number') { |
48 | && typeof (args.indicator) === 'number' | ||
49 | ) { | ||
50 | app.badgeCount = args.indicator; | 56 | app.badgeCount = args.indicator; |
51 | } | 57 | } |
52 | 58 | ||
53 | if (isWindows) { | 59 | if (isWindows) { |
54 | if (typeof args.indicator === 'number' | 60 | if (typeof args.indicator === 'number' && args.indicator !== 0) { |
55 | && args.indicator !== 0) { | ||
56 | params.mainWindow.setOverlayIcon( | 61 | params.mainWindow.setOverlayIcon( |
57 | getAsset('taskbar', `${INDICATOR_TASKBAR}-${(args.indicator >= 10 ? 10 : args.indicator)}`), | 62 | getAsset( |
63 | 'taskbar', | ||
64 | `${INDICATOR_TASKBAR}-${ | ||
65 | args.indicator >= 10 ? 10 : args.indicator | ||
66 | }`, | ||
67 | ), | ||
58 | '', | 68 | '', |
59 | ); | 69 | ); |
60 | } else if (typeof args.indicator === 'string') { | 70 | } else if (typeof args.indicator === 'string') { |
diff --git a/src/electron/ipc-api/autoUpdate.js b/src/electron/ipc-api/autoUpdate.ts index 255595b9e..70890539d 100644 --- a/src/electron/ipc-api/autoUpdate.js +++ b/src/electron/ipc-api/autoUpdate.ts | |||
@@ -1,11 +1,11 @@ | |||
1 | import { app, ipcMain } from 'electron'; | 1 | import { app, ipcMain, BrowserWindow } from 'electron'; |
2 | import { autoUpdater } from 'electron-updater'; | 2 | import { autoUpdater } from 'electron-updater'; |
3 | import { GITHUB_NIGHTLIES_REPO_NAME, GITHUB_ORG_NAME } from '../../config'; | 3 | import { GITHUB_NIGHTLIES_REPO_NAME, GITHUB_ORG_NAME } from '../../config'; |
4 | import { isMac, isWindows } from '../../environment'; | 4 | import { isMac, isWindows } from '../../environment'; |
5 | 5 | ||
6 | const debug = require('debug')('Ferdi:ipcApi:autoUpdate'); | 6 | const debug = require('debug')('Ferdi:ipcApi:autoUpdate'); |
7 | 7 | ||
8 | export default (params) => { | 8 | export default (params: { mainWindow: BrowserWindow; settings: any }) => { |
9 | const enableUpdate = Boolean(params.settings.app.get('automaticUpdates')); | 9 | const enableUpdate = Boolean(params.settings.app.get('automaticUpdates')); |
10 | 10 | ||
11 | if (!enableUpdate) { | 11 | if (!enableUpdate) { |
@@ -16,11 +16,15 @@ export default (params) => { | |||
16 | if (enableUpdate) { | 16 | if (enableUpdate) { |
17 | try { | 17 | try { |
18 | autoUpdater.autoInstallOnAppQuit = false; | 18 | autoUpdater.autoInstallOnAppQuit = false; |
19 | autoUpdater.allowPrerelease = Boolean(params.settings.app.get('beta')); | 19 | autoUpdater.allowPrerelease = Boolean( |
20 | params.settings.app.get('beta'), | ||
21 | ); | ||
20 | autoUpdater.channel = autoUpdater.allowPrerelease ? 'beta' : 'latest'; | 22 | autoUpdater.channel = autoUpdater.allowPrerelease ? 'beta' : 'latest'; |
21 | 23 | ||
22 | if (params.settings.app.get('nightly')) { | 24 | if (params.settings.app.get('nightly')) { |
23 | autoUpdater.allowPrerelease = Boolean(params.settings.app.get('nightly')); | 25 | autoUpdater.allowPrerelease = Boolean( |
26 | params.settings.app.get('nightly'), | ||
27 | ); | ||
24 | autoUpdater.channel = 'alpha'; | 28 | autoUpdater.channel = 'alpha'; |
25 | autoUpdater.setFeedURL({ | 29 | autoUpdater.setFeedURL({ |
26 | provider: 'github', | 30 | provider: 'github', |
@@ -52,7 +56,7 @@ export default (params) => { | |||
52 | params.mainWindow.webContents.send('autoUpdate', { available: false }); | 56 | params.mainWindow.webContents.send('autoUpdate', { available: false }); |
53 | }); | 57 | }); |
54 | 58 | ||
55 | autoUpdater.on('update-available', (event) => { | 59 | autoUpdater.on('update-available', event => { |
56 | debug('update-available'); | 60 | debug('update-available'); |
57 | 61 | ||
58 | if (enableUpdate) { | 62 | if (enableUpdate) { |
@@ -63,7 +67,7 @@ export default (params) => { | |||
63 | } | 67 | } |
64 | }); | 68 | }); |
65 | 69 | ||
66 | autoUpdater.on('download-progress', (progressObj) => { | 70 | autoUpdater.on('download-progress', progressObj => { |
67 | let logMessage = `Download speed: ${progressObj.bytesPerSecond}`; | 71 | let logMessage = `Download speed: ${progressObj.bytesPerSecond}`; |
68 | logMessage = `${logMessage} - Downloaded ${progressObj.percent}%`; | 72 | logMessage = `${logMessage} - Downloaded ${progressObj.percent}%`; |
69 | logMessage = `${logMessage} (${progressObj.transferred}/${progressObj.total})`; | 73 | logMessage = `${logMessage} (${progressObj.transferred}/${progressObj.total})`; |
diff --git a/src/electron/ipc-api/cld.js b/src/electron/ipc-api/cld.ts index 73e320ad9..b907f3730 100644 --- a/src/electron/ipc-api/cld.js +++ b/src/electron/ipc-api/cld.ts | |||
@@ -4,12 +4,15 @@ import cld from 'cld'; | |||
4 | const debug = require('debug')('Ferdi:ipcApi:cld'); | 4 | const debug = require('debug')('Ferdi:ipcApi:cld'); |
5 | 5 | ||
6 | export default async () => { | 6 | export default async () => { |
7 | ipcMain.handle('detect-language', async (event, { sample }) => { | 7 | ipcMain.handle('detect-language', async (_event, { sample }) => { |
8 | try { | 8 | try { |
9 | const result = await cld.detect(sample); | 9 | const result = await cld.detect(sample); |
10 | debug('Checking language', 'probability', result.languages); | 10 | debug('Checking language', 'probability', result.languages); |
11 | if (result.reliable) { | 11 | if (result.reliable) { |
12 | debug('Language detected reliably, setting spellchecker language to', result.languages[0].code); | 12 | debug( |
13 | 'Language detected reliably, setting spellchecker language to', | ||
14 | result.languages[0].code, | ||
15 | ); | ||
13 | 16 | ||
14 | return result.languages[0].code; | 17 | return result.languages[0].code; |
15 | } | 18 | } |
diff --git a/src/electron/ipc-api/dnd.js b/src/electron/ipc-api/dnd.ts index 6fb8999a3..6fb8999a3 100644 --- a/src/electron/ipc-api/dnd.js +++ b/src/electron/ipc-api/dnd.ts | |||
diff --git a/src/electron/ipc-api/download.js b/src/electron/ipc-api/download.js deleted file mode 100644 index ba261ba1e..000000000 --- a/src/electron/ipc-api/download.js +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | import { ipcMain, dialog, BrowserWindow } from 'electron'; | ||
2 | import { download } from 'electron-dl'; | ||
3 | import mime from 'mime-types'; | ||
4 | import { writeFileSync } from 'fs-extra'; | ||
5 | |||
6 | const debug = require('debug')('Ferdi:ipcApi:download'); | ||
7 | |||
8 | function decodeBase64Image(dataString) { | ||
9 | const matches = dataString.match(/^data:([A-Za-z-+/]+);base64,(.+)$/); | ||
10 | |||
11 | if (matches.length !== 3) { | ||
12 | return new Error('Invalid input string'); | ||
13 | } | ||
14 | |||
15 | return Buffer.from(matches[2], 'base64'); | ||
16 | } | ||
17 | |||
18 | export default (params) => { | ||
19 | ipcMain.on('download-file', async (event, { url, content, fileOptions = {} }) => { | ||
20 | const win = BrowserWindow.getFocusedWindow(); | ||
21 | |||
22 | try { | ||
23 | if (!content) { | ||
24 | const dl = await download(win, url, { | ||
25 | saveAs: true, | ||
26 | }); | ||
27 | debug('File saved to', dl.savePath); | ||
28 | } else { | ||
29 | const extension = mime.extension(fileOptions.mime); | ||
30 | const filename = `${fileOptions.name}.${extension}`; | ||
31 | |||
32 | try { | ||
33 | const saveDialog = await dialog.showSaveDialog(params.mainWindow, { | ||
34 | defaultPath: filename, | ||
35 | }); | ||
36 | |||
37 | if (saveDialog.canceled) return; | ||
38 | |||
39 | const binaryImage = decodeBase64Image(content); | ||
40 | writeFileSync(saveDialog.filePath, binaryImage, 'binary'); | ||
41 | |||
42 | debug('File blob saved to', saveDialog.filePath); | ||
43 | } catch (err) { | ||
44 | console.log(err); | ||
45 | } | ||
46 | } | ||
47 | } catch (e) { | ||
48 | console.error(e); | ||
49 | } | ||
50 | }); | ||
51 | }; | ||
diff --git a/src/electron/ipc-api/download.ts b/src/electron/ipc-api/download.ts new file mode 100644 index 000000000..822658f26 --- /dev/null +++ b/src/electron/ipc-api/download.ts | |||
@@ -0,0 +1,59 @@ | |||
1 | import { ipcMain, dialog, BrowserWindow } from 'electron'; | ||
2 | import { download } from 'electron-dl'; | ||
3 | import mime from 'mime-types'; | ||
4 | import { writeFileSync } from 'fs-extra'; | ||
5 | import { PathLike } from 'fs'; | ||
6 | |||
7 | const debug = require('debug')('Ferdi:ipcApi:download'); | ||
8 | |||
9 | function decodeBase64Image(dataString: string) { | ||
10 | const matches = dataString.match(/^data:([A-Za-z-+/]+);base64,(.+)$/); | ||
11 | |||
12 | if (matches?.length !== 3) { | ||
13 | return new Error('Invalid input string'); | ||
14 | } | ||
15 | |||
16 | return Buffer.from(matches[2], 'base64'); | ||
17 | } | ||
18 | |||
19 | export default (params: { mainWindow: BrowserWindow }) => { | ||
20 | ipcMain.on( | ||
21 | 'download-file', | ||
22 | async (_event, { url, content, fileOptions = {} }) => { | ||
23 | const win = BrowserWindow.getFocusedWindow(); | ||
24 | |||
25 | try { | ||
26 | if (!content) { | ||
27 | const dl = await download(win!, url, { | ||
28 | saveAs: true, | ||
29 | }); | ||
30 | debug('File saved to', dl.savePath); | ||
31 | } else { | ||
32 | const extension = mime.extension(fileOptions.mime); | ||
33 | const filename = `${fileOptions.name}.${extension}`; | ||
34 | |||
35 | try { | ||
36 | const saveDialog = await dialog.showSaveDialog(params.mainWindow, { | ||
37 | defaultPath: filename, | ||
38 | }); | ||
39 | |||
40 | if (saveDialog.canceled) return; | ||
41 | |||
42 | const binaryImage = decodeBase64Image(content); | ||
43 | writeFileSync( | ||
44 | saveDialog.filePath as PathLike, | ||
45 | binaryImage as unknown as string, | ||
46 | 'binary', | ||
47 | ); | ||
48 | |||
49 | debug('File blob saved to', saveDialog.filePath); | ||
50 | } catch (err) { | ||
51 | console.log(err); | ||
52 | } | ||
53 | } | ||
54 | } catch (e) { | ||
55 | console.error(e); | ||
56 | } | ||
57 | }, | ||
58 | ); | ||
59 | }; | ||
diff --git a/src/electron/ipc-api/focusState.js b/src/electron/ipc-api/focusState.ts index 0b4a0d8f3..01aa1a971 100644 --- a/src/electron/ipc-api/focusState.js +++ b/src/electron/ipc-api/focusState.ts | |||
@@ -1,4 +1,6 @@ | |||
1 | export default (params) => { | 1 | import { BrowserWindow } from 'electron'; |
2 | |||
3 | export default (params: { mainWindow: BrowserWindow }) => { | ||
2 | params.mainWindow.on('focus', () => { | 4 | params.mainWindow.on('focus', () => { |
3 | params.mainWindow.webContents.send('isWindowFocused', true); | 5 | params.mainWindow.webContents.send('isWindowFocused', true); |
4 | }); | 6 | }); |
diff --git a/src/electron/ipc-api/index.js b/src/electron/ipc-api/index.ts index 5da1edc39..06c50be10 100644 --- a/src/electron/ipc-api/index.js +++ b/src/electron/ipc-api/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { BrowserWindow, Tray } from 'electron'; | ||
1 | import autoUpdate from './autoUpdate'; | 2 | import autoUpdate from './autoUpdate'; |
2 | import settings from './settings'; | 3 | import settings from './settings'; |
3 | import appIndicator from './appIndicator'; | 4 | import appIndicator from './appIndicator'; |
@@ -7,13 +8,17 @@ import cld from './cld'; | |||
7 | import dnd from './dnd'; | 8 | import dnd from './dnd'; |
8 | import focusState from './focusState'; | 9 | import focusState from './focusState'; |
9 | 10 | ||
10 | export default (params) => { | 11 | export default (params: { |
12 | mainWindow: BrowserWindow; | ||
13 | settings: any; | ||
14 | tray: Tray; | ||
15 | }) => { | ||
11 | settings(params); | 16 | settings(params); |
12 | autoUpdate(params); | 17 | autoUpdate(params); |
13 | appIndicator(params); | 18 | appIndicator(params); |
14 | download(params); | 19 | download(params); |
15 | localServer(params); | 20 | localServer(params); |
16 | cld(params); | 21 | cld(); |
17 | dnd(); | 22 | dnd(); |
18 | focusState(params); | 23 | focusState(params); |
19 | }; | 24 | }; |
diff --git a/src/electron/ipc-api/localServer.js b/src/electron/ipc-api/localServer.ts index 591e70504..d318b93a5 100644 --- a/src/electron/ipc-api/localServer.js +++ b/src/electron/ipc-api/localServer.ts | |||
@@ -1,12 +1,12 @@ | |||
1 | import { ipcMain } from 'electron'; | 1 | import { ipcMain, BrowserWindow } from 'electron'; |
2 | import net from 'net'; | 2 | import net from 'net'; |
3 | import { LOCAL_HOSTNAME, LOCAL_PORT } from '../../config'; | 3 | import { LOCAL_HOSTNAME, LOCAL_PORT } from '../../config'; |
4 | import { userDataPath } from '../../environment'; | 4 | import { userDataPath } from '../../environment'; |
5 | import startServer from '../../internal-server/start'; | 5 | import startServer from '../../internal-server/start'; |
6 | 6 | ||
7 | const portInUse = function (port) { | 7 | const portInUse = (port: number): Promise<boolean> => |
8 | return new Promise((resolve) => { | 8 | new Promise(resolve => { |
9 | const server = net.createServer((socket) => { | 9 | const server = net.createServer(socket => { |
10 | socket.write('Echo server\r\n'); | 10 | socket.write('Echo server\r\n'); |
11 | socket.pipe(socket); | 11 | socket.pipe(socket); |
12 | }); | 12 | }); |
@@ -20,11 +20,10 @@ const portInUse = function (port) { | |||
20 | resolve(false); | 20 | resolve(false); |
21 | }); | 21 | }); |
22 | }); | 22 | }); |
23 | }; | ||
24 | 23 | ||
25 | let localServerStarted = false; | 24 | let localServerStarted = false; |
26 | 25 | ||
27 | export default (params) => { | 26 | export default (params: { mainWindow: BrowserWindow }) => { |
28 | ipcMain.on('startLocalServer', () => { | 27 | ipcMain.on('startLocalServer', () => { |
29 | if (!localServerStarted) { | 28 | if (!localServerStarted) { |
30 | // Find next unused port for server | 29 | // Find next unused port for server |
diff --git a/src/electron/ipc-api/settings.js b/src/electron/ipc-api/settings.js deleted file mode 100644 index 15182739c..000000000 --- a/src/electron/ipc-api/settings.js +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | import { ipcMain } from 'electron'; | ||
2 | |||
3 | export default (params) => { | ||
4 | ipcMain.on('getAppSettings', (event, type) => { | ||
5 | params.mainWindow.webContents.send('appSettings', { | ||
6 | type, | ||
7 | data: params.settings[type].allSerialized, | ||
8 | }); | ||
9 | }); | ||
10 | |||
11 | ipcMain.on('updateAppSettings', (event, args) => { | ||
12 | params.settings[args.type].set(args.data); | ||
13 | }); | ||
14 | }; | ||
diff --git a/src/electron/ipc-api/settings.ts b/src/electron/ipc-api/settings.ts new file mode 100644 index 000000000..72de6866d --- /dev/null +++ b/src/electron/ipc-api/settings.ts | |||
@@ -0,0 +1,14 @@ | |||
1 | import { ipcMain, BrowserWindow, Settings } from 'electron'; | ||
2 | |||
3 | export default (params: { mainWindow: BrowserWindow; settings: Settings }) => { | ||
4 | ipcMain.on('getAppSettings', (_event, type) => { | ||
5 | params.mainWindow.webContents.send('appSettings', { | ||
6 | type, | ||
7 | data: params.settings[type].allSerialized, | ||
8 | }); | ||
9 | }); | ||
10 | |||
11 | ipcMain.on('updateAppSettings', (_event, args) => { | ||
12 | params.settings[args.type].set(args.data); | ||
13 | }); | ||
14 | }; | ||
diff --git a/src/electron/macOSPermissions.js b/src/electron/macOSPermissions.ts index 887af2903..f5a8c7cc4 100644 --- a/src/electron/macOSPermissions.js +++ b/src/electron/macOSPermissions.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { systemPreferences, dialog } from 'electron'; | 1 | import { systemPreferences, BrowserWindow, dialog } from 'electron'; |
2 | import { pathExistsSync, mkdirSync, writeFileSync } from 'fs-extra'; | 2 | import { pathExistsSync, mkdirSync, writeFileSync } from 'fs-extra'; |
3 | import macosVersion from 'macos-version'; | 3 | import macosVersion from 'macos-version'; |
4 | import { dirname } from 'path'; | 4 | import { dirname } from 'path'; |
@@ -7,12 +7,15 @@ import { userDataPath } from '../environment'; | |||
7 | 7 | ||
8 | const debug = require('debug')('Ferdi:macOSPermissions'); | 8 | const debug = require('debug')('Ferdi:macOSPermissions'); |
9 | 9 | ||
10 | const isExplicitScreenCapturePermissionReqd = macosVersion.isGreaterThanOrEqualTo('10.15'); | 10 | const isExplicitScreenCapturePermissionReqd = |
11 | debug(`Should check explicitly for screen-capture permissions: ${isExplicitScreenCapturePermissionReqd}`); | 11 | macosVersion.isGreaterThanOrEqualTo('10.15'); |
12 | debug( | ||
13 | `Should check explicitly for screen-capture permissions: ${isExplicitScreenCapturePermissionReqd}`, | ||
14 | ); | ||
12 | 15 | ||
13 | const filePath = userDataPath('.has-app-requested-screen-capture-permissions'); | 16 | const filePath = userDataPath('.has-app-requested-screen-capture-permissions'); |
14 | 17 | ||
15 | function hasPromptedForScreenCapturePermission() { | 18 | function hasPromptedForScreenCapturePermission(): boolean { |
16 | if (!isExplicitScreenCapturePermissionReqd) { | 19 | if (!isExplicitScreenCapturePermissionReqd) { |
17 | return false; | 20 | return false; |
18 | } | 21 | } |
@@ -21,7 +24,7 @@ function hasPromptedForScreenCapturePermission() { | |||
21 | return filePath && pathExistsSync(filePath); | 24 | return filePath && pathExistsSync(filePath); |
22 | } | 25 | } |
23 | 26 | ||
24 | function hasScreenCapturePermissionAlreadyBeenGranted() { | 27 | function hasScreenCapturePermissionAlreadyBeenGranted(): boolean { |
25 | if (!isExplicitScreenCapturePermissionReqd) { | 28 | if (!isExplicitScreenCapturePermissionReqd) { |
26 | return true; | 29 | return true; |
27 | } | 30 | } |
@@ -35,7 +38,7 @@ function createStatusFile() { | |||
35 | try { | 38 | try { |
36 | writeFileSync(filePath, ''); | 39 | writeFileSync(filePath, ''); |
37 | } catch (error) { | 40 | } catch (error) { |
38 | if (error.code === 'ENOENT') { | 41 | if ((error as any).code === 'ENOENT') { |
39 | mkdirSync(dirname(filePath)); | 42 | mkdirSync(dirname(filePath)); |
40 | writeFileSync(filePath, ''); | 43 | writeFileSync(filePath, ''); |
41 | } | 44 | } |
@@ -44,7 +47,7 @@ function createStatusFile() { | |||
44 | } | 47 | } |
45 | } | 48 | } |
46 | 49 | ||
47 | export const askFormacOSPermissions = async mainWindow => { | 50 | export const askFormacOSPermissions = async (mainWindow: BrowserWindow) => { |
48 | debug('Checking camera & microphone permissions'); | 51 | debug('Checking camera & microphone permissions'); |
49 | systemPreferences.askForMediaAccess('camera'); | 52 | systemPreferences.askForMediaAccess('camera'); |
50 | systemPreferences.askForMediaAccess('microphone'); | 53 | systemPreferences.askForMediaAccess('microphone'); |
diff --git a/src/electron/webview-ime-focus.js b/src/electron/webview-ime-focus.js deleted file mode 100644 index e187ee0b4..000000000 --- a/src/electron/webview-ime-focus.js +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | import { webContents } from '@electron/remote'; | ||
2 | import { releaseDocumentFocus } from './webview-ime-focus-helpers'; | ||
3 | |||
4 | function giveWebviewDocumentFocus(element) { | ||
5 | releaseDocumentFocus(); | ||
6 | |||
7 | window.requestAnimationFrame(() => { | ||
8 | element.send('claim-document-focus'); | ||
9 | }); | ||
10 | } | ||
11 | |||
12 | function elementIsUnfocusedWebview(element) { | ||
13 | return element.tagName === 'WEBVIEW' && !webContents.fromId(element.getWebContentsId()).isFocused(); | ||
14 | } | ||
15 | |||
16 | function webviewDidAutofocus(element) { | ||
17 | function didKeyDown() { | ||
18 | element.removeEventListener('keydown', didKeyDown, true); | ||
19 | giveWebviewDocumentFocus(element); | ||
20 | } | ||
21 | |||
22 | element.addEventListener('keydown', didKeyDown, true); | ||
23 | } | ||
24 | |||
25 | function handleAutofocus(element) { | ||
26 | element.addEventListener('ipc-message', (event) => { | ||
27 | if (event.channel === 'autofocus') { | ||
28 | element.focus(); | ||
29 | webviewDidAutofocus(element); | ||
30 | } | ||
31 | }); | ||
32 | } | ||
33 | |||
34 | function didMouseDown(event) { | ||
35 | if (elementIsUnfocusedWebview(event.target)) { | ||
36 | giveWebviewDocumentFocus(event.target); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | document.addEventListener('mousedown', didMouseDown, true); | ||
41 | document.querySelectorAll('webview').forEach(handleAutofocus); | ||
diff --git a/src/electron/windowUtils.js b/src/electron/windowUtils.js deleted file mode 100644 index 23b946ac4..000000000 --- a/src/electron/windowUtils.js +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | /* eslint import/prefer-default-export: 0 */ | ||
2 | |||
3 | import { screen } from 'electron'; | ||
4 | |||
5 | export function isPositionValid(position) { | ||
6 | const displays = screen.getAllDisplays(); | ||
7 | const { x, y } = position; | ||
8 | return displays.some(({ | ||
9 | workArea, | ||
10 | }) => x >= workArea.x && x <= workArea.x + workArea.width && y >= workArea.y && y <= workArea.y + workArea.height); | ||
11 | } | ||
diff --git a/src/electron/windowUtils.ts b/src/electron/windowUtils.ts new file mode 100644 index 000000000..1db1ff246 --- /dev/null +++ b/src/electron/windowUtils.ts | |||
@@ -0,0 +1,13 @@ | |||
1 | import { screen } from 'electron'; | ||
2 | |||
3 | export function isPositionValid(position: { x: number; y: number }) { | ||
4 | const displays = screen.getAllDisplays(); | ||
5 | const { x, y } = position; | ||
6 | return displays.some( | ||
7 | ({ workArea }) => | ||
8 | x >= workArea.x && | ||
9 | x <= workArea.x + workArea.width && | ||
10 | y >= workArea.y && | ||
11 | y <= workArea.y + workArea.height, | ||
12 | ); | ||
13 | } | ||