From b335300b716ec86e91f7dda78ac047903d59c56d Mon Sep 17 00:00:00 2001 From: Curry Yang <1019yanglu@gmail.com> Date: Tue, 15 Oct 2024 17:04:27 +0800 Subject: [PATCH] fix: stop interval when window not focused --- packages/insomnia/src/main/ipc/electron.ts | 5 ++- packages/insomnia/src/main/ipc/main.ts | 6 ++++ packages/insomnia/src/main/window-utils.ts | 17 +++++++++- packages/insomnia/src/preload.ts | 1 + .../dropdowns/git-sync-dropdown.tsx | 33 +++++++++++++++---- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/packages/insomnia/src/main/ipc/electron.ts b/packages/insomnia/src/main/ipc/electron.ts index f706d2ac7b5..cd65449e305 100644 --- a/packages/insomnia/src/main/ipc/electron.ts +++ b/packages/insomnia/src/main/ipc/electron.ts @@ -28,6 +28,7 @@ export type HandleChannels = | 'webSocket.open' | 'webSocket.readyState' | 'writeFile' + | 'isWindowFocused' | 'extractJsonFileFromPostmanDataDumpArchive'; export const ipcMainHandle = ( @@ -86,7 +87,9 @@ export type RendererOnChannels = | 'toggle-preferences-shortcuts' | 'toggle-preferences' | 'toggle-sidebar' - | 'updaterStatus'; + | 'updaterStatus' + | 'main-window-focus' + | 'main-window-blur'; export const ipcMainOn = ( channel: MainOnChannels, listener: ( diff --git a/packages/insomnia/src/main/ipc/main.ts b/packages/insomnia/src/main/ipc/main.ts index 216a90bd6e3..09dca0e66c8 100644 --- a/packages/insomnia/src/main/ipc/main.ts +++ b/packages/insomnia/src/main/ipc/main.ts @@ -14,6 +14,7 @@ import type { CurlBridgeAPI } from '../network/curl'; import { cancelCurlRequest, curlRequest } from '../network/libcurl-promise'; import { addExecutionStep, completeExecutionStep, getExecution, startExecution, type TimingStep, updateLatestStepName } from '../network/request-timing'; import type { WebSocketBridgeAPI } from '../network/websocket'; +import { isWindowFocused } from '../window-utils'; import { ipcMainHandle, ipcMainOn, ipcMainOnce, type RendererOnChannels } from './electron'; import extractPostmanDataDumpHandler from './extractPostmanDataDump'; import type { gRPCBridgeAPI } from './grpc'; @@ -31,6 +32,7 @@ export interface RendererToMainBridgeAPI { setMenuBarVisibility: (visible: boolean) => void; installPlugin: typeof installPlugin; writeFile: (options: { path: string; content: string }) => Promise; + isWindowFocused: () => Promise; cancelCurlRequest: typeof cancelCurlRequest; curlRequest: typeof curlRequest; on: (channel: RendererOnChannels, listener: (event: IpcRendererEvent, ...args: any[]) => void) => () => void; @@ -98,6 +100,10 @@ export function registerMainHandlers() { } }); + ipcMainHandle('isWindowFocused', async () => { + return isWindowFocused(); + }); + ipcMainHandle('curlRequest', (_, options: Parameters[0]) => { return curlRequest(options); }); diff --git a/packages/insomnia/src/main/window-utils.ts b/packages/insomnia/src/main/window-utils.ts index 0b66d432cd1..2fe34fea6f9 100644 --- a/packages/insomnia/src/main/window-utils.ts +++ b/packages/insomnia/src/main/window-utils.ts @@ -38,7 +38,7 @@ const DEFAULT_HEIGHT = 720; const MINIMUM_WIDTH = 500; const MINIMUM_HEIGHT = 400; -const browserWindows = new Map<'Insomnia' | 'HiddenBrowserWindow', ElectronBrowserWindow>(); +export const browserWindows = new Map<'Insomnia' | 'HiddenBrowserWindow', ElectronBrowserWindow>(); let localStorage: LocalStorage | null = null; let hiddenWindowIsBusy = false; @@ -271,6 +271,16 @@ export function createWindow({ firstLaunch }: { firstLaunch?: boolean } = {}): E } }); + mainBrowserWindow.on('focus', () => { + console.log('[main] window focus'); + mainBrowserWindow.webContents.send('main-window-focus'); + }); + + mainBrowserWindow.on('blur', () => { + console.log('[main] window blur'); + mainBrowserWindow.webContents.send('main-window-blur'); + }); + const applicationMenu: MenuItemConstructorOptions = { label: `${MNEMONIC_SYM}Application`, submenu: [ @@ -792,3 +802,8 @@ export function createWindowsAndReturnMain({ firstLaunch }: { firstLaunch?: bool } return mainWindow; } + +export const isWindowFocused = () => { + const mainWindow = browserWindows.get('Insomnia'); + return mainWindow?.isFocused(); +}; diff --git a/packages/insomnia/src/preload.ts b/packages/insomnia/src/preload.ts index fc994eb4346..e93131353c1 100644 --- a/packages/insomnia/src/preload.ts +++ b/packages/insomnia/src/preload.ts @@ -60,6 +60,7 @@ const main: Window['main'] = { curlRequest: options => ipcRenderer.invoke('curlRequest', options), cancelCurlRequest: options => ipcRenderer.send('cancelCurlRequest', options), writeFile: options => ipcRenderer.invoke('writeFile', options), + isWindowFocused: () => ipcRenderer.invoke('isWindowFocused'), on: (channel, listener) => { ipcRenderer.on(channel, listener); return () => ipcRenderer.removeListener(channel, listener); diff --git a/packages/insomnia/src/ui/components/dropdowns/git-sync-dropdown.tsx b/packages/insomnia/src/ui/components/dropdowns/git-sync-dropdown.tsx index 2c8e82770fc..924462638b5 100644 --- a/packages/insomnia/src/ui/components/dropdowns/git-sync-dropdown.tsx +++ b/packages/insomnia/src/ui/components/dropdowns/git-sync-dropdown.tsx @@ -1,5 +1,5 @@ import type { IconName, IconProp } from '@fortawesome/fontawesome-svg-core'; -import React, { type FC, useEffect, useState } from 'react'; +import React, { type FC, useEffect, useRef, useState } from 'react'; import { Button, Collection, Menu, MenuItem, MenuTrigger, Popover, Section, Tooltip, TooltipTrigger } from 'react-aria-components'; import { useFetcher, useParams, useRevalidator } from 'react-router-dom'; import { useInterval } from 'react-use'; @@ -40,6 +40,7 @@ export const GitSyncDropdown: FC = ({ gitRepository, isInsomniaSyncEnable const [isGitBranchesModalOpen, setIsGitBranchesModalOpen] = useState(false); const [isGitLogModalOpen, setIsGitLogModalOpen] = useState(false); const [isGitStagingModalOpen, setIsGitStagingModalOpen] = useState(false); + const [isWindowFocused, setIsWindowFocused] = useState(false); const gitPushFetcher = useFetcher(); const gitPullFetcher = useFetcher(); @@ -48,11 +49,28 @@ export const GitSyncDropdown: FC = ({ gitRepository, isInsomniaSyncEnable const gitFetchFetcher = useFetcher(); const gitStatusFetcher = useFetcher(); + const isCheckingGitChanges = useRef(false); + const loadingPush = gitPushFetcher.state === 'loading'; const loadingPull = gitPullFetcher.state === 'loading'; const loadingFetch = gitFetchFetcher.state === 'loading'; const loadingStatus = gitStatusFetcher.state === 'loading'; + useEffect(() => { + (async () => { + const isWindowFocused = await window.main.isWindowFocused(); + setIsWindowFocused(isWindowFocused); + })(); + + window.main.on('main-window-focus', () => { + setIsWindowFocused(true); + }); + + window.main.on('main-window-blur', () => { + setIsWindowFocused(false); + }); + }, []); + useEffect(() => { if ( gitRepository?.uri && @@ -85,11 +103,14 @@ export const GitSyncDropdown: FC = ({ gitRepository, isInsomniaSyncEnable } }, [gitStatusFetcher, organizationId, projectId, shouldFetchGitRepoStatus, workspaceId]); - useInterval(() => { - requestIdleCallback(() => { - checkGitChanges(workspaceId); - }); - }, 30 * 1000); + useInterval(async () => { + if (isCheckingGitChanges.current) { + return; + } + isCheckingGitChanges.current = true; + await checkGitChanges(workspaceId); + isCheckingGitChanges.current = false; + }, isWindowFocused ? 1000 : null); useEffect(() => { if (shouldFetchGitRepoStatus) {