From b7b8a65e18af8b31b45a754f61b0a6027f395b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ska=C5=82ka?= Date: Thu, 14 Sep 2023 15:00:31 +0200 Subject: [PATCH 1/3] migrate Visibility files to TypeScript --- .../{index.desktop.js => index.desktop.ts} | 12 ++---------- .../{index.native.js => index.native.ts} | 16 ++++------------ src/libs/Visibility/{index.js => index.ts} | 10 +--------- src/types/modules/electron.d.ts | 9 +++++++++ 4 files changed, 16 insertions(+), 31 deletions(-) rename src/libs/Visibility/{index.desktop.js => index.desktop.ts} (85%) rename src/libs/Visibility/{index.native.js => index.native.ts} (68%) rename src/libs/Visibility/{index.js => index.ts} (78%) create mode 100644 src/types/modules/electron.d.ts diff --git a/src/libs/Visibility/index.desktop.js b/src/libs/Visibility/index.desktop.ts similarity index 85% rename from src/libs/Visibility/index.desktop.js rename to src/libs/Visibility/index.desktop.ts index e3a7eab5bf56..5057365ef94e 100644 --- a/src/libs/Visibility/index.desktop.js +++ b/src/libs/Visibility/index.desktop.ts @@ -4,28 +4,20 @@ import ELECTRON_EVENTS from '../../../desktop/ELECTRON_EVENTS'; * Detects whether the app is visible or not. Electron supports document.visibilityState, * but switching to another app while Electron is partially occluded will not trigger a state of hidden * so we ask the main process synchronously whether the BrowserWindow.isFocused() - * - * @returns {Boolean} */ function isVisible() { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return window.electron.sendSync(ELECTRON_EVENTS.REQUEST_VISIBILITY); } -/** - * @returns {Boolean} - */ function hasFocus() { return true; } /** * Adds event listener for changes in visibility state - * - * @param {Function} callback - * - * @return {Function} removes the listener */ -function onVisibilityChange(callback) { +function onVisibilityChange(callback: () => void) { // Deliberately strip callback argument to be consistent across implementations window.electron.on(ELECTRON_EVENTS.FOCUS, () => callback()); window.electron.on(ELECTRON_EVENTS.BLUR, () => callback()); diff --git a/src/libs/Visibility/index.native.js b/src/libs/Visibility/index.native.ts similarity index 68% rename from src/libs/Visibility/index.native.js rename to src/libs/Visibility/index.native.ts index b888cf1a2b9f..3dc41c1340a1 100644 --- a/src/libs/Visibility/index.native.js +++ b/src/libs/Visibility/index.native.ts @@ -3,26 +3,18 @@ import {AppState} from 'react-native'; -/** - * @return {Boolean} - */ -const isVisible = () => AppState.currentState === 'active'; +function isVisible() { + return AppState.currentState === 'active'; +} -/** - * @returns {Boolean} - */ function hasFocus() { return true; } /** * Adds event listener for changes in visibility state - * - * @param {Function} callback - * - * @return {Function} removes the listener */ -function onVisibilityChange(callback) { +function onVisibilityChange(callback: () => void) { // Deliberately strip callback argument to be consistent across implementations const subscription = AppState.addEventListener('change', () => callback()); diff --git a/src/libs/Visibility/index.js b/src/libs/Visibility/index.ts similarity index 78% rename from src/libs/Visibility/index.js rename to src/libs/Visibility/index.ts index 91a003168ccd..ac9e8ae2705c 100644 --- a/src/libs/Visibility/index.js +++ b/src/libs/Visibility/index.ts @@ -2,8 +2,6 @@ import {AppState} from 'react-native'; /** * Detects whether the app is visible or not. - * - * @returns {Boolean} */ function isVisible() { return document.visibilityState === 'visible'; @@ -11,8 +9,6 @@ function isVisible() { /** * Whether the app is focused. - * - * @returns {Boolean} */ function hasFocus() { return document.hasFocus(); @@ -20,12 +16,8 @@ function hasFocus() { /** * Adds event listener for changes in visibility state - * - * @param {Function} callback - * - * @return {Function} removes the listener */ -function onVisibilityChange(callback) { +function onVisibilityChange(callback: () => void) { // Deliberately strip callback argument to be consistent across implementations const subscription = AppState.addEventListener('change', () => callback()); diff --git a/src/types/modules/electron.d.ts b/src/types/modules/electron.d.ts new file mode 100644 index 000000000000..f5d6b31f7db3 --- /dev/null +++ b/src/types/modules/electron.d.ts @@ -0,0 +1,9 @@ +declare global { + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + interface Window { + electron: Electron; + } +} + +// We used the export {} line to mark this file as an external module +export {}; From fd4fa9f6d4a4ecaeb437589d153495782e29611c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ska=C5=82ka?= Date: Tue, 19 Sep 2023 12:20:13 +0200 Subject: [PATCH 2/3] review changes --- src/libs/Visibility/index.desktop.ts | 14 +++++--------- src/libs/Visibility/index.native.ts | 13 +++++-------- src/libs/Visibility/index.ts | 13 +++++-------- src/libs/Visibility/types.ts | 5 +++++ src/types/modules/electron.d.ts | 2 +- 5 files changed, 21 insertions(+), 26 deletions(-) create mode 100644 src/libs/Visibility/types.ts diff --git a/src/libs/Visibility/index.desktop.ts b/src/libs/Visibility/index.desktop.ts index 5057365ef94e..bdc8b9a4267a 100644 --- a/src/libs/Visibility/index.desktop.ts +++ b/src/libs/Visibility/index.desktop.ts @@ -1,23 +1,19 @@ import ELECTRON_EVENTS from '../../../desktop/ELECTRON_EVENTS'; +import {HasFocus, IsVisible, OnVisibilityChange} from './types'; /** * Detects whether the app is visible or not. Electron supports document.visibilityState, * but switching to another app while Electron is partially occluded will not trigger a state of hidden * so we ask the main process synchronously whether the BrowserWindow.isFocused() */ -function isVisible() { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return window.electron.sendSync(ELECTRON_EVENTS.REQUEST_VISIBILITY); -} +const isVisible: IsVisible = () => !!window.electron.sendSync(ELECTRON_EVENTS.REQUEST_VISIBILITY); -function hasFocus() { - return true; -} +const hasFocus: HasFocus = () => true; /** * Adds event listener for changes in visibility state */ -function onVisibilityChange(callback: () => void) { +const onVisibilityChange: OnVisibilityChange = (callback) => { // Deliberately strip callback argument to be consistent across implementations window.electron.on(ELECTRON_EVENTS.FOCUS, () => callback()); window.electron.on(ELECTRON_EVENTS.BLUR, () => callback()); @@ -26,7 +22,7 @@ function onVisibilityChange(callback: () => void) { window.electron.removeAllListeners(ELECTRON_EVENTS.FOCUS); window.electron.removeAllListeners(ELECTRON_EVENTS.BLUR); }; -} +}; export default { isVisible, diff --git a/src/libs/Visibility/index.native.ts b/src/libs/Visibility/index.native.ts index 3dc41c1340a1..695df3651da7 100644 --- a/src/libs/Visibility/index.native.ts +++ b/src/libs/Visibility/index.native.ts @@ -2,24 +2,21 @@ // they do not use the Notification lib. import {AppState} from 'react-native'; +import {HasFocus, IsVisible, OnVisibilityChange} from './types'; -function isVisible() { - return AppState.currentState === 'active'; -} +const isVisible: IsVisible = () => AppState.currentState === 'active'; -function hasFocus() { - return true; -} +const hasFocus: HasFocus = () => true; /** * Adds event listener for changes in visibility state */ -function onVisibilityChange(callback: () => void) { +const onVisibilityChange: OnVisibilityChange = (callback) => { // Deliberately strip callback argument to be consistent across implementations const subscription = AppState.addEventListener('change', () => callback()); return () => subscription.remove(); -} +}; export default { isVisible, diff --git a/src/libs/Visibility/index.ts b/src/libs/Visibility/index.ts index ac9e8ae2705c..4cf18b010a07 100644 --- a/src/libs/Visibility/index.ts +++ b/src/libs/Visibility/index.ts @@ -1,28 +1,25 @@ import {AppState} from 'react-native'; +import {HasFocus, IsVisible, OnVisibilityChange} from './types'; /** * Detects whether the app is visible or not. */ -function isVisible() { - return document.visibilityState === 'visible'; -} +const isVisible: IsVisible = () => document.visibilityState === 'visible'; /** * Whether the app is focused. */ -function hasFocus() { - return document.hasFocus(); -} +const hasFocus: HasFocus = () => document.hasFocus(); /** * Adds event listener for changes in visibility state */ -function onVisibilityChange(callback: () => void) { +const onVisibilityChange: OnVisibilityChange = (callback) => { // Deliberately strip callback argument to be consistent across implementations const subscription = AppState.addEventListener('change', () => callback()); return () => subscription.remove(); -} +}; export default { isVisible, diff --git a/src/libs/Visibility/types.ts b/src/libs/Visibility/types.ts new file mode 100644 index 000000000000..0332f24740ce --- /dev/null +++ b/src/libs/Visibility/types.ts @@ -0,0 +1,5 @@ +type IsVisible = () => boolean; +type HasFocus = () => boolean; +type OnVisibilityChange = (callback: () => void) => () => void; + +export type {IsVisible, HasFocus, OnVisibilityChange}; diff --git a/src/types/modules/electron.d.ts b/src/types/modules/electron.d.ts index f5d6b31f7db3..01e2f2d322b8 100644 --- a/src/types/modules/electron.d.ts +++ b/src/types/modules/electron.d.ts @@ -1,7 +1,7 @@ declare global { // eslint-disable-next-line @typescript-eslint/consistent-type-definitions interface Window { - electron: Electron; + electron: Electron.IpcRenderer; } } From 5a9f707198d51ddcb3928535467617ef7411acc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ska=C5=82ka?= Date: Tue, 19 Sep 2023 12:55:29 +0200 Subject: [PATCH 3/3] retype electron.d.ts --- src/types/modules/electron.d.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/types/modules/electron.d.ts b/src/types/modules/electron.d.ts index 01e2f2d322b8..09e33f29ba38 100644 --- a/src/types/modules/electron.d.ts +++ b/src/types/modules/electron.d.ts @@ -1,7 +1,16 @@ +// TODO: Move this type to desktop/contextBridge.js once it is converted to TS +type ContextBridgeApi = { + send: (channel: string, data?: unknown) => void; + sendSync: (channel: string, data?: unknown) => unknown; + invoke: (channel: string, ...args: unknown) => Promise; + on: (channel: string, func: () => void) => void; + removeAllListeners: (channel: string) => void; +}; + declare global { // eslint-disable-next-line @typescript-eslint/consistent-type-definitions interface Window { - electron: Electron.IpcRenderer; + electron: ContextBridgeApi; } }