From b5b91977eca5b2f65f65443422fd474bda7d243e Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Wed, 27 Mar 2024 18:47:04 -0400 Subject: [PATCH 01/22] Move startup template loading to main process --- src/common/safeIpc.ts | 2 +- src/main/gui/main-window.ts | 14 +++++++--- src/renderer/contexts/GlobalNodeState.tsx | 31 ++--------------------- 3 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index 4c2f8508e..fcd6bb040 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -39,7 +39,7 @@ export interface InvokeChannels { FileSaveResult, [saveData: SaveData, defaultPath: string | undefined] >; - 'get-cli-open': ChannelInfo | undefined>; + 'get-auto-open': ChannelInfo | undefined>; 'owns-backend': ChannelInfo; 'restart-backend': ChannelInfo; 'relaunch-application': ChannelInfo; diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 00cce253d..6d9ab4d16 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -151,10 +151,13 @@ const registerEventHandlerPreSetup = ( if (globalThis.startupFile) { // Open file with chaiNNer on other platforms const result = openSaveFile(globalThis.startupFile); - ipcMain.handle('get-cli-open', () => result); + ipcMain.handle('get-auto-open', () => result); globalThis.startupFile = null; + } else if (settings.startupTemplate) { + const result = openSaveFile(settings.startupTemplate); + ipcMain.handle('get-auto-open', () => result); } else { - ipcMain.handle('get-cli-open', () => undefined); + ipcMain.handle('get-auto-open', () => undefined); } // We remove the event we created in main.ts earlier on app.removeAllListeners('open-file'); @@ -171,9 +174,12 @@ const registerEventHandlerPreSetup = ( if (args.file) { // Open file with chaiNNer on other platforms const result = openSaveFile(args.file); - ipcMain.handle('get-cli-open', () => result); + ipcMain.handle('get-auto-open', () => result); + } else if (settings.startupTemplate) { + const result = openSaveFile(settings.startupTemplate); + ipcMain.handle('get-auto-open', () => result); } else { - ipcMain.handle('get-cli-open', () => undefined); + ipcMain.handle('get-auto-open', () => undefined); } app.on('second-instance', (_event, commandLine) => { diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index 1cdf1ad74..e3459e310 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -29,7 +29,7 @@ import { getEffectivelyDisabledNodes } from '../../common/nodes/disabled'; import { ChainLineage } from '../../common/nodes/lineage'; import { TypeState } from '../../common/nodes/TypeState'; import { ipcRenderer } from '../../common/safeIpc'; -import { ParsedSaveData, SaveData, openSaveFile } from '../../common/SaveFile'; +import { ParsedSaveData, SaveData } from '../../common/SaveFile'; import { EMPTY_SET, @@ -669,7 +669,7 @@ export const GlobalProvider = memo( useAsyncEffect( () => async () => { - const result = await ipcRenderer.invoke('get-cli-open'); + const result = await ipcRenderer.invoke('get-auto-open'); if (result) { if (result.kind === 'Success') { await setStateFromJSONRef.current(result.saveData, result.path, true); @@ -720,33 +720,6 @@ export const GlobalProvider = memo( // eslint-disable-next-line @typescript-eslint/no-misused-promises useIpcRendererListener('file-export-template', exportTemplate); - const [firstLoad, setFirstLoad] = useSessionStorage('firstLoad', true); - useAsyncEffect( - () => async () => { - if (firstLoad && startupTemplate) { - try { - const saveFile = await openSaveFile(startupTemplate); - if (saveFile.kind === 'Success') { - await setStateFromJSONRef.current(saveFile.saveData, '', true); - } else { - sendAlert({ - type: AlertType.ERROR, - message: `Unable to open file ${startupTemplate}: ${saveFile.error}`, - }); - } - } catch (error) { - log.error(error); - sendAlert({ - type: AlertType.ERROR, - message: `Unable to open file ${startupTemplate}`, - }); - } - setFirstLoad(false); - } - }, - [firstLoad, sendAlert, setFirstLoad, startupTemplate] - ); - const removeNodesById = useCallback( (ids: readonly string[]) => { if (ids.length === 0) return; From cfadb4f1438212729ee35cb278a3498d8435b29a Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Wed, 27 Mar 2024 18:56:49 -0400 Subject: [PATCH 02/22] remove unused variable --- src/renderer/contexts/GlobalNodeState.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index e3459e310..d04b3a2d8 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -169,7 +169,7 @@ export const GlobalProvider = memo( ({ children, reactFlowWrapper }: React.PropsWithChildren) => { const { sendAlert, sendToast, showAlert } = useContext(AlertBoxContext); const { schemata, functionDefinitions, scope, backend } = useContext(BackendContext); - const { startupTemplate, viewportExportPadding } = useSettings(); + const { viewportExportPadding } = useSettings(); const [nodeChanges, addNodeChanges, nodeChangesRef] = useChangeCounter(); const [edgeChanges, addEdgeChanges, edgeChangesRef] = useChangeCounter(); From 0180082558e0b24d382129884ec78d72bb25b7b6 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 00:46:25 -0400 Subject: [PATCH 03/22] replace initial batch of frontend FS --- src/common/safeIpc.ts | 10 ++++++++++ src/main/gui/main-window.ts | 19 +++++++++++++++++++ .../components/groups/NcnnFileInputsGroup.tsx | 6 ++++-- .../components/settings/components.tsx | 16 +++++++++++----- src/renderer/helpers/copyAndPaste.ts | 5 +++-- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index fcd6bb040..c7f513109 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -8,6 +8,7 @@ import { ipcMain as unsafeIpcMain, ipcRenderer as unsafeIpcRenderer, } from 'electron'; +import { MakeDirectoryOptions } from 'fs'; import { FileOpenResult, FileSaveResult, PythonInfo, Version } from './common-types'; import { ParsedSaveData, SaveData } from './SaveFile'; import { ChainnerSettings } from './settings/settings'; @@ -50,6 +51,15 @@ export interface InvokeChannels { // settings 'get-settings': ChannelInfo; 'set-settings': ChannelInfo; + + // fs + 'fs-read-file': ChannelInfo; + 'fs-write-file': ChannelInfo; + 'fs-exists': ChannelInfo; + 'fs-mkdir': ChannelInfo; + 'fs-readdir': ChannelInfo; + 'fs-unlink': ChannelInfo; + 'fs-access': ChannelInfo; } export interface SendChannels { diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 6d9ab4d16..3842a97c5 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -1,5 +1,6 @@ import { BrowserWindow, app, dialog, nativeTheme, powerSaveBlocker, shell } from 'electron'; import EventSource from 'eventsource'; +import fs, { constants } from 'fs/promises'; import { t } from 'i18next'; import { BackendEventMap } from '../../common/Backend'; import { Version } from '../../common/common-types'; @@ -195,6 +196,24 @@ const registerEventHandlerPreSetup = ( })().catch(log.error); }); } + + // Handle filesystem + ipcMain.handle('fs-read-file', async (event, path) => fs.readFile(path, { encoding: 'utf8' })); + ipcMain.handle('fs-write-file', async (event, path, content) => + fs.writeFile(path, content, { encoding: 'utf8' }) + ); + ipcMain.handle('fs-exists', async (event, path) => { + try { + await fs.access(path, constants.F_OK); + return true; + } catch { + return false; + } + }); + ipcMain.handle('fs-mkdir', async (event, path, options) => fs.mkdir(path, options)); + ipcMain.handle('fs-readdir', async (event, path) => fs.readdir(path)); + ipcMain.handle('fs-unlink', async (event, path) => fs.unlink(path)); + ipcMain.handle('fs-access', async (event, path) => fs.access(path)); }; const registerEventHandlerPostSetup = ( diff --git a/src/renderer/components/groups/NcnnFileInputsGroup.tsx b/src/renderer/components/groups/NcnnFileInputsGroup.tsx index 18f2cab9c..5dd985420 100644 --- a/src/renderer/components/groups/NcnnFileInputsGroup.tsx +++ b/src/renderer/components/groups/NcnnFileInputsGroup.tsx @@ -1,11 +1,13 @@ import { memo, useEffect } from 'react'; import { log } from '../../../common/log'; -import { checkFileExists, getInputValue } from '../../../common/util'; +import { ipcRenderer } from '../../../common/safeIpc'; +import { getInputValue } from '../../../common/util'; import { SchemaInput } from '../inputs/SchemaInput'; import { GroupProps } from './props'; const ifExists = (file: string, then: () => void) => { - checkFileExists(file) + ipcRenderer + .invoke('fs-exists', file) .then((exists) => { if (exists) { then(); diff --git a/src/renderer/components/settings/components.tsx b/src/renderer/components/settings/components.tsx index 44224c892..9a38627ea 100644 --- a/src/renderer/components/settings/components.tsx +++ b/src/renderer/components/settings/components.tsx @@ -9,7 +9,6 @@ import { Select, Switch, } from '@chakra-ui/react'; -import { access, mkdir, readdir, unlink } from 'fs/promises'; import path from 'path'; import { memo, useEffect, useMemo } from 'react'; import { Setting } from '../../../common/common-types'; @@ -130,9 +129,14 @@ const CacheSetting = memo(({ setting, value, setValue }: SettingsProps<'cache'>) onClick={() => { locationPromise .then(async (cacheLocation) => { - const files = await readdir(cacheLocation); + const files = await ipcRenderer.invoke('fs-readdir', cacheLocation); await Promise.all( - files.map((file) => unlink(path.join(cacheLocation, file))) + files.map((file) => + ipcRenderer.invoke( + 'fs-unlink', + path.join(cacheLocation, file) + ) + ) ); }) .catch(log.error); @@ -151,9 +155,11 @@ const CacheSetting = memo(({ setting, value, setValue }: SettingsProps<'cache'>) locationPromise .then(async (cacheLocation) => { try { - await access(cacheLocation); + await ipcRenderer.invoke('fs-access', cacheLocation); } catch (error) { - await mkdir(cacheLocation, { recursive: true }); + await ipcRenderer.invoke('fs-mkdir', cacheLocation, { + recursive: true, + }); } setValue(cacheLocation); }) diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 51327c92e..b42e0407d 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -1,11 +1,11 @@ import { clipboard } from 'electron'; -import { writeFile } from 'fs/promises'; import os from 'os'; import path from 'path'; import { Edge, Node, Project } from 'reactflow'; import { v4 as uuid4 } from 'uuid'; import { EdgeData, InputId, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; +import { ipcRenderer } from '../../common/safeIpc'; import { createUniqueId, deriveUniqueId } from '../../common/util'; import { NodeProto, copyEdges, copyNodes, setSelected } from './reactFlowUtil'; import { SetState } from './types'; @@ -108,7 +108,8 @@ export const pasteFromClipboard = ( case 'image/png': { const imgData = clipboard.readImage().toPNG(); const imgPath = path.join(os.tmpdir(), `chaiNNer-clipboard-${uuid4()}.png`); - writeFile(imgPath, imgData) + ipcRenderer + .invoke('fs-write-file', imgPath, imgData) .then(() => { log.debug('Clipboard image', imgPath); let positionX = 0; From e548ab9d9ba4c899e9365f6bd655b69142d555d4 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 00:54:02 -0400 Subject: [PATCH 04/22] move input override code that the renderer needs --- src/common/input-override-common.ts | 9 +++++++++ src/common/input-override.ts | 9 +-------- src/renderer/hooks/useInputRefactor.tsx | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 src/common/input-override-common.ts diff --git a/src/common/input-override-common.ts b/src/common/input-override-common.ts new file mode 100644 index 000000000..c329bdfe5 --- /dev/null +++ b/src/common/input-override-common.ts @@ -0,0 +1,9 @@ +import { InputId } from './common-types'; + +export type InputOverrideId = string & { readonly __input_override_id?: never }; + +export const createInputOverrideId = (nodeId: string, inputId: InputId): InputOverrideId => { + if (nodeId.length !== 36) + throw new Error('Expected node id to be a 36 character hexadecimal UUID.'); + return `#${nodeId}:${inputId}`; +}; diff --git a/src/common/input-override.ts b/src/common/input-override.ts index 193711f02..bcdd82c66 100644 --- a/src/common/input-override.ts +++ b/src/common/input-override.ts @@ -1,19 +1,12 @@ import { readFile } from 'fs/promises'; import { extname } from 'path'; import { EdgeData, InputData, InputId, InputValue, Mutable, NodeData } from './common-types'; +import { InputOverrideId } from './input-override-common'; import { log } from './log'; import { SchemaMap } from './SchemaMap'; import { joinEnglish } from './util'; import type { Edge, Node } from 'reactflow'; -export type InputOverrideId = string & { readonly __input_override_id?: never }; - -export const createInputOverrideId = (nodeId: string, inputId: InputId): InputOverrideId => { - if (nodeId.length !== 36) - throw new Error('Expected node id to be a 36 character hexadecimal UUID.'); - return `#${nodeId}:${inputId}`; -}; - const isValidInputOverrideId = (id: InputOverrideId) => /^#[a-f0-9-]{36}:\d+$/.test(id); export const parseInputOverrideId = (id: InputOverrideId): { nodeId: string; inputId: InputId } => { if (!isValidInputOverrideId(id)) throw new Error(`"${id}" is not a valid input override id.`); diff --git a/src/renderer/hooks/useInputRefactor.tsx b/src/renderer/hooks/useInputRefactor.tsx index 6d2f371fa..03b61cae6 100644 --- a/src/renderer/hooks/useInputRefactor.tsx +++ b/src/renderer/hooks/useInputRefactor.tsx @@ -16,7 +16,7 @@ import { PartialBy, SchemaId, } from '../../common/common-types'; -import { createInputOverrideId } from '../../common/input-override'; +import { createInputOverrideId } from '../../common/input-override-common'; import { createUniqueId } from '../../common/util'; import { BackendContext } from '../contexts/BackendContext'; import { FakeNodeContext } from '../contexts/FakeExampleContext'; From f9741e8172dd45eeadd30cff36d39b23b2a70bbc Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 11:56:18 -0400 Subject: [PATCH 05/22] more correct typing for read and write file, pass through options --- src/common/safeIpc.ts | 35 +++++++++++++++++++++++++++++++++-- src/main/gui/main-window.ts | 6 +++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index c7f513109..eca7c641f 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -9,6 +9,7 @@ import { ipcRenderer as unsafeIpcRenderer, } from 'electron'; import { MakeDirectoryOptions } from 'fs'; +import { Mode, ObjectEncodingOptions, OpenMode, PathLike } from 'original-fs'; import { FileOpenResult, FileSaveResult, PythonInfo, Version } from './common-types'; import { ParsedSaveData, SaveData } from './SaveFile'; import { ChainnerSettings } from './settings/settings'; @@ -53,8 +54,38 @@ export interface InvokeChannels { 'set-settings': ChannelInfo; // fs - 'fs-read-file': ChannelInfo; - 'fs-write-file': ChannelInfo; + 'fs-read-file': ChannelInfo< + string, + // Mostly copied this from the original fs.readFile, but had to remove some bits due to being unable to import the types + [ + path: PathLike, + options: + | { + encoding: BufferEncoding; + flag?: OpenMode | undefined; + } + | BufferEncoding + ] + >; + 'fs-write-file': ChannelInfo< + void, + // Mostly copied this from the original fs.writeFile, but had to remove some bits due to being unable to import the types + [ + file: PathLike, + data: + | string + | NodeJS.ArrayBufferView + | Iterable + | AsyncIterable, + options?: + | (ObjectEncodingOptions & { + mode?: Mode | undefined; + flag?: OpenMode | undefined; + }) + | BufferEncoding + | null + ] + >; 'fs-exists': ChannelInfo; 'fs-mkdir': ChannelInfo; 'fs-readdir': ChannelInfo; diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 3842a97c5..728904b49 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -198,9 +198,9 @@ const registerEventHandlerPreSetup = ( } // Handle filesystem - ipcMain.handle('fs-read-file', async (event, path) => fs.readFile(path, { encoding: 'utf8' })); - ipcMain.handle('fs-write-file', async (event, path, content) => - fs.writeFile(path, content, { encoding: 'utf8' }) + ipcMain.handle('fs-read-file', async (event, path, options) => fs.readFile(path, options)); + ipcMain.handle('fs-write-file', async (event, path, content, options) => + fs.writeFile(path, content, options) ); ipcMain.handle('fs-exists', async (event, path) => { try { From c08cd54ee28575fd511a833ef5c80a528d111757 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 12:36:53 -0400 Subject: [PATCH 06/22] move shell calls to main process --- src/common/safeIpc.ts | 4 ++++ src/main/gui/main-window.ts | 4 ++++ src/renderer/components/inputs/DirectoryInput.tsx | 7 +++++-- src/renderer/components/inputs/FileInput.tsx | 5 +++-- src/renderer/contexts/AlertBoxContext.tsx | 10 ++++++---- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index eca7c641f..90d7bd988 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -91,6 +91,10 @@ export interface InvokeChannels { 'fs-readdir': ChannelInfo; 'fs-unlink': ChannelInfo; 'fs-access': ChannelInfo; + + // Electron + 'shell-showItemInFolder': ChannelInfo; + 'shell-openPath': ChannelInfo; } export interface SendChannels { diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 728904b49..e13d7bc2e 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -214,6 +214,10 @@ const registerEventHandlerPreSetup = ( ipcMain.handle('fs-readdir', async (event, path) => fs.readdir(path)); ipcMain.handle('fs-unlink', async (event, path) => fs.unlink(path)); ipcMain.handle('fs-access', async (event, path) => fs.access(path)); + + // Handle electron + ipcMain.handle('shell-showItemInFolder', (event, fullPath) => shell.showItemInFolder(fullPath)); + ipcMain.handle('shell-openPath', (event, fullPath) => shell.openPath(fullPath)); }; const registerEventHandlerPostSetup = ( diff --git a/src/renderer/components/inputs/DirectoryInput.tsx b/src/renderer/components/inputs/DirectoryInput.tsx index f6d0f7686..e6cf7b717 100644 --- a/src/renderer/components/inputs/DirectoryInput.tsx +++ b/src/renderer/components/inputs/DirectoryInput.tsx @@ -9,11 +9,12 @@ import { MenuList, Tooltip, } from '@chakra-ui/react'; -import { clipboard, shell } from 'electron'; +import { clipboard } from 'electron'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { BsFolderPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; +import { log } from '../../../common/log'; import { ipcRenderer } from '../../../common/safeIpc'; import { getFields, isDirectory } from '../../../common/types/util'; import { useContextMenu } from '../../hooks/useContextMenu'; @@ -79,7 +80,9 @@ export const DirectoryInput = memo( isDisabled={!displayDirectory} onClick={() => { if (displayDirectory) { - shell.showItemInFolder(displayDirectory); + ipcRenderer + .invoke('shell-showItemInFolder', displayDirectory) + .catch(log.error); } }} > diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index 982ab1a50..2c7aae4fa 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -9,13 +9,14 @@ import { Tooltip, VStack, } from '@chakra-ui/react'; -import { clipboard, shell } from 'electron'; +import { clipboard } from 'electron'; import path from 'path'; import { DragEvent, memo } from 'react'; import { useTranslation } from 'react-i18next'; import { BsFileEarmarkPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; import { useContext } from 'use-context-selector'; +import { log } from '../../../common/log'; import { ipcRenderer } from '../../../common/safeIpc'; import { AlertBoxContext } from '../../contexts/AlertBoxContext'; import { getSingleFileWithExtension } from '../../helpers/dataTransfer'; @@ -120,7 +121,7 @@ export const FileInput = memo( isDisabled={!filePath} onClick={() => { if (filePath) { - shell.showItemInFolder(filePath); + ipcRenderer.invoke('shell-showItemInFolder', filePath).catch(log.error); } }} > diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index e62f8dd7f..9d24a1694 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -16,7 +16,7 @@ import { useDisclosure, useToast, } from '@chakra-ui/react'; -import { app, clipboard, shell } from 'electron'; +import { app, clipboard } from 'electron'; import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; @@ -182,9 +182,11 @@ const getButtons = ( ipcRenderer .invoke('get-appdata') .then((appDataPath) => { - shell.openPath(path.join(appDataPath, 'logs')).catch(() => { - log.error('Failed to open logs folder'); - }); + ipcRenderer + .invoke('shell-openPath', path.join(appDataPath, 'logs')) + .catch(() => { + log.error('Failed to open logs folder'); + }); }) .catch(() => { log.error('Failed to get appdata path'); From e5f91541bb92709ee96df03a365329f2be869ff5 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 12:43:56 -0400 Subject: [PATCH 07/22] move app.quit to main --- src/common/safeIpc.ts | 1 + src/main/gui/main-window.ts | 1 + src/renderer/contexts/AlertBoxContext.tsx | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index 90d7bd988..05a634f9a 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -95,6 +95,7 @@ export interface InvokeChannels { // Electron 'shell-showItemInFolder': ChannelInfo; 'shell-openPath': ChannelInfo; + 'app-quit': ChannelInfo; } export interface SendChannels { diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index e13d7bc2e..606775b9a 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -218,6 +218,7 @@ const registerEventHandlerPreSetup = ( // Handle electron ipcMain.handle('shell-showItemInFolder', (event, fullPath) => shell.showItemInFolder(fullPath)); ipcMain.handle('shell-openPath', (event, fullPath) => shell.openPath(fullPath)); + ipcMain.handle('app-quit', () => app.quit()); }; const registerEventHandlerPostSetup = ( diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index 9d24a1694..a8ae870ec 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -16,7 +16,7 @@ import { useDisclosure, useToast, } from '@chakra-ui/react'; -import { app, clipboard } from 'electron'; +import { clipboard } from 'electron'; import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; @@ -205,7 +205,9 @@ const getButtons = ( ref={cancelRef} onClick={() => { window.close(); - app.quit(); + ipcRenderer.invoke('app-quit').catch(() => { + log.error('Failed to quit application'); + }); }} > Exit Application From 73db236661664fe03f6526cfd6bd6a5c1459f433 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 13:01:22 -0400 Subject: [PATCH 08/22] initial clipboard replacements --- src/common/safeIpc.ts | 2 ++ src/main/gui/main-window.ts | 12 ++++++++- .../components/inputs/DirectoryInput.tsx | 5 ++-- src/renderer/components/inputs/FileInput.tsx | 7 ++--- .../components/inputs/NumberInput.tsx | 26 ++++++++++++------- .../components/inputs/SliderInput.tsx | 20 +++++++++----- src/renderer/components/inputs/TextInput.tsx | 24 +++++++++++------ .../components/node/special/NoteNode.tsx | 23 ++++++++++------ src/renderer/contexts/AlertBoxContext.tsx | 7 +++-- src/renderer/contexts/DependencyContext.tsx | 16 +++++++----- 10 files changed, 96 insertions(+), 46 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index 05a634f9a..0368b56dd 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -96,6 +96,8 @@ export interface InvokeChannels { 'shell-showItemInFolder': ChannelInfo; 'shell-openPath': ChannelInfo; 'app-quit': ChannelInfo; + 'clipboard-writeText': ChannelInfo; + 'clipboard-readText': ChannelInfo; } export interface SendChannels { diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 606775b9a..bcb306238 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -1,4 +1,12 @@ -import { BrowserWindow, app, dialog, nativeTheme, powerSaveBlocker, shell } from 'electron'; +import { + BrowserWindow, + app, + clipboard, + dialog, + nativeTheme, + powerSaveBlocker, + shell, +} from 'electron'; import EventSource from 'eventsource'; import fs, { constants } from 'fs/promises'; import { t } from 'i18next'; @@ -219,6 +227,8 @@ const registerEventHandlerPreSetup = ( ipcMain.handle('shell-showItemInFolder', (event, fullPath) => shell.showItemInFolder(fullPath)); ipcMain.handle('shell-openPath', (event, fullPath) => shell.openPath(fullPath)); ipcMain.handle('app-quit', () => app.quit()); + ipcMain.handle('clipboard-writeText', (event, text) => clipboard.writeText(text)); + ipcMain.handle('clipboard-readText', () => clipboard.readText()); }; const registerEventHandlerPostSetup = ( diff --git a/src/renderer/components/inputs/DirectoryInput.tsx b/src/renderer/components/inputs/DirectoryInput.tsx index e6cf7b717..ec28ea360 100644 --- a/src/renderer/components/inputs/DirectoryInput.tsx +++ b/src/renderer/components/inputs/DirectoryInput.tsx @@ -9,7 +9,6 @@ import { MenuList, Tooltip, } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { BsFolderPlus } from 'react-icons/bs'; @@ -93,7 +92,9 @@ export const DirectoryInput = memo( isDisabled={!displayDirectory} onClick={() => { if (displayDirectory) { - clipboard.writeText(displayDirectory); + ipcRenderer + .invoke('clipboard-writeText', displayDirectory) + .catch(log.error); } }} > diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index 2c7aae4fa..649c5e6c9 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -9,7 +9,6 @@ import { Tooltip, VStack, } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import path from 'path'; import { DragEvent, memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -132,7 +131,9 @@ export const FileInput = memo( isDisabled={!filePath} onClick={() => { if (filePath) { - clipboard.writeText(path.parse(filePath).name); + ipcRenderer + .invoke('clipboard-writeText', path.parse(filePath).name) + .catch(log.error); } }} > @@ -143,7 +144,7 @@ export const FileInput = memo( isDisabled={!filePath} onClick={() => { if (filePath) { - clipboard.writeText(filePath); + ipcRenderer.invoke('clipboard-writeText', filePath).catch(log.error); } }} > diff --git a/src/renderer/components/inputs/NumberInput.tsx b/src/renderer/components/inputs/NumberInput.tsx index a69641f40..97875a2a9 100644 --- a/src/renderer/components/inputs/NumberInput.tsx +++ b/src/renderer/components/inputs/NumberInput.tsx @@ -1,9 +1,10 @@ import { isNumericLiteral } from '@chainner/navi'; import { HStack, MenuItem, MenuList } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import { memo, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { MdContentCopy, MdContentPaste } from 'react-icons/md'; +import { log } from '../../../common/log'; +import { ipcRenderer } from '../../../common/safeIpc'; import { areApproximatelyEqual } from '../../../common/util'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; @@ -58,7 +59,7 @@ export const NumberInput = memo( icon={} isDisabled={!displayString} onClick={() => { - clipboard.writeText(displayString); + ipcRenderer.invoke('clipboard-writeText', displayString).catch(log.error); }} > {t('inputs.number.copyText', 'Copy Number')} @@ -66,14 +67,19 @@ export const NumberInput = memo( } onClick={() => { - const n = Number(clipboard.readText()); - if ( - !Number.isNaN(n) && - (min == null || min <= n) && - (max == null || max >= n) - ) { - setValue(n); - } + ipcRenderer + .invoke('clipboard-readText') + .then((clipboardValue) => { + const n = Number(clipboardValue); + if ( + !Number.isNaN(n) && + (min == null || min <= n) && + (max == null || max >= n) + ) { + setValue(n); + } + }) + .catch(log.error); }} > {t('inputs.number.paste', 'Paste')} diff --git a/src/renderer/components/inputs/SliderInput.tsx b/src/renderer/components/inputs/SliderInput.tsx index cab155e9c..260eab015 100644 --- a/src/renderer/components/inputs/SliderInput.tsx +++ b/src/renderer/components/inputs/SliderInput.tsx @@ -1,11 +1,12 @@ import { isNumericLiteral } from '@chainner/navi'; import { HStack, MenuItem, MenuList, Text, VStack } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { MdContentCopy, MdContentPaste } from 'react-icons/md'; import { useContext, useContextSelector } from 'use-context-selector'; import { Input, OfKind } from '../../../common/common-types'; +import { log } from '../../../common/log'; +import { ipcRenderer } from '../../../common/safeIpc'; import { assertNever } from '../../../common/util'; import { BackendContext } from '../../contexts/BackendContext'; import { InputContext } from '../../contexts/InputContext'; @@ -152,7 +153,9 @@ export const SliderInput = memo( } onClick={() => { - clipboard.writeText(String(displaySliderValue)); + ipcRenderer + .invoke('clipboard-writeText', String(displaySliderValue)) + .catch(log.error); }} > {t('inputs.number.copyText', 'Copy Number')} @@ -160,10 +163,15 @@ export const SliderInput = memo( } onClick={() => { - const n = Number(clipboard.readText()); - if (!Number.isNaN(n) && min <= n && max >= n) { - setValue(n); - } + ipcRenderer + .invoke('clipboard-readText') + .then((clipboardValue) => { + const n = Number(clipboardValue); + if (!Number.isNaN(n) && min <= n && max >= n) { + setValue(n); + } + }) + .catch(log.error); }} > {t('inputs.number.paste', 'Paste')} diff --git a/src/renderer/components/inputs/TextInput.tsx b/src/renderer/components/inputs/TextInput.tsx index b7d017a2e..e7314c642 100644 --- a/src/renderer/components/inputs/TextInput.tsx +++ b/src/renderer/components/inputs/TextInput.tsx @@ -1,11 +1,12 @@ import { Center, Input, MenuItem, MenuList, Textarea } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import { Resizable } from 're-resizable'; import { ChangeEvent, memo, useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { MdContentCopy, MdContentPaste } from 'react-icons/md'; import { useContextSelector } from 'use-context-selector'; import { useDebouncedCallback } from 'use-debounce'; +import { log } from '../../../common/log'; +import { ipcRenderer } from '../../../common/safeIpc'; import { GlobalVolatileContext } from '../../contexts/GlobalNodeState'; import { typeToString } from '../../helpers/naviHelpers'; import { useContextMenu } from '../../hooks/useContextMenu'; @@ -90,7 +91,7 @@ export const TextInput = memo( isDisabled={!displayText} onClick={() => { if (displayText !== undefined) { - clipboard.writeText(displayText); + ipcRenderer.invoke('clipboard-writeText', displayText).catch(log.error); } }} > @@ -100,12 +101,19 @@ export const TextInput = memo( icon={} isDisabled={isConnected} onClick={() => { - let text = clipboard.readText(); - // replace new lines - text = text.replace(/\r?\n|\r/g, multiline ? '\n' : ' '); - if (text) { - inputValue(text, false); - } + ipcRenderer + .invoke('clipboard-readText') + .then((clipboardValue) => { + // replace new lines + const text = clipboardValue.replace( + /\r?\n|\r/g, + multiline ? '\n' : ' ' + ); + if (text) { + inputValue(text, false); + } + }) + .catch(log.error); }} > {t('inputs.text.paste', 'Paste')} diff --git a/src/renderer/components/node/special/NoteNode.tsx b/src/renderer/components/node/special/NoteNode.tsx index 3594d2e77..73cceaced 100644 --- a/src/renderer/components/node/special/NoteNode.tsx +++ b/src/renderer/components/node/special/NoteNode.tsx @@ -14,7 +14,6 @@ import { Tooltip, VStack, } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import { Resizable } from 're-resizable'; import { ChangeEvent, memo, useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -23,6 +22,8 @@ import { MdContentCopy, MdContentPaste } from 'react-icons/md'; import { useContextSelector } from 'use-context-selector'; import { useDebouncedCallback } from 'use-debounce'; import { InputId, NodeData, Size } from '../../../../common/common-types'; +import { log } from '../../../../common/log'; +import { ipcRenderer } from '../../../../common/safeIpc'; import { GlobalVolatileContext } from '../../../contexts/GlobalNodeState'; import { useNodeStateFromData } from '../../../helpers/nodeState'; import { useContextMenu } from '../../../hooks/useContextMenu'; @@ -128,7 +129,9 @@ const NoteNodeInner = memo(({ data, selected }: NodeProps) => { icon={} onClick={() => { if (value !== undefined) { - clipboard.writeText(value.toString()); + ipcRenderer + .invoke('clipboard-writeText', value.toString()) + .catch(log.error); } }} > @@ -137,12 +140,16 @@ const NoteNodeInner = memo(({ data, selected }: NodeProps) => { } onClick={() => { - let text = clipboard.readText(); - // replace new lines - text = text.replace(/\r?\n|\r/g, '\n'); - if (text) { - setInputValue(textInputId, text); - } + ipcRenderer + .invoke('clipboard-readText') + .then((clipboardValue) => { + // replace new lines + const text = clipboardValue.replace(/\r?\n|\r/g, '\n'); + if (text) { + setInputValue(textInputId, text); + } + }) + .catch(log.error); }} > {t('inputs.text.paste', 'Paste')} diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index a8ae870ec..74641ff14 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -16,7 +16,6 @@ import { useDisclosure, useToast, } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; @@ -319,7 +318,11 @@ const AlertBoxDialog = memo( background="transparent" icon={} title="Copy to Clipboard" - onClick={() => clipboard.writeText(copyText)} + onClick={() => { + ipcRenderer + .invoke('clipboard-writeText', copyText) + .catch(log.error); + }} /> { - clipboard.writeText(command); - onPopoverToggle(); - setTimeout(() => { - onPopoverClose(); - }, 5000); + ipcRenderer + .invoke('clipboard-writeText', command) + .then(() => { + onPopoverToggle(); + setTimeout(() => { + onPopoverClose(); + }, 5000); + }) + .catch(log.error); }; const installPackage = (pkg: Package) => { From c74cec35b9d434ea0669844b267fbb76022c687a Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 14:14:31 -0400 Subject: [PATCH 09/22] Finish moving all clipboard stuff --- src/common/safeIpc.ts | 11 +++ src/main/gui/main-window.ts | 14 ++++ src/renderer/contexts/GlobalNodeState.tsx | 2 +- src/renderer/helpers/copyAndPaste.ts | 84 ++++++++++++++--------- src/renderer/helpers/nodeScreenshot.ts | 6 +- src/renderer/hooks/useInputRefactor.tsx | 7 +- 6 files changed, 84 insertions(+), 40 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index 0368b56dd..e681a1c4a 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -98,6 +98,17 @@ export interface InvokeChannels { 'app-quit': ChannelInfo; 'clipboard-writeText': ChannelInfo; 'clipboard-readText': ChannelInfo; + 'clipboard-writeBuffer': ChannelInfo< + void, + [format: string, buffer: Buffer, type?: 'selection' | 'clipboard' | undefined] + >; + 'clipboard-readBuffer': ChannelInfo; + 'clipboard-availableFormats': ChannelInfo; + 'clipboard-readHTML': ChannelInfo; + 'clipboard-readRTF': ChannelInfo; + 'clipboard-readImage': ChannelInfo; + 'clipboard-writeImage': ChannelInfo; + 'clipboard-writeImageFromURL': ChannelInfo; } export interface SendChannels { diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index bcb306238..9d5cff3c3 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -3,6 +3,7 @@ import { app, clipboard, dialog, + nativeImage, nativeTheme, powerSaveBlocker, shell, @@ -229,6 +230,19 @@ const registerEventHandlerPreSetup = ( ipcMain.handle('app-quit', () => app.quit()); ipcMain.handle('clipboard-writeText', (event, text) => clipboard.writeText(text)); ipcMain.handle('clipboard-readText', () => clipboard.readText()); + ipcMain.handle('clipboard-writeBuffer', (event, format, buffer, type) => + clipboard.writeBuffer(format, buffer, type) + ); + ipcMain.handle('clipboard-readBuffer', (event, format) => clipboard.readBuffer(format)); + ipcMain.handle('clipboard-availableFormats', () => clipboard.availableFormats()); + ipcMain.handle('clipboard-readHTML', () => clipboard.readHTML()); + ipcMain.handle('clipboard-readRTF', () => clipboard.readRTF()); + ipcMain.handle('clipboard-readImage', () => clipboard.readImage()); + ipcMain.handle('clipboard-writeImage', (event, image) => clipboard.writeImage(image)); + ipcMain.handle('clipboard-writeImageFromURL', (event, url) => { + const image = nativeImage.createFromDataURL(url); + clipboard.writeImage(image); + }); }; const registerEventHandlerPostSetup = ( diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index d04b3a2d8..87e6033a5 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -1191,7 +1191,7 @@ export const GlobalProvider = memo( createNode, screenToFlowPosition, reactFlowWrapper - ); + ).catch(log.error); }, [changeNodes, changeEdges, createNode, screenToFlowPosition, reactFlowWrapper]); const selectAllFn = useCallback(() => { changeNodes((nodes) => nodes.map((n) => ({ ...n, selected: true }))); diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index b42e0407d..83bc73855 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -1,4 +1,3 @@ -import { clipboard } from 'electron'; import os from 'os'; import path from 'path'; import { Edge, Node, Project } from 'reactflow'; @@ -30,7 +29,9 @@ export const copyToClipboard = ( edges: edges.filter((e) => copyIds.has(e.source) && copyIds.has(e.target)), }; const copyData = Buffer.from(JSON.stringify(data)); - clipboard.writeBuffer('application/chainner.chain', copyData, 'clipboard'); + ipcRenderer + .invoke('clipboard-writeBuffer', 'application/chainner.chain', copyData, 'clipboard') + .catch(log.error); }; export const cutAndCopyToClipboard = ( @@ -52,19 +53,21 @@ export const cutAndCopyToClipboard = ( ); }; -export const pasteFromClipboard = ( +export const pasteFromClipboard = async ( setNodes: SetState[]>, setEdges: SetState[]>, createNode: (proto: NodeProto, parentId?: string) => void, screenToFlowPosition: Project, reactFlowWrapper: React.RefObject ) => { - const availableFormats = clipboard.availableFormats(); + const availableFormats = await ipcRenderer.invoke('clipboard-availableFormats'); if (availableFormats.length === 0) { try { - const chain = JSON.parse( - clipboard.readBuffer('application/chainner.chain').toString() - ) as ClipboardChain; + const clipboardData = await ipcRenderer.invoke( + 'clipboard-readBuffer', + 'application/chainner.chain' + ); + const chain = JSON.parse(clipboardData.toString()) as ClipboardChain; const duplicationId = createUniqueId(); const deriveId = (oldId: string) => deriveUniqueId(duplicationId + oldId); @@ -93,50 +96,63 @@ export const pasteFromClipboard = ( log.debug('Clipboard format', format); switch (format) { case 'text/plain': - log.debug('Clipboard text', clipboard.readText()); + log.debug('Clipboard text', ipcRenderer.invoke('clipboard-readText')); break; case 'text/html': - log.debug('Clipboard html', clipboard.readHTML()); + log.debug('Clipboard html', ipcRenderer.invoke('clipboard-readHTML')); break; case 'text/rtf': - log.debug('Clipboard rtf', clipboard.readRTF()); + log.debug('Clipboard rtf', ipcRenderer.invoke('clipboard-readRTF')); break; case 'image/jpeg': case 'image/gif': case 'image/bmp': case 'image/tiff': case 'image/png': { - const imgData = clipboard.readImage().toPNG(); - const imgPath = path.join(os.tmpdir(), `chaiNNer-clipboard-${uuid4()}.png`); ipcRenderer - .invoke('fs-write-file', imgPath, imgData) - .then(() => { - log.debug('Clipboard image', imgPath); - let positionX = 0; - let positionY = 0; - if (reactFlowWrapper.current) { - const { height, width, x, y } = - reactFlowWrapper.current.getBoundingClientRect(); - positionX = (width + x) / 2; - positionY = (height + y) / 2; - } - createNode({ - position: screenToFlowPosition({ x: positionX, y: positionY }), - data: { - schemaId: 'chainner:image:load' as SchemaId, - inputData: { - [0 as InputId]: imgPath, - }, - }, - }); + .invoke('clipboard-readImage') + .then((clipboardData) => { + const imgData = clipboardData.toPNG(); + const imgPath = path.join( + os.tmpdir(), + `chaiNNer-clipboard-${uuid4()}.png` + ); + ipcRenderer + .invoke('fs-write-file', imgPath, imgData) + .then(() => { + log.debug('Clipboard image', imgPath); + let positionX = 0; + let positionY = 0; + if (reactFlowWrapper.current) { + const { height, width, x, y } = + reactFlowWrapper.current.getBoundingClientRect(); + positionX = (width + x) / 2; + positionY = (height + y) / 2; + } + createNode({ + position: screenToFlowPosition({ + x: positionX, + y: positionY, + }), + data: { + schemaId: 'chainner:image:load' as SchemaId, + inputData: { + [0 as InputId]: imgPath, + }, + }, + }); + }) + .catch((e) => { + log.error('Failed to write clipboard image', e); + }); }) .catch((e) => { - log.error('Failed to write clipboard image', e); + log.error('Failed to read clipboard image', e); }); break; } default: - log.debug('Clipboard data', clipboard.readBuffer(format)); + log.debug('Clipboard data', ipcRenderer.invoke('clipboard-readBuffer', format)); } }); } diff --git a/src/renderer/helpers/nodeScreenshot.ts b/src/renderer/helpers/nodeScreenshot.ts index 5c16eccdf..671e782af 100644 --- a/src/renderer/helpers/nodeScreenshot.ts +++ b/src/renderer/helpers/nodeScreenshot.ts @@ -1,7 +1,8 @@ -import { clipboard, nativeImage } from 'electron'; import { toPng } from 'html-to-image'; import { Node, ReactFlowInstance } from 'reactflow'; import { EdgeData, NodeData } from '../../common/common-types'; +import { log } from '../../common/log'; +import { ipcRenderer } from '../../common/safeIpc'; import { delay } from '../../common/util'; interface Rect { @@ -109,6 +110,5 @@ export const saveDataUrlAsFile = (dataUrl: PngDataUrl, fileName: string) => { }; export const writeDataUrlToClipboard = (dataUrl: PngDataUrl) => { - const image = nativeImage.createFromDataURL(dataUrl); - clipboard.writeImage(image); + ipcRenderer.invoke('clipboard-writeImageFromURL', dataUrl).catch(log.error); }; diff --git a/src/renderer/hooks/useInputRefactor.tsx b/src/renderer/hooks/useInputRefactor.tsx index 03b61cae6..6754b3c78 100644 --- a/src/renderer/hooks/useInputRefactor.tsx +++ b/src/renderer/hooks/useInputRefactor.tsx @@ -1,5 +1,4 @@ import { MenuDivider, MenuItem } from '@chakra-ui/react'; -import { clipboard } from 'electron'; import { useTranslation } from 'react-i18next'; import { CgArrowsExpandUpLeft } from 'react-icons/cg'; import { MdContentCopy } from 'react-icons/md'; @@ -17,6 +16,8 @@ import { SchemaId, } from '../../common/common-types'; import { createInputOverrideId } from '../../common/input-override-common'; +import { log } from '../../common/log'; +import { ipcRenderer } from '../../common/safeIpc'; import { createUniqueId } from '../../common/util'; import { BackendContext } from '../contexts/BackendContext'; import { FakeNodeContext } from '../contexts/FakeExampleContext'; @@ -108,7 +109,9 @@ export const useInputRefactor = ( icon={} key="copy override" onClick={() => { - clipboard.writeText(createInputOverrideId(nodeId, inputId)); + ipcRenderer + .invoke('clipboard-writeText', createInputOverrideId(nodeId, inputId)) + .catch(log.error); }} > {t('inputs.copyInputOverrideId', 'Copy Input Override Id')} From c5e1b503044a285ad05efa3d8d83516aed07480f Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 14:53:29 -0400 Subject: [PATCH 10/22] split IPC into own files --- src/common/{safeIpc.ts => safeIpcCommon.ts} | 74 +------------------ src/common/safeIpcMain.ts | 35 +++++++++ src/common/safeIpcRenderer.ts | 33 +++++++++ src/main/gui/main-window.ts | 3 +- src/main/gui/menu.ts | 2 +- src/main/gui/splash.ts | 2 +- src/renderer/app.tsx | 2 +- src/renderer/components/Header/AppInfo.tsx | 2 +- src/renderer/components/Header/KoFiButton.tsx | 2 +- src/renderer/components/SettingsModal.tsx | 2 +- .../components/groups/NcnnFileInputsGroup.tsx | 2 +- .../components/inputs/DirectoryInput.tsx | 2 +- src/renderer/components/inputs/FileInput.tsx | 2 +- .../components/inputs/NumberInput.tsx | 2 +- .../components/inputs/SliderInput.tsx | 2 +- src/renderer/components/inputs/TextInput.tsx | 2 +- .../components/node/special/NoteNode.tsx | 2 +- .../components/settings/components.tsx | 2 +- src/renderer/contexts/AlertBoxContext.tsx | 2 +- src/renderer/contexts/BackendContext.tsx | 2 +- src/renderer/contexts/DependencyContext.tsx | 2 +- src/renderer/contexts/ExecutionContext.tsx | 2 +- src/renderer/contexts/GlobalNodeState.tsx | 2 +- src/renderer/contexts/HotKeyContext.tsx | 2 +- src/renderer/contexts/SettingsContext.tsx | 2 +- src/renderer/helpers/copyAndPaste.ts | 2 +- src/renderer/helpers/dataTransfer.ts | 2 +- src/renderer/helpers/nodeScreenshot.ts | 2 +- src/renderer/hooks/useInputRefactor.tsx | 2 +- src/renderer/hooks/useIpcRendererListener.ts | 3 +- src/renderer/hooks/useOpenRecent.ts | 2 +- src/renderer/index.tsx | 2 +- src/renderer/splash.tsx | 2 +- 33 files changed, 101 insertions(+), 103 deletions(-) rename src/common/{safeIpc.ts => safeIpcCommon.ts} (71%) create mode 100644 src/common/safeIpcMain.ts create mode 100644 src/common/safeIpcRenderer.ts diff --git a/src/common/safeIpc.ts b/src/common/safeIpcCommon.ts similarity index 71% rename from src/common/safeIpc.ts rename to src/common/safeIpcCommon.ts index e681a1c4a..a57fa63ea 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpcCommon.ts @@ -1,13 +1,4 @@ -import { - BrowserWindow, - IpcMainEvent, - IpcMainInvokeEvent, - IpcRendererEvent, - MessagePortMain, - WebContents, - ipcMain as unsafeIpcMain, - ipcRenderer as unsafeIpcRenderer, -} from 'electron'; +import { type BrowserWindow, type MessagePortMain, type WebContents } from 'electron'; import { MakeDirectoryOptions } from 'fs'; import { Mode, ObjectEncodingOptions, OpenMode, PathLike } from 'original-fs'; import { FileOpenResult, FileSaveResult, PythonInfo, Version } from './common-types'; @@ -154,66 +145,6 @@ export type ChannelArgs = (Invo export type ChannelReturn = (InvokeChannels & SendChannels)[C]['returnType']; -interface SafeIpcMain extends Electron.IpcMain { - handle( - channel: C, - listener: ( - event: IpcMainInvokeEvent, - ...args: ChannelArgs - ) => Promise> | ChannelReturn - ): void; - handleOnce( - channel: C, - listener: ( - event: IpcMainInvokeEvent, - ...args: ChannelArgs - ) => Promise> | ChannelReturn - ): void; - on( - channel: C, - listener: (event: IpcMainEvent, ...args: ChannelArgs) => void - ): this; - once( - channel: C, - listener: (event: IpcMainEvent, ...args: ChannelArgs) => void - ): this; - removeAllListeners(channel?: keyof SendChannels): this; - removeHandler(channel: keyof InvokeChannels): void; - removeListener( - channel: C, - listener: (event: IpcMainEvent | IpcMainInvokeEvent, ...args: ChannelArgs) => void - ): this; -} - -interface SafeIpcRenderer extends Electron.IpcRenderer { - invoke( - channel: C, - ...args: ChannelArgs - ): Promise>; - on( - channel: C, - listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void - ): this; - once( - channel: C, - listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void - ): this; - postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePort[]): void; - removeAllListeners(channel: keyof SendChannels): this; - removeListener( - channel: C, - listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void - ): this; - send(channel: C, ...args: ChannelArgs): void; - sendSync(channel: C, ...args: ChannelArgs): void; - sendTo( - webContentsId: number, - channel: C, - ...args: ChannelArgs - ): void; - sendToHost(channel: C, ...args: ChannelArgs): void; -} - interface WebContentsWithSafeIcp extends WebContents { invoke( channel: C, @@ -232,6 +163,3 @@ interface WebContentsWithSafeIcp extends WebContents { export interface BrowserWindowWithSafeIpc extends BrowserWindow { webContents: WebContentsWithSafeIcp; } - -export const ipcMain = unsafeIpcMain as SafeIpcMain; -export const ipcRenderer = unsafeIpcRenderer as SafeIpcRenderer; diff --git a/src/common/safeIpcMain.ts b/src/common/safeIpcMain.ts new file mode 100644 index 000000000..a997d75e6 --- /dev/null +++ b/src/common/safeIpcMain.ts @@ -0,0 +1,35 @@ +import { IpcMainEvent, IpcMainInvokeEvent, ipcMain as unsafeIpcMain } from 'electron'; +import { ChannelArgs, ChannelReturn, InvokeChannels, SendChannels } from './safeIpcCommon'; + +interface SafeIpcMain extends Electron.IpcMain { + handle( + channel: C, + listener: ( + event: IpcMainInvokeEvent, + ...args: ChannelArgs + ) => Promise> | ChannelReturn + ): void; + handleOnce( + channel: C, + listener: ( + event: IpcMainInvokeEvent, + ...args: ChannelArgs + ) => Promise> | ChannelReturn + ): void; + on( + channel: C, + listener: (event: IpcMainEvent, ...args: ChannelArgs) => void + ): this; + once( + channel: C, + listener: (event: IpcMainEvent, ...args: ChannelArgs) => void + ): this; + removeAllListeners(channel?: keyof SendChannels): this; + removeHandler(channel: keyof InvokeChannels): void; + removeListener( + channel: C, + listener: (event: IpcMainEvent | IpcMainInvokeEvent, ...args: ChannelArgs) => void + ): this; +} + +export const ipcMain = unsafeIpcMain as SafeIpcMain; diff --git a/src/common/safeIpcRenderer.ts b/src/common/safeIpcRenderer.ts new file mode 100644 index 000000000..0f55c6520 --- /dev/null +++ b/src/common/safeIpcRenderer.ts @@ -0,0 +1,33 @@ +import { IpcRendererEvent, ipcRenderer as unsafeIpcRenderer } from 'electron'; +import { ChannelArgs, ChannelReturn, InvokeChannels, SendChannels } from './safeIpcCommon'; + +interface SafeIpcRenderer extends Electron.IpcRenderer { + invoke( + channel: C, + ...args: ChannelArgs + ): Promise>; + on( + channel: C, + listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void + ): this; + once( + channel: C, + listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void + ): this; + postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePort[]): void; + removeAllListeners(channel: keyof SendChannels): this; + removeListener( + channel: C, + listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void + ): this; + send(channel: C, ...args: ChannelArgs): void; + sendSync(channel: C, ...args: ChannelArgs): void; + sendTo( + webContentsId: number, + channel: C, + ...args: ChannelArgs + ): void; + sendToHost(channel: C, ...args: ChannelArgs): void; +} + +export const ipcRenderer = unsafeIpcRenderer as SafeIpcRenderer; diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 9d5cff3c3..2bb616791 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -15,7 +15,8 @@ import { BackendEventMap } from '../../common/Backend'; import { Version } from '../../common/common-types'; import { isMac } from '../../common/env'; import { log } from '../../common/log'; -import { BrowserWindowWithSafeIpc, ipcMain } from '../../common/safeIpc'; +import { BrowserWindowWithSafeIpc } from '../../common/safeIpcCommon'; +import { ipcMain } from '../../common/safeIpcMain'; import { SaveFile, openSaveFile } from '../../common/SaveFile'; import { ChainnerSettings } from '../../common/settings/settings'; import { CriticalError } from '../../common/ui/error'; diff --git a/src/main/gui/menu.ts b/src/main/gui/menu.ts index 931b18cb0..e6072f76e 100644 --- a/src/main/gui/menu.ts +++ b/src/main/gui/menu.ts @@ -4,7 +4,7 @@ import os from 'os'; import path from 'path'; import { isMac } from '../../common/env'; import { links } from '../../common/links'; -import { BrowserWindowWithSafeIpc } from '../../common/safeIpc'; +import { BrowserWindowWithSafeIpc } from '../../common/safeIpcCommon'; import { openSaveFile } from '../../common/SaveFile'; import { getLogsFolder } from '../platform'; import { getCpuInfo, getGpuInfo } from '../systemInfo'; diff --git a/src/main/gui/splash.ts b/src/main/gui/splash.ts index 26b36bd6c..764755528 100644 --- a/src/main/gui/splash.ts +++ b/src/main/gui/splash.ts @@ -1,6 +1,6 @@ import { BrowserWindow, MessageBoxOptions, app, dialog, shell } from 'electron'; import { log } from '../../common/log'; -import { BrowserWindowWithSafeIpc } from '../../common/safeIpc'; +import { BrowserWindowWithSafeIpc } from '../../common/safeIpcCommon'; import { Progress, ProgressMonitor } from '../../common/ui/progress'; import { assertNever } from '../../common/util'; diff --git a/src/renderer/app.tsx b/src/renderer/app.tsx index 4d484c5ef..756521742 100644 --- a/src/renderer/app.tsx +++ b/src/renderer/app.tsx @@ -3,7 +3,7 @@ import TimeAgo from 'javascript-time-ago'; import en from 'javascript-time-ago/locale/en.json'; import { memo, useState } from 'react'; import { PythonInfo } from '../common/common-types'; -import { ipcRenderer } from '../common/safeIpc'; +import { ipcRenderer } from '../common/safeIpcRenderer'; import { ChainnerSettings } from '../common/settings/settings'; import { AlertBoxProvider } from './contexts/AlertBoxContext'; import { BackendProvider } from './contexts/BackendContext'; diff --git a/src/renderer/components/Header/AppInfo.tsx b/src/renderer/components/Header/AppInfo.tsx index 3f0f01e53..dba2b16a3 100644 --- a/src/renderer/components/Header/AppInfo.tsx +++ b/src/renderer/components/Header/AppInfo.tsx @@ -26,7 +26,7 @@ import { import { memo, useEffect, useRef, useState } from 'react'; import semver from 'semver'; import { GitHubRelease, getLatestVersionIfUpdateAvailable } from '../../../common/api/github'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import logo from '../../../public/icons/png/256x256.png'; import { useSettings } from '../../contexts/SettingsContext'; import { useAsyncEffect } from '../../hooks/useAsyncEffect'; diff --git a/src/renderer/components/Header/KoFiButton.tsx b/src/renderer/components/Header/KoFiButton.tsx index 86418db42..b82eeb2e6 100644 --- a/src/renderer/components/Header/KoFiButton.tsx +++ b/src/renderer/components/Header/KoFiButton.tsx @@ -3,7 +3,7 @@ import { memo } from 'react'; import { SiKofi } from 'react-icons/si'; import { links } from '../../../common/links'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; export const KoFiButton = memo(() => { return ( diff --git a/src/renderer/components/SettingsModal.tsx b/src/renderer/components/SettingsModal.tsx index 4347876cf..233a63c23 100644 --- a/src/renderer/components/SettingsModal.tsx +++ b/src/renderer/components/SettingsModal.tsx @@ -31,7 +31,7 @@ import { BsFillPencilFill, BsPaletteFill } from 'react-icons/bs'; import { FaPython, FaTools } from 'react-icons/fa'; import { useContext } from 'use-context-selector'; import { isMac } from '../../common/env'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { BackendContext } from '../contexts/BackendContext'; import { useMutSetting } from '../contexts/SettingsContext'; import { IconFactory } from './CustomIcons'; diff --git a/src/renderer/components/groups/NcnnFileInputsGroup.tsx b/src/renderer/components/groups/NcnnFileInputsGroup.tsx index 5dd985420..911d9d7c3 100644 --- a/src/renderer/components/groups/NcnnFileInputsGroup.tsx +++ b/src/renderer/components/groups/NcnnFileInputsGroup.tsx @@ -1,6 +1,6 @@ import { memo, useEffect } from 'react'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import { getInputValue } from '../../../common/util'; import { SchemaInput } from '../inputs/SchemaInput'; import { GroupProps } from './props'; diff --git a/src/renderer/components/inputs/DirectoryInput.tsx b/src/renderer/components/inputs/DirectoryInput.tsx index ec28ea360..5d820db2c 100644 --- a/src/renderer/components/inputs/DirectoryInput.tsx +++ b/src/renderer/components/inputs/DirectoryInput.tsx @@ -14,7 +14,7 @@ import { useTranslation } from 'react-i18next'; import { BsFolderPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import { getFields, isDirectory } from '../../../common/types/util'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index 649c5e6c9..4c4e601f0 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -16,7 +16,7 @@ import { BsFileEarmarkPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; import { useContext } from 'use-context-selector'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import { AlertBoxContext } from '../../contexts/AlertBoxContext'; import { getSingleFileWithExtension } from '../../helpers/dataTransfer'; import { useContextMenu } from '../../hooks/useContextMenu'; diff --git a/src/renderer/components/inputs/NumberInput.tsx b/src/renderer/components/inputs/NumberInput.tsx index 97875a2a9..c6b475737 100644 --- a/src/renderer/components/inputs/NumberInput.tsx +++ b/src/renderer/components/inputs/NumberInput.tsx @@ -4,7 +4,7 @@ import { memo, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { MdContentCopy, MdContentPaste } from 'react-icons/md'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import { areApproximatelyEqual } from '../../../common/util'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; diff --git a/src/renderer/components/inputs/SliderInput.tsx b/src/renderer/components/inputs/SliderInput.tsx index 260eab015..79658ab8e 100644 --- a/src/renderer/components/inputs/SliderInput.tsx +++ b/src/renderer/components/inputs/SliderInput.tsx @@ -6,7 +6,7 @@ import { MdContentCopy, MdContentPaste } from 'react-icons/md'; import { useContext, useContextSelector } from 'use-context-selector'; import { Input, OfKind } from '../../../common/common-types'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import { assertNever } from '../../../common/util'; import { BackendContext } from '../../contexts/BackendContext'; import { InputContext } from '../../contexts/InputContext'; diff --git a/src/renderer/components/inputs/TextInput.tsx b/src/renderer/components/inputs/TextInput.tsx index e7314c642..727155641 100644 --- a/src/renderer/components/inputs/TextInput.tsx +++ b/src/renderer/components/inputs/TextInput.tsx @@ -6,7 +6,7 @@ import { MdContentCopy, MdContentPaste } from 'react-icons/md'; import { useContextSelector } from 'use-context-selector'; import { useDebouncedCallback } from 'use-debounce'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import { GlobalVolatileContext } from '../../contexts/GlobalNodeState'; import { typeToString } from '../../helpers/naviHelpers'; import { useContextMenu } from '../../hooks/useContextMenu'; diff --git a/src/renderer/components/node/special/NoteNode.tsx b/src/renderer/components/node/special/NoteNode.tsx index 73cceaced..278df896a 100644 --- a/src/renderer/components/node/special/NoteNode.tsx +++ b/src/renderer/components/node/special/NoteNode.tsx @@ -23,7 +23,7 @@ import { useContextSelector } from 'use-context-selector'; import { useDebouncedCallback } from 'use-debounce'; import { InputId, NodeData, Size } from '../../../../common/common-types'; import { log } from '../../../../common/log'; -import { ipcRenderer } from '../../../../common/safeIpc'; +import { ipcRenderer } from '../../../../common/safeIpcRenderer'; import { GlobalVolatileContext } from '../../../contexts/GlobalNodeState'; import { useNodeStateFromData } from '../../../helpers/nodeState'; import { useContextMenu } from '../../../hooks/useContextMenu'; diff --git a/src/renderer/components/settings/components.tsx b/src/renderer/components/settings/components.tsx index 9a38627ea..ce3e743a3 100644 --- a/src/renderer/components/settings/components.tsx +++ b/src/renderer/components/settings/components.tsx @@ -14,7 +14,7 @@ import { memo, useEffect, useMemo } from 'react'; import { Setting } from '../../../common/common-types'; import { getCacheLocation } from '../../../common/env'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../common/safeIpcRenderer'; import { SettingsProps } from './props'; import { SettingContainer } from './SettingContainer'; diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index 74641ff14..847cbf6ee 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -20,7 +20,7 @@ import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { assertNever, noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; import { ContextMenuContext } from './ContextMenuContext'; diff --git a/src/renderer/contexts/BackendContext.tsx b/src/renderer/contexts/BackendContext.tsx index d841ef5e0..04616d310 100644 --- a/src/renderer/contexts/BackendContext.tsx +++ b/src/renderer/contexts/BackendContext.tsx @@ -26,7 +26,7 @@ import { import { log } from '../../common/log'; import { parseFunctionDefinitions } from '../../common/nodes/parseFunctionDefinitions'; import { sortNodes } from '../../common/nodes/sort'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { SchemaInputsMap } from '../../common/SchemaInputsMap'; import { SchemaMap } from '../../common/SchemaMap'; import { getChainnerScope } from '../../common/types/chainner-scope'; diff --git a/src/renderer/contexts/DependencyContext.tsx b/src/renderer/contexts/DependencyContext.tsx index fbf498153..0f0c992df 100644 --- a/src/renderer/contexts/DependencyContext.tsx +++ b/src/renderer/contexts/DependencyContext.tsx @@ -54,7 +54,7 @@ import { } from '../../common/common-types'; import { log } from '../../common/log'; import { getFindLinks } from '../../common/pip'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { noop } from '../../common/util'; import { versionGt } from '../../common/version'; import { Markdown } from '../components/Markdown'; diff --git a/src/renderer/contexts/ExecutionContext.tsx b/src/renderer/contexts/ExecutionContext.tsx index bfb1152fe..3cc188ae2 100644 --- a/src/renderer/contexts/ExecutionContext.tsx +++ b/src/renderer/contexts/ExecutionContext.tsx @@ -11,7 +11,7 @@ import { checkNodeValidity } from '../../common/nodes/checkNodeValidity'; import { getConnectedInputs } from '../../common/nodes/connectedInputs'; import { optimizeChain } from '../../common/nodes/optimize'; import { toBackendJson } from '../../common/nodes/toBackendJson'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { getChainnerScope } from '../../common/types/chainner-scope'; import { fromJson } from '../../common/types/json'; import { EMPTY_MAP, EMPTY_SET, assertNever, groupBy } from '../../common/util'; diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index 87e6033a5..6cde24998 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -28,7 +28,7 @@ import { log } from '../../common/log'; import { getEffectivelyDisabledNodes } from '../../common/nodes/disabled'; import { ChainLineage } from '../../common/nodes/lineage'; import { TypeState } from '../../common/nodes/TypeState'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { ParsedSaveData, SaveData } from '../../common/SaveFile'; import { diff --git a/src/renderer/contexts/HotKeyContext.tsx b/src/renderer/contexts/HotKeyContext.tsx index 8834d5a76..d216e30f0 100644 --- a/src/renderer/contexts/HotKeyContext.tsx +++ b/src/renderer/contexts/HotKeyContext.tsx @@ -1,6 +1,6 @@ import React, { memo, useCallback, useState } from 'react'; import { createContext } from 'use-context-selector'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; diff --git a/src/renderer/contexts/SettingsContext.tsx b/src/renderer/contexts/SettingsContext.tsx index 1be077bbf..0a63d34d2 100644 --- a/src/renderer/contexts/SettingsContext.tsx +++ b/src/renderer/contexts/SettingsContext.tsx @@ -2,7 +2,7 @@ import { useColorMode } from '@chakra-ui/react'; import React, { SetStateAction, memo, useCallback, useEffect, useState } from 'react'; import { createContext, useContext } from 'use-context-selector'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { ChainnerSettings, defaultSettings } from '../../common/settings/settings'; import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 83bc73855..0db8eb2e9 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -4,7 +4,7 @@ import { Edge, Node, Project } from 'reactflow'; import { v4 as uuid4 } from 'uuid'; import { EdgeData, InputId, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { createUniqueId, deriveUniqueId } from '../../common/util'; import { NodeProto, copyEdges, copyNodes, setSelected } from './reactFlowUtil'; import { SetState } from './types'; diff --git a/src/renderer/helpers/dataTransfer.ts b/src/renderer/helpers/dataTransfer.ts index 72b9931c1..6e7df8575 100644 --- a/src/renderer/helpers/dataTransfer.ts +++ b/src/renderer/helpers/dataTransfer.ts @@ -2,7 +2,7 @@ import { extname } from 'path'; import { Edge, Node, XYPosition } from 'reactflow'; import { EdgeData, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { ParsedSaveData, openSaveFile } from '../../common/SaveFile'; import { SchemaMap } from '../../common/SchemaMap'; import { createUniqueId, deriveUniqueId } from '../../common/util'; diff --git a/src/renderer/helpers/nodeScreenshot.ts b/src/renderer/helpers/nodeScreenshot.ts index 671e782af..af772e3b0 100644 --- a/src/renderer/helpers/nodeScreenshot.ts +++ b/src/renderer/helpers/nodeScreenshot.ts @@ -2,7 +2,7 @@ import { toPng } from 'html-to-image'; import { Node, ReactFlowInstance } from 'reactflow'; import { EdgeData, NodeData } from '../../common/common-types'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { delay } from '../../common/util'; interface Rect { diff --git a/src/renderer/hooks/useInputRefactor.tsx b/src/renderer/hooks/useInputRefactor.tsx index 6754b3c78..885689b9e 100644 --- a/src/renderer/hooks/useInputRefactor.tsx +++ b/src/renderer/hooks/useInputRefactor.tsx @@ -17,7 +17,7 @@ import { } from '../../common/common-types'; import { createInputOverrideId } from '../../common/input-override-common'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { createUniqueId } from '../../common/util'; import { BackendContext } from '../contexts/BackendContext'; import { FakeNodeContext } from '../contexts/FakeExampleContext'; diff --git a/src/renderer/hooks/useIpcRendererListener.ts b/src/renderer/hooks/useIpcRendererListener.ts index dcbb0c0a2..c1f259580 100644 --- a/src/renderer/hooks/useIpcRendererListener.ts +++ b/src/renderer/hooks/useIpcRendererListener.ts @@ -1,6 +1,7 @@ import { IpcRendererEvent } from 'electron'; import { useEffect } from 'react'; -import { ChannelArgs, SendChannels, ipcRenderer } from '../../common/safeIpc'; +import { ChannelArgs, SendChannels } from '../../common/safeIpcCommon'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; export const useIpcRendererListener = ( channel: C, diff --git a/src/renderer/hooks/useOpenRecent.ts b/src/renderer/hooks/useOpenRecent.ts index 0d3b0e241..d74bfa7de 100644 --- a/src/renderer/hooks/useOpenRecent.ts +++ b/src/renderer/hooks/useOpenRecent.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect } from 'react'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../common/safeIpcRenderer'; import { EMPTY_ARRAY } from '../../common/util'; import { useIpcRendererListener } from './useIpcRendererListener'; import { useStored } from './useStored'; diff --git a/src/renderer/index.tsx b/src/renderer/index.tsx index 7556a0e1f..d5028760b 100644 --- a/src/renderer/index.tsx +++ b/src/renderer/index.tsx @@ -3,7 +3,7 @@ import path from 'path'; import { createRoot } from 'react-dom/client'; import { QueryClient, QueryClientProvider } from 'react-query'; import { LEVEL_NAME, log } from '../common/log'; -import { ipcRenderer } from '../common/safeIpc'; +import { ipcRenderer } from '../common/safeIpcRenderer'; import { App } from './app'; ipcRenderer diff --git a/src/renderer/splash.tsx b/src/renderer/splash.tsx index 7eb692690..d0f2b84f9 100644 --- a/src/renderer/splash.tsx +++ b/src/renderer/splash.tsx @@ -3,7 +3,7 @@ import { memo, useEffect, useState } from 'react'; import { createRoot } from 'react-dom/client'; import './i18n'; import { useTranslation } from 'react-i18next'; -import { ipcRenderer } from '../common/safeIpc'; +import { ipcRenderer } from '../common/safeIpcRenderer'; import { ChaiNNerLogo } from './components/chaiNNerLogo'; import { theme } from './splashTheme'; From 4c7b6157f46931e70ce23267f7ce1efd60a622e5 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 20:00:18 -0400 Subject: [PATCH 11/22] this should work --- src/common/safeIpc.ts | 5 ++++- src/main/backend/process.ts | 2 +- src/main/cli/create.ts | 2 +- src/main/cli/run.ts | 2 +- src/main/gui/create.ts | 2 +- src/main/gui/main-window.ts | 5 ++++- src/main/gui/menu.ts | 3 ++- src/main/gui/splash.ts | 3 ++- src/main/main.ts | 2 +- src/main/platform.ts | 2 +- src/renderer/components/inputs/DirectoryInput.tsx | 2 +- src/renderer/components/inputs/FileInput.tsx | 2 +- src/renderer/components/inputs/NumberInput.tsx | 2 +- src/renderer/components/inputs/SliderInput.tsx | 2 +- src/renderer/components/inputs/TextInput.tsx | 2 +- src/renderer/components/node/special/NoteNode.tsx | 2 +- src/renderer/contexts/AlertBoxContext.tsx | 4 ++-- src/renderer/contexts/DependencyContext.tsx | 2 +- src/renderer/helpers/copyAndPaste.ts | 2 +- src/renderer/helpers/nodeScreenshot.ts | 2 +- src/renderer/hooks/useInputRefactor.tsx | 2 +- src/renderer/hooks/useIpcRendererListener.ts | 2 +- 22 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index eca7c641f..109da345f 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -7,7 +7,7 @@ import { WebContents, ipcMain as unsafeIpcMain, ipcRenderer as unsafeIpcRenderer, -} from 'electron'; +} from 'electron/common'; import { MakeDirectoryOptions } from 'fs'; import { Mode, ObjectEncodingOptions, OpenMode, PathLike } from 'original-fs'; import { FileOpenResult, FileSaveResult, PythonInfo, Version } from './common-types'; @@ -91,6 +91,9 @@ export interface InvokeChannels { 'fs-readdir': ChannelInfo; 'fs-unlink': ChannelInfo; 'fs-access': ChannelInfo; + + // Electron + 'app-quit': ChannelInfo; } export interface SendChannels { diff --git a/src/main/backend/process.ts b/src/main/backend/process.ts index eb38ba41c..e65a8e454 100644 --- a/src/main/backend/process.ts +++ b/src/main/backend/process.ts @@ -1,5 +1,5 @@ import { ChildProcessWithoutNullStreams, spawn } from 'child_process'; -import { app } from 'electron'; +import { app } from 'electron/main'; import { existsSync } from 'fs'; import path from 'path'; import { getBackend } from '../../common/Backend'; diff --git a/src/main/cli/create.ts b/src/main/cli/create.ts index d5bf579f8..35cc74de3 100644 --- a/src/main/cli/create.ts +++ b/src/main/cli/create.ts @@ -1,5 +1,5 @@ -import { app } from 'electron'; import electronLog from 'electron-log'; +import { app } from 'electron/main'; import { log } from '../../common/log'; import { Exit } from './exit'; diff --git a/src/main/cli/run.ts b/src/main/cli/run.ts index 136d2a987..0af48561c 100644 --- a/src/main/cli/run.ts +++ b/src/main/cli/run.ts @@ -1,4 +1,4 @@ -import { app } from 'electron'; +import { app } from 'electron/main'; import EventSource from 'eventsource'; import { Backend, BackendEventMap, getBackend } from '../../common/Backend'; import { EdgeData, NodeData, NodeSchema, SchemaId } from '../../common/common-types'; diff --git a/src/main/gui/create.ts b/src/main/gui/create.ts index c7e8a589f..9ded237c4 100644 --- a/src/main/gui/create.ts +++ b/src/main/gui/create.ts @@ -1,5 +1,5 @@ -import { app, dialog } from 'electron'; import electronLog from 'electron-log'; +import { app, dialog } from 'electron/main'; import { log } from '../../common/log'; import { lazy } from '../../common/util'; import { OpenArguments } from '../arguments'; diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 728904b49..796f6439a 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -1,4 +1,5 @@ -import { BrowserWindow, app, dialog, nativeTheme, powerSaveBlocker, shell } from 'electron'; +import { shell } from 'electron/common'; +import { BrowserWindow, app, dialog, nativeTheme, powerSaveBlocker } from 'electron/main'; import EventSource from 'eventsource'; import fs, { constants } from 'fs/promises'; import { t } from 'i18next'; @@ -214,6 +215,8 @@ const registerEventHandlerPreSetup = ( ipcMain.handle('fs-readdir', async (event, path) => fs.readdir(path)); ipcMain.handle('fs-unlink', async (event, path) => fs.unlink(path)); ipcMain.handle('fs-access', async (event, path) => fs.access(path)); + + ipcMain.handle('app-quit', () => app.quit()); }; const registerEventHandlerPostSetup = ( diff --git a/src/main/gui/menu.ts b/src/main/gui/menu.ts index 931b18cb0..684b7e682 100644 --- a/src/main/gui/menu.ts +++ b/src/main/gui/menu.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ -import { Menu, MenuItemConstructorOptions, app, dialog, shell } from 'electron'; +import { shell } from 'electron/common'; +import { Menu, MenuItemConstructorOptions, app, dialog } from 'electron/main'; import os from 'os'; import path from 'path'; import { isMac } from '../../common/env'; diff --git a/src/main/gui/splash.ts b/src/main/gui/splash.ts index 26b36bd6c..c19283190 100644 --- a/src/main/gui/splash.ts +++ b/src/main/gui/splash.ts @@ -1,4 +1,5 @@ -import { BrowserWindow, MessageBoxOptions, app, dialog, shell } from 'electron'; +import { shell } from 'electron/common'; +import { BrowserWindow, MessageBoxOptions, app, dialog } from 'electron/main'; import { log } from '../../common/log'; import { BrowserWindowWithSafeIpc } from '../../common/safeIpc'; import { Progress, ProgressMonitor } from '../../common/ui/progress'; diff --git a/src/main/main.ts b/src/main/main.ts index 11d72b765..1f57e8ea0 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,5 +1,5 @@ -import { app } from 'electron'; import electronLog from 'electron-log'; +import { app } from 'electron/main'; import { readdirSync, rmSync } from 'fs'; import os from 'os'; import path from 'path'; diff --git a/src/main/platform.ts b/src/main/platform.ts index 72ba3bd1f..5fd77327b 100644 --- a/src/main/platform.ts +++ b/src/main/platform.ts @@ -1,4 +1,4 @@ -import { app } from 'electron'; +import { app } from 'electron/main'; import { existsSync } from 'fs'; import os from 'os'; import path from 'path'; diff --git a/src/renderer/components/inputs/DirectoryInput.tsx b/src/renderer/components/inputs/DirectoryInput.tsx index f6d0f7686..0641fc775 100644 --- a/src/renderer/components/inputs/DirectoryInput.tsx +++ b/src/renderer/components/inputs/DirectoryInput.tsx @@ -9,7 +9,7 @@ import { MenuList, Tooltip, } from '@chakra-ui/react'; -import { clipboard, shell } from 'electron'; +import { clipboard, shell } from 'electron/common'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { BsFolderPlus } from 'react-icons/bs'; diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index 982ab1a50..a6eb598fb 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -9,7 +9,7 @@ import { Tooltip, VStack, } from '@chakra-ui/react'; -import { clipboard, shell } from 'electron'; +import { clipboard, shell } from 'electron/common'; import path from 'path'; import { DragEvent, memo } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/src/renderer/components/inputs/NumberInput.tsx b/src/renderer/components/inputs/NumberInput.tsx index a69641f40..aa1a43bb9 100644 --- a/src/renderer/components/inputs/NumberInput.tsx +++ b/src/renderer/components/inputs/NumberInput.tsx @@ -1,6 +1,6 @@ import { isNumericLiteral } from '@chainner/navi'; import { HStack, MenuItem, MenuList } from '@chakra-ui/react'; -import { clipboard } from 'electron'; +import { clipboard } from 'electron/common'; import { memo, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { MdContentCopy, MdContentPaste } from 'react-icons/md'; diff --git a/src/renderer/components/inputs/SliderInput.tsx b/src/renderer/components/inputs/SliderInput.tsx index cab155e9c..b2fe4d77a 100644 --- a/src/renderer/components/inputs/SliderInput.tsx +++ b/src/renderer/components/inputs/SliderInput.tsx @@ -1,6 +1,6 @@ import { isNumericLiteral } from '@chainner/navi'; import { HStack, MenuItem, MenuList, Text, VStack } from '@chakra-ui/react'; -import { clipboard } from 'electron'; +import { clipboard } from 'electron/common'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { MdContentCopy, MdContentPaste } from 'react-icons/md'; diff --git a/src/renderer/components/inputs/TextInput.tsx b/src/renderer/components/inputs/TextInput.tsx index b7d017a2e..f5e9fb291 100644 --- a/src/renderer/components/inputs/TextInput.tsx +++ b/src/renderer/components/inputs/TextInput.tsx @@ -1,5 +1,5 @@ import { Center, Input, MenuItem, MenuList, Textarea } from '@chakra-ui/react'; -import { clipboard } from 'electron'; +import { clipboard } from 'electron/common'; import { Resizable } from 're-resizable'; import { ChangeEvent, memo, useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/src/renderer/components/node/special/NoteNode.tsx b/src/renderer/components/node/special/NoteNode.tsx index 3594d2e77..b2d8016da 100644 --- a/src/renderer/components/node/special/NoteNode.tsx +++ b/src/renderer/components/node/special/NoteNode.tsx @@ -14,7 +14,7 @@ import { Tooltip, VStack, } from '@chakra-ui/react'; -import { clipboard } from 'electron'; +import { clipboard } from 'electron/common'; import { Resizable } from 're-resizable'; import { ChangeEvent, memo, useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index e62f8dd7f..c19fa6318 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -16,7 +16,7 @@ import { useDisclosure, useToast, } from '@chakra-ui/react'; -import { app, clipboard, shell } from 'electron'; +import { clipboard, shell } from 'electron/common'; import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; @@ -203,7 +203,7 @@ const getButtons = ( ref={cancelRef} onClick={() => { window.close(); - app.quit(); + ipcRenderer.invoke('app-quit').catch(log.error); }} > Exit Application diff --git a/src/renderer/contexts/DependencyContext.tsx b/src/renderer/contexts/DependencyContext.tsx index c4edf4054..47d793cb0 100644 --- a/src/renderer/contexts/DependencyContext.tsx +++ b/src/renderer/contexts/DependencyContext.tsx @@ -38,7 +38,7 @@ import { VStack, useDisclosure, } from '@chakra-ui/react'; -import { clipboard } from 'electron'; +import { clipboard } from 'electron/common'; import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { BsQuestionCircle, BsTerminalFill } from 'react-icons/bs'; import { HiOutlineRefresh } from 'react-icons/hi'; diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index b42e0407d..1f681200f 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -1,4 +1,4 @@ -import { clipboard } from 'electron'; +import { clipboard } from 'electron/common'; import os from 'os'; import path from 'path'; import { Edge, Node, Project } from 'reactflow'; diff --git a/src/renderer/helpers/nodeScreenshot.ts b/src/renderer/helpers/nodeScreenshot.ts index 5c16eccdf..ec4626d6e 100644 --- a/src/renderer/helpers/nodeScreenshot.ts +++ b/src/renderer/helpers/nodeScreenshot.ts @@ -1,4 +1,4 @@ -import { clipboard, nativeImage } from 'electron'; +import { clipboard, nativeImage } from 'electron/common'; import { toPng } from 'html-to-image'; import { Node, ReactFlowInstance } from 'reactflow'; import { EdgeData, NodeData } from '../../common/common-types'; diff --git a/src/renderer/hooks/useInputRefactor.tsx b/src/renderer/hooks/useInputRefactor.tsx index 03b61cae6..b7eeffd20 100644 --- a/src/renderer/hooks/useInputRefactor.tsx +++ b/src/renderer/hooks/useInputRefactor.tsx @@ -1,5 +1,5 @@ import { MenuDivider, MenuItem } from '@chakra-ui/react'; -import { clipboard } from 'electron'; +import { clipboard } from 'electron/common'; import { useTranslation } from 'react-i18next'; import { CgArrowsExpandUpLeft } from 'react-icons/cg'; import { MdContentCopy } from 'react-icons/md'; diff --git a/src/renderer/hooks/useIpcRendererListener.ts b/src/renderer/hooks/useIpcRendererListener.ts index dcbb0c0a2..d46216686 100644 --- a/src/renderer/hooks/useIpcRendererListener.ts +++ b/src/renderer/hooks/useIpcRendererListener.ts @@ -1,4 +1,4 @@ -import { IpcRendererEvent } from 'electron'; +import { IpcRendererEvent } from 'electron/renderer'; import { useEffect } from 'react'; import { ChannelArgs, SendChannels, ipcRenderer } from '../../common/safeIpc'; From f9233e7240cf7d3e40dce02c32a479179103af79 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 29 Mar 2024 20:15:37 -0400 Subject: [PATCH 12/22] Separate electron imports between renderer and main --- src/common/safeIpc.ts | 103 +----------------- src/main/gui/main-window.ts | 2 +- src/main/gui/menu.ts | 2 +- src/main/gui/splash.ts | 2 +- src/main/main.ts | 2 +- src/main/safeIpc.ts | 62 +++++++++++ src/renderer/app.tsx | 2 +- src/renderer/components/Header/AppInfo.tsx | 2 +- src/renderer/components/Header/KoFiButton.tsx | 2 +- src/renderer/components/SettingsModal.tsx | 2 +- .../components/groups/NcnnFileInputsGroup.tsx | 2 +- .../components/inputs/DirectoryInput.tsx | 2 +- src/renderer/components/inputs/FileInput.tsx | 2 +- .../components/settings/components.tsx | 2 +- src/renderer/contexts/AlertBoxContext.tsx | 2 +- src/renderer/contexts/BackendContext.tsx | 2 +- src/renderer/contexts/ExecutionContext.tsx | 2 +- src/renderer/contexts/GlobalNodeState.tsx | 2 +- src/renderer/contexts/HotKeyContext.tsx | 2 +- src/renderer/contexts/SettingsContext.tsx | 2 +- src/renderer/helpers/copyAndPaste.ts | 2 +- src/renderer/helpers/dataTransfer.ts | 2 +- src/renderer/hooks/useIpcRendererListener.ts | 3 +- src/renderer/hooks/useOpenRecent.ts | 2 +- src/renderer/index.tsx | 2 +- src/renderer/safeIpc.ts | 33 ++++++ src/renderer/splash.tsx | 2 +- 27 files changed, 124 insertions(+), 123 deletions(-) create mode 100644 src/main/safeIpc.ts create mode 100644 src/renderer/safeIpc.ts diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index 109da345f..2e8ebc191 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -1,13 +1,4 @@ -import { - BrowserWindow, - IpcMainEvent, - IpcMainInvokeEvent, - IpcRendererEvent, - MessagePortMain, - WebContents, - ipcMain as unsafeIpcMain, - ipcRenderer as unsafeIpcRenderer, -} from 'electron/common'; +import { type FileFilter, type OpenDialogReturnValue } from 'electron/common'; import { MakeDirectoryOptions } from 'fs'; import { Mode, ObjectEncodingOptions, OpenMode, PathLike } from 'original-fs'; import { FileOpenResult, FileSaveResult, PythonInfo, Version } from './common-types'; @@ -26,14 +17,10 @@ export interface InvokeChannels { 'get-backend-url': ChannelInfo; 'refresh-nodes': ChannelInfo; 'get-app-version': ChannelInfo; - 'dir-select': ChannelInfo; + 'dir-select': ChannelInfo; 'file-select': ChannelInfo< - Electron.OpenDialogReturnValue, - [ - filters: Electron.FileFilter[], - allowMultiple: boolean | undefined, - dirPath: string | undefined - ] + OpenDialogReturnValue, + [filters: FileFilter[], allowMultiple: boolean | undefined, dirPath: string | undefined] >; 'file-save-json': ChannelInfo; @@ -138,85 +125,3 @@ export type ChannelArgs = (Invo SendChannels)[C]['args']; export type ChannelReturn = (InvokeChannels & SendChannels)[C]['returnType']; - -interface SafeIpcMain extends Electron.IpcMain { - handle( - channel: C, - listener: ( - event: IpcMainInvokeEvent, - ...args: ChannelArgs - ) => Promise> | ChannelReturn - ): void; - handleOnce( - channel: C, - listener: ( - event: IpcMainInvokeEvent, - ...args: ChannelArgs - ) => Promise> | ChannelReturn - ): void; - on( - channel: C, - listener: (event: IpcMainEvent, ...args: ChannelArgs) => void - ): this; - once( - channel: C, - listener: (event: IpcMainEvent, ...args: ChannelArgs) => void - ): this; - removeAllListeners(channel?: keyof SendChannels): this; - removeHandler(channel: keyof InvokeChannels): void; - removeListener( - channel: C, - listener: (event: IpcMainEvent | IpcMainInvokeEvent, ...args: ChannelArgs) => void - ): this; -} - -interface SafeIpcRenderer extends Electron.IpcRenderer { - invoke( - channel: C, - ...args: ChannelArgs - ): Promise>; - on( - channel: C, - listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void - ): this; - once( - channel: C, - listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void - ): this; - postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePort[]): void; - removeAllListeners(channel: keyof SendChannels): this; - removeListener( - channel: C, - listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void - ): this; - send(channel: C, ...args: ChannelArgs): void; - sendSync(channel: C, ...args: ChannelArgs): void; - sendTo( - webContentsId: number, - channel: C, - ...args: ChannelArgs - ): void; - sendToHost(channel: C, ...args: ChannelArgs): void; -} - -interface WebContentsWithSafeIcp extends WebContents { - invoke( - channel: C, - ...args: ChannelArgs - ): Promise>; - postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePortMain[]): void; - send(channel: C, ...args: ChannelArgs): void; - sendSync(channel: C, ...args: ChannelArgs): ChannelReturn; - sendTo( - webContentsId: number, - channel: C, - ...args: ChannelArgs - ): void; - sendToHost(channel: C, ...args: ChannelArgs): void; -} -export interface BrowserWindowWithSafeIpc extends BrowserWindow { - webContents: WebContentsWithSafeIcp; -} - -export const ipcMain = unsafeIpcMain as SafeIpcMain; -export const ipcRenderer = unsafeIpcRenderer as SafeIpcRenderer; diff --git a/src/main/gui/main-window.ts b/src/main/gui/main-window.ts index 796f6439a..798c982a5 100644 --- a/src/main/gui/main-window.ts +++ b/src/main/gui/main-window.ts @@ -7,7 +7,6 @@ import { BackendEventMap } from '../../common/Backend'; import { Version } from '../../common/common-types'; import { isMac } from '../../common/env'; import { log } from '../../common/log'; -import { BrowserWindowWithSafeIpc, ipcMain } from '../../common/safeIpc'; import { SaveFile, openSaveFile } from '../../common/SaveFile'; import { ChainnerSettings } from '../../common/settings/settings'; import { CriticalError } from '../../common/ui/error'; @@ -16,6 +15,7 @@ import { OpenArguments, parseArgs } from '../arguments'; import { BackendProcess } from '../backend/process'; import { setupBackend } from '../backend/setup'; import { getRootDirSync } from '../platform'; +import { BrowserWindowWithSafeIpc, ipcMain } from '../safeIpc'; import { writeSettings } from '../setting-storage'; import { MenuData, setMainMenu } from './menu'; import { addSplashScreen } from './splash'; diff --git a/src/main/gui/menu.ts b/src/main/gui/menu.ts index 684b7e682..3fad9b9d7 100644 --- a/src/main/gui/menu.ts +++ b/src/main/gui/menu.ts @@ -5,9 +5,9 @@ import os from 'os'; import path from 'path'; import { isMac } from '../../common/env'; import { links } from '../../common/links'; -import { BrowserWindowWithSafeIpc } from '../../common/safeIpc'; import { openSaveFile } from '../../common/SaveFile'; import { getLogsFolder } from '../platform'; +import { BrowserWindowWithSafeIpc } from '../safeIpc'; import { getCpuInfo, getGpuInfo } from '../systemInfo'; export interface MenuData { diff --git a/src/main/gui/splash.ts b/src/main/gui/splash.ts index c19283190..8a43c4908 100644 --- a/src/main/gui/splash.ts +++ b/src/main/gui/splash.ts @@ -1,9 +1,9 @@ import { shell } from 'electron/common'; import { BrowserWindow, MessageBoxOptions, app, dialog } from 'electron/main'; import { log } from '../../common/log'; -import { BrowserWindowWithSafeIpc } from '../../common/safeIpc'; import { Progress, ProgressMonitor } from '../../common/ui/progress'; import { assertNever } from '../../common/util'; +import { BrowserWindowWithSafeIpc } from '../safeIpc'; export type SplashStage = 'init' | 'done'; diff --git a/src/main/main.ts b/src/main/main.ts index 1f57e8ea0..11d72b765 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,5 +1,5 @@ +import { app } from 'electron'; import electronLog from 'electron-log'; -import { app } from 'electron/main'; import { readdirSync, rmSync } from 'fs'; import os from 'os'; import path from 'path'; diff --git a/src/main/safeIpc.ts b/src/main/safeIpc.ts new file mode 100644 index 000000000..e3cfadea3 --- /dev/null +++ b/src/main/safeIpc.ts @@ -0,0 +1,62 @@ +import { + BrowserWindow, + IpcMainEvent, + IpcMainInvokeEvent, + MessagePortMain, + WebContents, + ipcMain as unsafeIpcMain, +} from 'electron/main'; +import { ChannelArgs, ChannelReturn, InvokeChannels, SendChannels } from '../common/safeIpc'; + +interface SafeIpcMain extends Electron.IpcMain { + handle( + channel: C, + listener: ( + event: IpcMainInvokeEvent, + ...args: ChannelArgs + ) => Promise> | ChannelReturn + ): void; + handleOnce( + channel: C, + listener: ( + event: IpcMainInvokeEvent, + ...args: ChannelArgs + ) => Promise> | ChannelReturn + ): void; + on( + channel: C, + listener: (event: IpcMainEvent, ...args: ChannelArgs) => void + ): this; + once( + channel: C, + listener: (event: IpcMainEvent, ...args: ChannelArgs) => void + ): this; + removeAllListeners(channel?: keyof SendChannels): this; + removeHandler(channel: keyof InvokeChannels): void; + removeListener( + channel: C, + listener: (event: IpcMainEvent | IpcMainInvokeEvent, ...args: ChannelArgs) => void + ): this; +} + +interface WebContentsWithSafeIcp extends WebContents { + invoke( + channel: C, + ...args: ChannelArgs + ): Promise>; + postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePortMain[]): void; + send(channel: C, ...args: ChannelArgs): void; + sendSync(channel: C, ...args: ChannelArgs): ChannelReturn; + sendTo( + webContentsId: number, + channel: C, + ...args: ChannelArgs + ): void; + sendToHost(channel: C, ...args: ChannelArgs): void; +} + +export interface BrowserWindowWithSafeIpc extends BrowserWindow { + webContents: WebContentsWithSafeIcp; +} + +export const ipcMain = unsafeIpcMain as SafeIpcMain; diff --git a/src/renderer/app.tsx b/src/renderer/app.tsx index 4d484c5ef..388128110 100644 --- a/src/renderer/app.tsx +++ b/src/renderer/app.tsx @@ -3,7 +3,6 @@ import TimeAgo from 'javascript-time-ago'; import en from 'javascript-time-ago/locale/en.json'; import { memo, useState } from 'react'; import { PythonInfo } from '../common/common-types'; -import { ipcRenderer } from '../common/safeIpc'; import { ChainnerSettings } from '../common/settings/settings'; import { AlertBoxProvider } from './contexts/AlertBoxContext'; import { BackendProvider } from './contexts/BackendContext'; @@ -12,6 +11,7 @@ import { HotkeysProvider } from './contexts/HotKeyContext'; import { SettingsProvider } from './contexts/SettingsContext'; import { useAsyncEffect } from './hooks/useAsyncEffect'; import { Main } from './main'; +import { ipcRenderer } from './safeIpc'; import { darktheme } from './theme'; import './i18n'; diff --git a/src/renderer/components/Header/AppInfo.tsx b/src/renderer/components/Header/AppInfo.tsx index 3f0f01e53..f202e19a8 100644 --- a/src/renderer/components/Header/AppInfo.tsx +++ b/src/renderer/components/Header/AppInfo.tsx @@ -26,7 +26,7 @@ import { import { memo, useEffect, useRef, useState } from 'react'; import semver from 'semver'; import { GitHubRelease, getLatestVersionIfUpdateAvailable } from '../../../common/api/github'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../renderer/safeIpc'; import logo from '../../../public/icons/png/256x256.png'; import { useSettings } from '../../contexts/SettingsContext'; import { useAsyncEffect } from '../../hooks/useAsyncEffect'; diff --git a/src/renderer/components/Header/KoFiButton.tsx b/src/renderer/components/Header/KoFiButton.tsx index 86418db42..f4a5cadc6 100644 --- a/src/renderer/components/Header/KoFiButton.tsx +++ b/src/renderer/components/Header/KoFiButton.tsx @@ -3,7 +3,7 @@ import { memo } from 'react'; import { SiKofi } from 'react-icons/si'; import { links } from '../../../common/links'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../renderer/safeIpc'; export const KoFiButton = memo(() => { return ( diff --git a/src/renderer/components/SettingsModal.tsx b/src/renderer/components/SettingsModal.tsx index 4347876cf..63ed453d1 100644 --- a/src/renderer/components/SettingsModal.tsx +++ b/src/renderer/components/SettingsModal.tsx @@ -31,7 +31,7 @@ import { BsFillPencilFill, BsPaletteFill } from 'react-icons/bs'; import { FaPython, FaTools } from 'react-icons/fa'; import { useContext } from 'use-context-selector'; import { isMac } from '../../common/env'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { BackendContext } from '../contexts/BackendContext'; import { useMutSetting } from '../contexts/SettingsContext'; import { IconFactory } from './CustomIcons'; diff --git a/src/renderer/components/groups/NcnnFileInputsGroup.tsx b/src/renderer/components/groups/NcnnFileInputsGroup.tsx index 5dd985420..5106b0c42 100644 --- a/src/renderer/components/groups/NcnnFileInputsGroup.tsx +++ b/src/renderer/components/groups/NcnnFileInputsGroup.tsx @@ -1,6 +1,6 @@ import { memo, useEffect } from 'react'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../renderer/safeIpc'; import { getInputValue } from '../../../common/util'; import { SchemaInput } from '../inputs/SchemaInput'; import { GroupProps } from './props'; diff --git a/src/renderer/components/inputs/DirectoryInput.tsx b/src/renderer/components/inputs/DirectoryInput.tsx index 0641fc775..7b740e7fd 100644 --- a/src/renderer/components/inputs/DirectoryInput.tsx +++ b/src/renderer/components/inputs/DirectoryInput.tsx @@ -14,7 +14,7 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { BsFolderPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../renderer/safeIpc'; import { getFields, isDirectory } from '../../../common/types/util'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index a6eb598fb..c26af7603 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -16,7 +16,7 @@ import { useTranslation } from 'react-i18next'; import { BsFileEarmarkPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; import { useContext } from 'use-context-selector'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../renderer/safeIpc'; import { AlertBoxContext } from '../../contexts/AlertBoxContext'; import { getSingleFileWithExtension } from '../../helpers/dataTransfer'; import { useContextMenu } from '../../hooks/useContextMenu'; diff --git a/src/renderer/components/settings/components.tsx b/src/renderer/components/settings/components.tsx index 9a38627ea..b66cf41ee 100644 --- a/src/renderer/components/settings/components.tsx +++ b/src/renderer/components/settings/components.tsx @@ -14,7 +14,7 @@ import { memo, useEffect, useMemo } from 'react'; import { Setting } from '../../../common/common-types'; import { getCacheLocation } from '../../../common/env'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../common/safeIpc'; +import { ipcRenderer } from '../../../renderer/safeIpc'; import { SettingsProps } from './props'; import { SettingContainer } from './SettingContainer'; diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index c19fa6318..1b3e13ff0 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -21,7 +21,7 @@ import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { assertNever, noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; import { ContextMenuContext } from './ContextMenuContext'; diff --git a/src/renderer/contexts/BackendContext.tsx b/src/renderer/contexts/BackendContext.tsx index d841ef5e0..3cb5fe384 100644 --- a/src/renderer/contexts/BackendContext.tsx +++ b/src/renderer/contexts/BackendContext.tsx @@ -26,7 +26,7 @@ import { import { log } from '../../common/log'; import { parseFunctionDefinitions } from '../../common/nodes/parseFunctionDefinitions'; import { sortNodes } from '../../common/nodes/sort'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { SchemaInputsMap } from '../../common/SchemaInputsMap'; import { SchemaMap } from '../../common/SchemaMap'; import { getChainnerScope } from '../../common/types/chainner-scope'; diff --git a/src/renderer/contexts/ExecutionContext.tsx b/src/renderer/contexts/ExecutionContext.tsx index bfb1152fe..022ab4d93 100644 --- a/src/renderer/contexts/ExecutionContext.tsx +++ b/src/renderer/contexts/ExecutionContext.tsx @@ -11,7 +11,7 @@ import { checkNodeValidity } from '../../common/nodes/checkNodeValidity'; import { getConnectedInputs } from '../../common/nodes/connectedInputs'; import { optimizeChain } from '../../common/nodes/optimize'; import { toBackendJson } from '../../common/nodes/toBackendJson'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { getChainnerScope } from '../../common/types/chainner-scope'; import { fromJson } from '../../common/types/json'; import { EMPTY_MAP, EMPTY_SET, assertNever, groupBy } from '../../common/util'; diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index d04b3a2d8..583749c57 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -28,7 +28,7 @@ import { log } from '../../common/log'; import { getEffectivelyDisabledNodes } from '../../common/nodes/disabled'; import { ChainLineage } from '../../common/nodes/lineage'; import { TypeState } from '../../common/nodes/TypeState'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { ParsedSaveData, SaveData } from '../../common/SaveFile'; import { diff --git a/src/renderer/contexts/HotKeyContext.tsx b/src/renderer/contexts/HotKeyContext.tsx index 8834d5a76..cd87f9335 100644 --- a/src/renderer/contexts/HotKeyContext.tsx +++ b/src/renderer/contexts/HotKeyContext.tsx @@ -1,6 +1,6 @@ import React, { memo, useCallback, useState } from 'react'; import { createContext } from 'use-context-selector'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; diff --git a/src/renderer/contexts/SettingsContext.tsx b/src/renderer/contexts/SettingsContext.tsx index 1be077bbf..6f51039a5 100644 --- a/src/renderer/contexts/SettingsContext.tsx +++ b/src/renderer/contexts/SettingsContext.tsx @@ -2,7 +2,7 @@ import { useColorMode } from '@chakra-ui/react'; import React, { SetStateAction, memo, useCallback, useEffect, useState } from 'react'; import { createContext, useContext } from 'use-context-selector'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { ChainnerSettings, defaultSettings } from '../../common/settings/settings'; import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 1f681200f..7f936fcfd 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -5,7 +5,7 @@ import { Edge, Node, Project } from 'reactflow'; import { v4 as uuid4 } from 'uuid'; import { EdgeData, InputId, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { createUniqueId, deriveUniqueId } from '../../common/util'; import { NodeProto, copyEdges, copyNodes, setSelected } from './reactFlowUtil'; import { SetState } from './types'; diff --git a/src/renderer/helpers/dataTransfer.ts b/src/renderer/helpers/dataTransfer.ts index 72b9931c1..c56a818a9 100644 --- a/src/renderer/helpers/dataTransfer.ts +++ b/src/renderer/helpers/dataTransfer.ts @@ -2,7 +2,7 @@ import { extname } from 'path'; import { Edge, Node, XYPosition } from 'reactflow'; import { EdgeData, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { ParsedSaveData, openSaveFile } from '../../common/SaveFile'; import { SchemaMap } from '../../common/SchemaMap'; import { createUniqueId, deriveUniqueId } from '../../common/util'; diff --git a/src/renderer/hooks/useIpcRendererListener.ts b/src/renderer/hooks/useIpcRendererListener.ts index d46216686..0359fad60 100644 --- a/src/renderer/hooks/useIpcRendererListener.ts +++ b/src/renderer/hooks/useIpcRendererListener.ts @@ -1,6 +1,7 @@ import { IpcRendererEvent } from 'electron/renderer'; import { useEffect } from 'react'; -import { ChannelArgs, SendChannels, ipcRenderer } from '../../common/safeIpc'; +import { ChannelArgs, SendChannels } from '../../common/safeIpc'; +import { ipcRenderer } from '../safeIpc'; export const useIpcRendererListener = ( channel: C, diff --git a/src/renderer/hooks/useOpenRecent.ts b/src/renderer/hooks/useOpenRecent.ts index 0d3b0e241..3c0bea241 100644 --- a/src/renderer/hooks/useOpenRecent.ts +++ b/src/renderer/hooks/useOpenRecent.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect } from 'react'; -import { ipcRenderer } from '../../common/safeIpc'; +import { ipcRenderer } from '../../renderer/safeIpc'; import { EMPTY_ARRAY } from '../../common/util'; import { useIpcRendererListener } from './useIpcRendererListener'; import { useStored } from './useStored'; diff --git a/src/renderer/index.tsx b/src/renderer/index.tsx index 7556a0e1f..3a86ae916 100644 --- a/src/renderer/index.tsx +++ b/src/renderer/index.tsx @@ -3,8 +3,8 @@ import path from 'path'; import { createRoot } from 'react-dom/client'; import { QueryClient, QueryClientProvider } from 'react-query'; import { LEVEL_NAME, log } from '../common/log'; -import { ipcRenderer } from '../common/safeIpc'; import { App } from './app'; +import { ipcRenderer } from './safeIpc'; ipcRenderer .invoke('get-appdata') diff --git a/src/renderer/safeIpc.ts b/src/renderer/safeIpc.ts new file mode 100644 index 000000000..e14b34b64 --- /dev/null +++ b/src/renderer/safeIpc.ts @@ -0,0 +1,33 @@ +import { IpcRendererEvent, ipcRenderer as unsafeIpcRenderer } from 'electron/renderer'; +import { ChannelArgs, ChannelReturn, InvokeChannels, SendChannels } from '../common/safeIpc'; + +interface SafeIpcRenderer extends Electron.IpcRenderer { + invoke( + channel: C, + ...args: ChannelArgs + ): Promise>; + on( + channel: C, + listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void + ): this; + once( + channel: C, + listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void + ): this; + postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePort[]): void; + removeAllListeners(channel: keyof SendChannels): this; + removeListener( + channel: C, + listener: (event: IpcRendererEvent, ...args: ChannelArgs) => void + ): this; + send(channel: C, ...args: ChannelArgs): void; + sendSync(channel: C, ...args: ChannelArgs): void; + sendTo( + webContentsId: number, + channel: C, + ...args: ChannelArgs + ): void; + sendToHost(channel: C, ...args: ChannelArgs): void; +} + +export const ipcRenderer = unsafeIpcRenderer as SafeIpcRenderer; diff --git a/src/renderer/splash.tsx b/src/renderer/splash.tsx index 7eb692690..3841a9bf6 100644 --- a/src/renderer/splash.tsx +++ b/src/renderer/splash.tsx @@ -3,8 +3,8 @@ import { memo, useEffect, useState } from 'react'; import { createRoot } from 'react-dom/client'; import './i18n'; import { useTranslation } from 'react-i18next'; -import { ipcRenderer } from '../common/safeIpc'; import { ChaiNNerLogo } from './components/chaiNNerLogo'; +import { ipcRenderer } from './safeIpc'; import { theme } from './splashTheme'; const Splash = memo(() => { From 9eb71c57cabf85278df045a62f4b732bacc2af68 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 12:36:31 -0400 Subject: [PATCH 13/22] lint --- src/renderer/components/Header/AppInfo.tsx | 2 +- src/renderer/components/Header/KoFiButton.tsx | 2 +- src/renderer/components/SettingsModal.tsx | 2 +- src/renderer/components/groups/NcnnFileInputsGroup.tsx | 2 +- src/renderer/components/inputs/DirectoryInput.tsx | 2 +- src/renderer/components/inputs/FileInput.tsx | 2 +- src/renderer/components/settings/components.tsx | 2 +- src/renderer/contexts/AlertBoxContext.tsx | 2 +- src/renderer/contexts/BackendContext.tsx | 2 +- src/renderer/contexts/ExecutionContext.tsx | 2 +- src/renderer/contexts/GlobalNodeState.tsx | 2 +- src/renderer/contexts/HotKeyContext.tsx | 2 +- src/renderer/contexts/SettingsContext.tsx | 2 +- src/renderer/helpers/copyAndPaste.ts | 2 +- src/renderer/helpers/dataTransfer.ts | 2 +- src/renderer/hooks/useOpenRecent.ts | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/renderer/components/Header/AppInfo.tsx b/src/renderer/components/Header/AppInfo.tsx index f202e19a8..8eb2665e6 100644 --- a/src/renderer/components/Header/AppInfo.tsx +++ b/src/renderer/components/Header/AppInfo.tsx @@ -26,11 +26,11 @@ import { import { memo, useEffect, useRef, useState } from 'react'; import semver from 'semver'; import { GitHubRelease, getLatestVersionIfUpdateAvailable } from '../../../common/api/github'; -import { ipcRenderer } from '../../../renderer/safeIpc'; import logo from '../../../public/icons/png/256x256.png'; import { useSettings } from '../../contexts/SettingsContext'; import { useAsyncEffect } from '../../hooks/useAsyncEffect'; import { useStored } from '../../hooks/useStored'; +import { ipcRenderer } from '../../safeIpc'; import { Markdown } from '../Markdown'; export const AppInfo = memo(() => { diff --git a/src/renderer/components/Header/KoFiButton.tsx b/src/renderer/components/Header/KoFiButton.tsx index f4a5cadc6..8f1af68d4 100644 --- a/src/renderer/components/Header/KoFiButton.tsx +++ b/src/renderer/components/Header/KoFiButton.tsx @@ -3,7 +3,7 @@ import { memo } from 'react'; import { SiKofi } from 'react-icons/si'; import { links } from '../../../common/links'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../renderer/safeIpc'; +import { ipcRenderer } from '../../safeIpc'; export const KoFiButton = memo(() => { return ( diff --git a/src/renderer/components/SettingsModal.tsx b/src/renderer/components/SettingsModal.tsx index 63ed453d1..89d67c937 100644 --- a/src/renderer/components/SettingsModal.tsx +++ b/src/renderer/components/SettingsModal.tsx @@ -31,9 +31,9 @@ import { BsFillPencilFill, BsPaletteFill } from 'react-icons/bs'; import { FaPython, FaTools } from 'react-icons/fa'; import { useContext } from 'use-context-selector'; import { isMac } from '../../common/env'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { BackendContext } from '../contexts/BackendContext'; import { useMutSetting } from '../contexts/SettingsContext'; +import { ipcRenderer } from '../safeIpc'; import { IconFactory } from './CustomIcons'; import { DropdownSetting, NumberSetting, ToggleSetting } from './settings/components'; import { SettingContainer } from './settings/SettingContainer'; diff --git a/src/renderer/components/groups/NcnnFileInputsGroup.tsx b/src/renderer/components/groups/NcnnFileInputsGroup.tsx index 5106b0c42..943fddaa2 100644 --- a/src/renderer/components/groups/NcnnFileInputsGroup.tsx +++ b/src/renderer/components/groups/NcnnFileInputsGroup.tsx @@ -1,7 +1,7 @@ import { memo, useEffect } from 'react'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../renderer/safeIpc'; import { getInputValue } from '../../../common/util'; +import { ipcRenderer } from '../../safeIpc'; import { SchemaInput } from '../inputs/SchemaInput'; import { GroupProps } from './props'; diff --git a/src/renderer/components/inputs/DirectoryInput.tsx b/src/renderer/components/inputs/DirectoryInput.tsx index 7b740e7fd..a78861213 100644 --- a/src/renderer/components/inputs/DirectoryInput.tsx +++ b/src/renderer/components/inputs/DirectoryInput.tsx @@ -14,11 +14,11 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { BsFolderPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; -import { ipcRenderer } from '../../../renderer/safeIpc'; import { getFields, isDirectory } from '../../../common/types/util'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; import { useLastDirectory } from '../../hooks/useLastDirectory'; +import { ipcRenderer } from '../../safeIpc'; import { AutoLabel } from './InputContainer'; import { InputProps } from './props'; diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index c26af7603..3227e944e 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -16,12 +16,12 @@ import { useTranslation } from 'react-i18next'; import { BsFileEarmarkPlus } from 'react-icons/bs'; import { MdContentCopy, MdFolder } from 'react-icons/md'; import { useContext } from 'use-context-selector'; -import { ipcRenderer } from '../../../renderer/safeIpc'; import { AlertBoxContext } from '../../contexts/AlertBoxContext'; import { getSingleFileWithExtension } from '../../helpers/dataTransfer'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; import { useLastDirectory } from '../../hooks/useLastDirectory'; +import { ipcRenderer } from '../../safeIpc'; import { WithLabel } from './InputContainer'; import { InputProps } from './props'; diff --git a/src/renderer/components/settings/components.tsx b/src/renderer/components/settings/components.tsx index b66cf41ee..eb9fd1e5b 100644 --- a/src/renderer/components/settings/components.tsx +++ b/src/renderer/components/settings/components.tsx @@ -14,7 +14,7 @@ import { memo, useEffect, useMemo } from 'react'; import { Setting } from '../../../common/common-types'; import { getCacheLocation } from '../../../common/env'; import { log } from '../../../common/log'; -import { ipcRenderer } from '../../../renderer/safeIpc'; +import { ipcRenderer } from '../../safeIpc'; import { SettingsProps } from './props'; import { SettingContainer } from './SettingContainer'; diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index 1b3e13ff0..d55274cca 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -21,9 +21,9 @@ import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { assertNever, noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; +import { ipcRenderer } from '../safeIpc'; import { ContextMenuContext } from './ContextMenuContext'; import { HotkeysContext } from './HotKeyContext'; diff --git a/src/renderer/contexts/BackendContext.tsx b/src/renderer/contexts/BackendContext.tsx index 3cb5fe384..c15705789 100644 --- a/src/renderer/contexts/BackendContext.tsx +++ b/src/renderer/contexts/BackendContext.tsx @@ -26,7 +26,6 @@ import { import { log } from '../../common/log'; import { parseFunctionDefinitions } from '../../common/nodes/parseFunctionDefinitions'; import { sortNodes } from '../../common/nodes/sort'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { SchemaInputsMap } from '../../common/SchemaInputsMap'; import { SchemaMap } from '../../common/SchemaMap'; import { getChainnerScope } from '../../common/types/chainner-scope'; @@ -35,6 +34,7 @@ import { EMPTY_ARRAY, EMPTY_MAP, delay } from '../../common/util'; import { useAsyncEffect } from '../hooks/useAsyncEffect'; import { useIpcRendererListener } from '../hooks/useIpcRendererListener'; import { useMemoObject } from '../hooks/useMemo'; +import { ipcRenderer } from '../safeIpc'; import { AlertBoxContext, AlertId, AlertType } from './AlertBoxContext'; interface BackendContextState { diff --git a/src/renderer/contexts/ExecutionContext.tsx b/src/renderer/contexts/ExecutionContext.tsx index 022ab4d93..591e3863a 100644 --- a/src/renderer/contexts/ExecutionContext.tsx +++ b/src/renderer/contexts/ExecutionContext.tsx @@ -11,7 +11,6 @@ import { checkNodeValidity } from '../../common/nodes/checkNodeValidity'; import { getConnectedInputs } from '../../common/nodes/connectedInputs'; import { optimizeChain } from '../../common/nodes/optimize'; import { toBackendJson } from '../../common/nodes/toBackendJson'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { getChainnerScope } from '../../common/types/chainner-scope'; import { fromJson } from '../../common/types/json'; import { EMPTY_MAP, EMPTY_SET, assertNever, groupBy } from '../../common/util'; @@ -29,6 +28,7 @@ import { } from '../hooks/useBackendEventSource'; import { EventBacklog, useEventBacklog } from '../hooks/useEventBacklog'; import { useMemoObject } from '../hooks/useMemo'; +import { ipcRenderer } from '../safeIpc'; import { AlertBoxContext, AlertType } from './AlertBoxContext'; import { BackendContext } from './BackendContext'; import { GlobalContext, GlobalVolatileContext } from './GlobalNodeState'; diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index 583749c57..ef71795ff 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -28,7 +28,6 @@ import { log } from '../../common/log'; import { getEffectivelyDisabledNodes } from '../../common/nodes/disabled'; import { ChainLineage } from '../../common/nodes/lineage'; import { TypeState } from '../../common/nodes/TypeState'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { ParsedSaveData, SaveData } from '../../common/SaveFile'; import { @@ -84,6 +83,7 @@ import { useOutputDataStore, } from '../hooks/useOutputDataStore'; import { getSessionStorageOrDefault, useSessionStorage } from '../hooks/useSessionStorage'; +import { ipcRenderer } from '../safeIpc'; import { AlertBoxContext, AlertType } from './AlertBoxContext'; import { BackendContext } from './BackendContext'; import { useSettings } from './SettingsContext'; diff --git a/src/renderer/contexts/HotKeyContext.tsx b/src/renderer/contexts/HotKeyContext.tsx index cd87f9335..abdfab2d6 100644 --- a/src/renderer/contexts/HotKeyContext.tsx +++ b/src/renderer/contexts/HotKeyContext.tsx @@ -1,8 +1,8 @@ import React, { memo, useCallback, useState } from 'react'; import { createContext } from 'use-context-selector'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; +import { ipcRenderer } from '../safeIpc'; interface HotkeysContextState { hotkeysEnabled: boolean; diff --git a/src/renderer/contexts/SettingsContext.tsx b/src/renderer/contexts/SettingsContext.tsx index 6f51039a5..ca0ce9a47 100644 --- a/src/renderer/contexts/SettingsContext.tsx +++ b/src/renderer/contexts/SettingsContext.tsx @@ -2,10 +2,10 @@ import { useColorMode } from '@chakra-ui/react'; import React, { SetStateAction, memo, useCallback, useEffect, useState } from 'react'; import { createContext, useContext } from 'use-context-selector'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { ChainnerSettings, defaultSettings } from '../../common/settings/settings'; import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; +import { ipcRenderer } from '../safeIpc'; interface SettingsContextValue { settings: Readonly; diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 7f936fcfd..695a47e8d 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -5,8 +5,8 @@ import { Edge, Node, Project } from 'reactflow'; import { v4 as uuid4 } from 'uuid'; import { EdgeData, InputId, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { createUniqueId, deriveUniqueId } from '../../common/util'; +import { ipcRenderer } from '../safeIpc'; import { NodeProto, copyEdges, copyNodes, setSelected } from './reactFlowUtil'; import { SetState } from './types'; diff --git a/src/renderer/helpers/dataTransfer.ts b/src/renderer/helpers/dataTransfer.ts index c56a818a9..96052c5a7 100644 --- a/src/renderer/helpers/dataTransfer.ts +++ b/src/renderer/helpers/dataTransfer.ts @@ -2,10 +2,10 @@ import { extname } from 'path'; import { Edge, Node, XYPosition } from 'reactflow'; import { EdgeData, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { ParsedSaveData, openSaveFile } from '../../common/SaveFile'; import { SchemaMap } from '../../common/SchemaMap'; import { createUniqueId, deriveUniqueId } from '../../common/util'; +import { ipcRenderer } from '../safeIpc'; import { NodeProto, copyEdges, copyNodes, setSelected } from './reactFlowUtil'; import { SetState } from './types'; diff --git a/src/renderer/hooks/useOpenRecent.ts b/src/renderer/hooks/useOpenRecent.ts index 3c0bea241..ff049e04b 100644 --- a/src/renderer/hooks/useOpenRecent.ts +++ b/src/renderer/hooks/useOpenRecent.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect } from 'react'; -import { ipcRenderer } from '../../renderer/safeIpc'; import { EMPTY_ARRAY } from '../../common/util'; +import { ipcRenderer } from '../safeIpc'; import { useIpcRendererListener } from './useIpcRendererListener'; import { useStored } from './useStored'; From 0f422e1e84c1e8573d60a5bfb50c36934cece7b0 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 13:10:59 -0400 Subject: [PATCH 14/22] attempt fixing main webpack --- webpack.main.config.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webpack.main.config.js b/webpack.main.config.js index bb586038e..9b7da5961 100644 --- a/webpack.main.config.js +++ b/webpack.main.config.js @@ -1,6 +1,8 @@ // eslint-disable-next-line import/no-extraneous-dependencies const CopyPlugin = require('copy-webpack-plugin'); +const isDevelopment = process.env.NODE_ENV !== 'production'; + /** @type {import("webpack").Configuration} */ module.exports = { /** @@ -10,6 +12,7 @@ module.exports = { entry: { main: './src/main/main.ts', }, + mode: isDevelopment ? 'development' : 'production', // Put your normal webpack config below here module: { // eslint-disable-next-line global-require @@ -21,6 +24,6 @@ module.exports = { }), ], resolve: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], + extensions: ['.js', '.ts'], }, }; From 1cc26f1ab1c5026b95fcb8531cecb1276abddd96 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 14:59:20 -0400 Subject: [PATCH 15/22] fixed webpack building --- package-lock.json | 246 +++++++++++++++++++++++++++++++++---- package.json | 5 +- webpack.main.config.js | 2 + webpack.renderer.config.js | 5 +- webpack.rules.js | 27 ++++ 5 files changed, 254 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5437e8b50..4176b8507 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,14 +91,14 @@ "@types/yargs": "^17.0.10", "@typescript-eslint/eslint-plugin": "^5.59.7", "@typescript-eslint/parser": "^5.59.7", - "@vercel/webpack-asset-relocator-loader": "^1.7.2", + "@vercel/webpack-asset-relocator-loader": "^1.7.3", "babel-loader": "^8.2.5", "babel-plugin-i18next-extract": "^0.9.0", "concurrently": "^7.2.1", "copy-webpack-plugin": "^11.0.0", "cross-env": "^7.0.3", "css-loader": "^6.7.1", - "electron": "^25.8.4", + "electron": "^29.1.6", "electron-installer-common": "^0.10.3", "eslint": "^8.16.0", "eslint-config-airbnb": "^19.0.4", @@ -128,6 +128,7 @@ "stylelint-config-standard-scss": "^5.0.0", "stylelint-prettier": "^2.0.0", "ts-jest": "^29.1.0", + "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "typescript": "^5.0.4" }, @@ -5993,10 +5994,13 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "node_modules/@types/node": { - "version": "18.17.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.1.tgz", - "integrity": "sha512-xlR1jahfizdplZYRU59JlUx9uzF1ARa8jbhM11ccpCJya8kvos5jwdm2ZAgxSCwOl0fq21svP18EVwPBXMQudw==", - "dev": true + "version": "20.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", + "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/node-localstorage": { "version": "1.3.0", @@ -6392,10 +6396,13 @@ "dev": true }, "node_modules/@vercel/webpack-asset-relocator-loader": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.2.tgz", - "integrity": "sha512-pdMwUawmAtH/LScbjKJq/y2+gZFggFMc2tlJrlPSrgKajvYPEis3L9QKcMyC9RN1Xos4ezAP5AJfRCNN6RMKCQ==", - "dev": true + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.3.tgz", + "integrity": "sha512-vizrI18v8Lcb1PmNNUBz7yxPxxXoOeuaVEjTG9MjvDrphjiSxFZrRJ5tIghk+qdLFRCXI5HBCshgobftbmrC5g==", + "dev": true, + "dependencies": { + "resolve": "^1.10.0" + } }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", @@ -10504,14 +10511,14 @@ "dev": true }, "node_modules/electron": { - "version": "25.8.4", - "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.4.tgz", - "integrity": "sha512-hUYS3RGdaa6E1UWnzeGnsdsBYOggwMMg4WGxNGvAoWtmRrr6J1BsjFW/yRq4WsJHJce2HdzQXtz4OGXV6yUCLg==", + "version": "29.1.6", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.6.tgz", + "integrity": "sha512-UIYfpHR9gRBFKHyejHuXUVQ7nNzZRnoPVOHlijkvqR+DSLwgJ2ZcVVt0LNduNeO8PhPkY1+6kHonL52OTC1cOw==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", + "@types/node": "^20.9.0", "extract-zip": "^2.0.1" }, "bin": { @@ -23942,6 +23949,105 @@ "node": ">=12" } }, + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ts-loader/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ts-loader/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ts-loader/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -24165,6 +24271,12 @@ "node": ">=14.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/unified": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", @@ -30004,10 +30116,13 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "@types/node": { - "version": "18.17.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.1.tgz", - "integrity": "sha512-xlR1jahfizdplZYRU59JlUx9uzF1ARa8jbhM11ccpCJya8kvos5jwdm2ZAgxSCwOl0fq21svP18EVwPBXMQudw==", - "dev": true + "version": "20.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", + "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } }, "@types/node-localstorage": { "version": "1.3.0", @@ -30310,10 +30425,13 @@ "dev": true }, "@vercel/webpack-asset-relocator-loader": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.2.tgz", - "integrity": "sha512-pdMwUawmAtH/LScbjKJq/y2+gZFggFMc2tlJrlPSrgKajvYPEis3L9QKcMyC9RN1Xos4ezAP5AJfRCNN6RMKCQ==", - "dev": true + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.3.tgz", + "integrity": "sha512-vizrI18v8Lcb1PmNNUBz7yxPxxXoOeuaVEjTG9MjvDrphjiSxFZrRJ5tIghk+qdLFRCXI5HBCshgobftbmrC5g==", + "dev": true, + "requires": { + "resolve": "^1.10.0" + } }, "@webassemblyjs/ast": { "version": "1.11.1", @@ -33464,13 +33582,13 @@ "dev": true }, "electron": { - "version": "25.8.4", - "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.4.tgz", - "integrity": "sha512-hUYS3RGdaa6E1UWnzeGnsdsBYOggwMMg4WGxNGvAoWtmRrr6J1BsjFW/yRq4WsJHJce2HdzQXtz4OGXV6yUCLg==", + "version": "29.1.6", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.6.tgz", + "integrity": "sha512-UIYfpHR9gRBFKHyejHuXUVQ7nNzZRnoPVOHlijkvqR+DSLwgJ2ZcVVt0LNduNeO8PhPkY1+6kHonL52OTC1cOw==", "dev": true, "requires": { "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", + "@types/node": "^20.9.0", "extract-zip": "^2.0.1" } }, @@ -43395,6 +43513,76 @@ } } }, + "ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -43556,6 +43744,12 @@ "@fastify/busboy": "^2.0.0" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "unified": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", diff --git a/package.json b/package.json index 3343f89e9..68ea707aa 100644 --- a/package.json +++ b/package.json @@ -65,14 +65,14 @@ "@types/yargs": "^17.0.10", "@typescript-eslint/eslint-plugin": "^5.59.7", "@typescript-eslint/parser": "^5.59.7", - "@vercel/webpack-asset-relocator-loader": "^1.7.2", + "@vercel/webpack-asset-relocator-loader": "^1.7.3", "babel-loader": "^8.2.5", "babel-plugin-i18next-extract": "^0.9.0", "concurrently": "^7.2.1", "copy-webpack-plugin": "^11.0.0", "cross-env": "^7.0.3", "css-loader": "^6.7.1", - "electron": "^25.8.4", + "electron": "^29.1.6", "electron-installer-common": "^0.10.3", "eslint": "^8.16.0", "eslint-config-airbnb": "^19.0.4", @@ -102,6 +102,7 @@ "stylelint-config-standard-scss": "^5.0.0", "stylelint-prettier": "^2.0.0", "ts-jest": "^29.1.0", + "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "typescript": "^5.0.4" }, diff --git a/webpack.main.config.js b/webpack.main.config.js index 9b7da5961..af1272f49 100644 --- a/webpack.main.config.js +++ b/webpack.main.config.js @@ -5,6 +5,7 @@ const isDevelopment = process.env.NODE_ENV !== 'production'; /** @type {import("webpack").Configuration} */ module.exports = { + target: 'electron-main', /** * This is the main entry point for your application, it's the first file * that runs in the main process. @@ -26,4 +27,5 @@ module.exports = { resolve: { extensions: ['.js', '.ts'], }, + externals: ['electron/common', 'electron/main'], }; diff --git a/webpack.renderer.config.js b/webpack.renderer.config.js index 39fdf3143..d6f0faef9 100644 --- a/webpack.renderer.config.js +++ b/webpack.renderer.config.js @@ -20,6 +20,7 @@ rules.push( /** @type {import("webpack").Configuration} */ module.exports = { + target: 'electron-renderer', // Put your normal webpack config below here module: { rules, @@ -36,9 +37,7 @@ module.exports = { resourceRegExp: /^fsevents$/, }), ].filter(Boolean), - externals: { - fsevents: "require('fsevents')", - }, + externals: ['electron/common', 'electron/renderer', 'fsevents'], resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], }, diff --git a/webpack.rules.js b/webpack.rules.js index 070112be4..32fc688ed 100644 --- a/webpack.rules.js +++ b/webpack.rules.js @@ -1,6 +1,33 @@ const isDevelopment = process.env.NODE_ENV !== 'production'; module.exports = [ + // Add support for native node modules + // { + // // We're specifying native_modules in the test because the asset relocator loader generates a + // // "fake" .node file which is really a cjs file. + // test: /native_modules[/\\].+\.node$/, + // use: 'node-loader', + // }, + // { + // test: /[/\\]node_modules[/\\].+\.(m?js|node)$/, + // parser: { amd: false }, + // use: { + // loader: '@vercel/webpack-asset-relocator-loader', + // options: { + // outputAssetBase: 'native_modules', + // }, + // }, + // }, + // { + // test: /\.tsx?$/, + // exclude: /(node_modules|\.webpack)/, + // use: { + // loader: 'ts-loader', + // options: { + // transpileOnly: true, + // }, + // }, + // }, // ... existing loader config ... { test: /\.[jt]sx?$/, From 8c42b7f79a815d3b65acbe58b16d2b24510811ab Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 15:17:03 -0400 Subject: [PATCH 16/22] Replace imports with TODOs --- src/common/safeIpc.ts | 4 +++- src/renderer/hooks/useIpcRendererListener.ts | 2 +- src/renderer/safeIpc.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index f8a7b6e68..f9a113984 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -1,5 +1,7 @@ +// eslint-disable-next-line import/no-duplicates import { type BrowserWindow, type MessagePortMain, type WebContents } from 'electron'; -import { type FileFilter, type OpenDialogReturnValue } from 'electron/common'; +// eslint-disable-next-line import/no-duplicates +import { type FileFilter, type OpenDialogReturnValue } from 'electron'; // TODO: replace with electron/common import { MakeDirectoryOptions } from 'fs'; import { Mode, ObjectEncodingOptions, OpenMode, PathLike } from 'original-fs'; import { FileOpenResult, FileSaveResult, PythonInfo, Version } from './common-types'; diff --git a/src/renderer/hooks/useIpcRendererListener.ts b/src/renderer/hooks/useIpcRendererListener.ts index 0359fad60..524e94c15 100644 --- a/src/renderer/hooks/useIpcRendererListener.ts +++ b/src/renderer/hooks/useIpcRendererListener.ts @@ -1,4 +1,4 @@ -import { IpcRendererEvent } from 'electron/renderer'; +import { IpcRendererEvent } from 'electron'; // TODO: replace with electron/renderer import { useEffect } from 'react'; import { ChannelArgs, SendChannels } from '../../common/safeIpc'; import { ipcRenderer } from '../safeIpc'; diff --git a/src/renderer/safeIpc.ts b/src/renderer/safeIpc.ts index e14b34b64..262fbb607 100644 --- a/src/renderer/safeIpc.ts +++ b/src/renderer/safeIpc.ts @@ -1,4 +1,4 @@ -import { IpcRendererEvent, ipcRenderer as unsafeIpcRenderer } from 'electron/renderer'; +import { IpcRendererEvent, ipcRenderer as unsafeIpcRenderer } from 'electron'; // TODO: replace with electron/renderer import { ChannelArgs, ChannelReturn, InvokeChannels, SendChannels } from '../common/safeIpc'; interface SafeIpcRenderer extends Electron.IpcRenderer { From 4c3e7b26eb0f70edc1e34afe0479f605da9fc67f Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 15:24:56 -0400 Subject: [PATCH 17/22] remove some residual stuff --- package-lock.json | 208 ++++++------------------------------------ package.json | 3 +- src/common/safeIpc.ts | 22 ----- webpack.rules.js | 27 ------ 4 files changed, 30 insertions(+), 230 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4176b8507..09fb9cd1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -98,7 +98,7 @@ "copy-webpack-plugin": "^11.0.0", "cross-env": "^7.0.3", "css-loader": "^6.7.1", - "electron": "^29.1.6", + "electron": "^25.8.4", "electron-installer-common": "^0.10.3", "eslint": "^8.16.0", "eslint-config-airbnb": "^19.0.4", @@ -128,7 +128,6 @@ "stylelint-config-standard-scss": "^5.0.0", "stylelint-prettier": "^2.0.0", "ts-jest": "^29.1.0", - "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "typescript": "^5.0.4" }, @@ -10511,14 +10510,14 @@ "dev": true }, "node_modules/electron": { - "version": "29.1.6", - "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.6.tgz", - "integrity": "sha512-UIYfpHR9gRBFKHyejHuXUVQ7nNzZRnoPVOHlijkvqR+DSLwgJ2ZcVVt0LNduNeO8PhPkY1+6kHonL52OTC1cOw==", + "version": "25.8.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.4.tgz", + "integrity": "sha512-hUYS3RGdaa6E1UWnzeGnsdsBYOggwMMg4WGxNGvAoWtmRrr6J1BsjFW/yRq4WsJHJce2HdzQXtz4OGXV6yUCLg==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^20.9.0", + "@types/node": "^18.11.18", "extract-zip": "^2.0.1" }, "bin": { @@ -10933,6 +10932,15 @@ "node": ">= 4.0.0" } }, + "node_modules/electron/node_modules/@types/node": { + "version": "18.19.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.28.tgz", + "integrity": "sha512-J5cOGD9n4x3YGgVuaND6khm5x07MMdAKkRyXnjVR6KFhLMNh2yONGiP7Z+4+tBOt5mK+GvDTiacTOVGGpqiecw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/elkjs": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", @@ -23949,105 +23957,6 @@ "node": ">=12" } }, - "node_modules/ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ts-loader/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ts-loader/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ts-loader/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ts-loader/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/ts-loader/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -33582,14 +33491,25 @@ "dev": true }, "electron": { - "version": "29.1.6", - "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.6.tgz", - "integrity": "sha512-UIYfpHR9gRBFKHyejHuXUVQ7nNzZRnoPVOHlijkvqR+DSLwgJ2ZcVVt0LNduNeO8PhPkY1+6kHonL52OTC1cOw==", + "version": "25.8.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.4.tgz", + "integrity": "sha512-hUYS3RGdaa6E1UWnzeGnsdsBYOggwMMg4WGxNGvAoWtmRrr6J1BsjFW/yRq4WsJHJce2HdzQXtz4OGXV6yUCLg==", "dev": true, "requires": { "@electron/get": "^2.0.0", - "@types/node": "^20.9.0", + "@types/node": "^18.11.18", "extract-zip": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "18.19.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.28.tgz", + "integrity": "sha512-J5cOGD9n4x3YGgVuaND6khm5x07MMdAKkRyXnjVR6KFhLMNh2yONGiP7Z+4+tBOt5mK+GvDTiacTOVGGpqiecw==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + } } }, "electron-installer-common": { @@ -43513,76 +43433,6 @@ } } }, - "ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", diff --git a/package.json b/package.json index 68ea707aa..f65565fc6 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "copy-webpack-plugin": "^11.0.0", "cross-env": "^7.0.3", "css-loader": "^6.7.1", - "electron": "^29.1.6", + "electron": "^25.8.4", "electron-installer-common": "^0.10.3", "eslint": "^8.16.0", "eslint-config-airbnb": "^19.0.4", @@ -102,7 +102,6 @@ "stylelint-config-standard-scss": "^5.0.0", "stylelint-prettier": "^2.0.0", "ts-jest": "^29.1.0", - "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "typescript": "^5.0.4" }, diff --git a/src/common/safeIpc.ts b/src/common/safeIpc.ts index f9a113984..d5f89d64d 100644 --- a/src/common/safeIpc.ts +++ b/src/common/safeIpc.ts @@ -1,6 +1,3 @@ -// eslint-disable-next-line import/no-duplicates -import { type BrowserWindow, type MessagePortMain, type WebContents } from 'electron'; -// eslint-disable-next-line import/no-duplicates import { type FileFilter, type OpenDialogReturnValue } from 'electron'; // TODO: replace with electron/common import { MakeDirectoryOptions } from 'fs'; import { Mode, ObjectEncodingOptions, OpenMode, PathLike } from 'original-fs'; @@ -143,22 +140,3 @@ export type ChannelArgs = (Invo SendChannels)[C]['args']; export type ChannelReturn = (InvokeChannels & SendChannels)[C]['returnType']; - -interface WebContentsWithSafeIcp extends WebContents { - invoke( - channel: C, - ...args: ChannelArgs - ): Promise>; - postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePortMain[]): void; - send(channel: C, ...args: ChannelArgs): void; - sendSync(channel: C, ...args: ChannelArgs): ChannelReturn; - sendTo( - webContentsId: number, - channel: C, - ...args: ChannelArgs - ): void; - sendToHost(channel: C, ...args: ChannelArgs): void; -} -export interface BrowserWindowWithSafeIpc extends BrowserWindow { - webContents: WebContentsWithSafeIcp; -} diff --git a/webpack.rules.js b/webpack.rules.js index 32fc688ed..070112be4 100644 --- a/webpack.rules.js +++ b/webpack.rules.js @@ -1,33 +1,6 @@ const isDevelopment = process.env.NODE_ENV !== 'production'; module.exports = [ - // Add support for native node modules - // { - // // We're specifying native_modules in the test because the asset relocator loader generates a - // // "fake" .node file which is really a cjs file. - // test: /native_modules[/\\].+\.node$/, - // use: 'node-loader', - // }, - // { - // test: /[/\\]node_modules[/\\].+\.(m?js|node)$/, - // parser: { amd: false }, - // use: { - // loader: '@vercel/webpack-asset-relocator-loader', - // options: { - // outputAssetBase: 'native_modules', - // }, - // }, - // }, - // { - // test: /\.tsx?$/, - // exclude: /(node_modules|\.webpack)/, - // use: { - // loader: 'ts-loader', - // options: { - // transpileOnly: true, - // }, - // }, - // }, // ... existing loader config ... { test: /\.[jt]sx?$/, From ac3ec8040096f8882fce154f990eee825cd7d099 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 15:27:10 -0400 Subject: [PATCH 18/22] remove extra newlines --- src/renderer/components/inputs/TextInput.tsx | 1 - src/renderer/contexts/AlertBoxContext.tsx | 1 - src/renderer/contexts/BackendContext.tsx | 1 - src/renderer/contexts/DependencyContext.tsx | 1 - src/renderer/contexts/ExecutionContext.tsx | 1 - src/renderer/contexts/HotKeyContext.tsx | 1 - src/renderer/contexts/SettingsContext.tsx | 1 - src/renderer/helpers/copyAndPaste.ts | 1 - src/renderer/helpers/dataTransfer.ts | 1 - src/renderer/helpers/nodeScreenshot.ts | 1 - src/renderer/hooks/useInputRefactor.tsx | 1 - 11 files changed, 11 deletions(-) diff --git a/src/renderer/components/inputs/TextInput.tsx b/src/renderer/components/inputs/TextInput.tsx index 016333afa..c2c9b1712 100644 --- a/src/renderer/components/inputs/TextInput.tsx +++ b/src/renderer/components/inputs/TextInput.tsx @@ -6,7 +6,6 @@ import { MdContentCopy, MdContentPaste } from 'react-icons/md'; import { useContextSelector } from 'use-context-selector'; import { useDebouncedCallback } from 'use-debounce'; import { log } from '../../../common/log'; - import { GlobalVolatileContext } from '../../contexts/GlobalNodeState'; import { typeToString } from '../../helpers/naviHelpers'; import { useContextMenu } from '../../hooks/useContextMenu'; diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index 770eb81f7..ac72dd046 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -20,7 +20,6 @@ import path from 'path'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createContext, useContext, useContextSelector } from 'use-context-selector'; import { log } from '../../common/log'; - import { assertNever, noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; import { ipcRenderer } from '../safeIpc'; diff --git a/src/renderer/contexts/BackendContext.tsx b/src/renderer/contexts/BackendContext.tsx index 738e1f6c9..c15705789 100644 --- a/src/renderer/contexts/BackendContext.tsx +++ b/src/renderer/contexts/BackendContext.tsx @@ -26,7 +26,6 @@ import { import { log } from '../../common/log'; import { parseFunctionDefinitions } from '../../common/nodes/parseFunctionDefinitions'; import { sortNodes } from '../../common/nodes/sort'; - import { SchemaInputsMap } from '../../common/SchemaInputsMap'; import { SchemaMap } from '../../common/SchemaMap'; import { getChainnerScope } from '../../common/types/chainner-scope'; diff --git a/src/renderer/contexts/DependencyContext.tsx b/src/renderer/contexts/DependencyContext.tsx index 8794cd2fb..cbb91614c 100644 --- a/src/renderer/contexts/DependencyContext.tsx +++ b/src/renderer/contexts/DependencyContext.tsx @@ -54,7 +54,6 @@ import { } from '../../common/common-types'; import { log } from '../../common/log'; import { getFindLinks } from '../../common/pip'; - import { noop } from '../../common/util'; import { versionGt } from '../../common/version'; import { Markdown } from '../components/Markdown'; diff --git a/src/renderer/contexts/ExecutionContext.tsx b/src/renderer/contexts/ExecutionContext.tsx index 66c8fd5b9..591e3863a 100644 --- a/src/renderer/contexts/ExecutionContext.tsx +++ b/src/renderer/contexts/ExecutionContext.tsx @@ -11,7 +11,6 @@ import { checkNodeValidity } from '../../common/nodes/checkNodeValidity'; import { getConnectedInputs } from '../../common/nodes/connectedInputs'; import { optimizeChain } from '../../common/nodes/optimize'; import { toBackendJson } from '../../common/nodes/toBackendJson'; - import { getChainnerScope } from '../../common/types/chainner-scope'; import { fromJson } from '../../common/types/json'; import { EMPTY_MAP, EMPTY_SET, assertNever, groupBy } from '../../common/util'; diff --git a/src/renderer/contexts/HotKeyContext.tsx b/src/renderer/contexts/HotKeyContext.tsx index bce513fa0..abdfab2d6 100644 --- a/src/renderer/contexts/HotKeyContext.tsx +++ b/src/renderer/contexts/HotKeyContext.tsx @@ -1,6 +1,5 @@ import React, { memo, useCallback, useState } from 'react'; import { createContext } from 'use-context-selector'; - import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; import { ipcRenderer } from '../safeIpc'; diff --git a/src/renderer/contexts/SettingsContext.tsx b/src/renderer/contexts/SettingsContext.tsx index 68263ae15..ca0ce9a47 100644 --- a/src/renderer/contexts/SettingsContext.tsx +++ b/src/renderer/contexts/SettingsContext.tsx @@ -2,7 +2,6 @@ import { useColorMode } from '@chakra-ui/react'; import React, { SetStateAction, memo, useCallback, useEffect, useState } from 'react'; import { createContext, useContext } from 'use-context-selector'; import { log } from '../../common/log'; - import { ChainnerSettings, defaultSettings } from '../../common/settings/settings'; import { noop } from '../../common/util'; import { useMemoObject } from '../hooks/useMemo'; diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 182216c2c..320760d0a 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -4,7 +4,6 @@ import { Edge, Node, Project } from 'reactflow'; import { v4 as uuid4 } from 'uuid'; import { EdgeData, InputId, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; - import { createUniqueId, deriveUniqueId } from '../../common/util'; import { ipcRenderer } from '../safeIpc'; import { NodeProto, copyEdges, copyNodes, setSelected } from './reactFlowUtil'; diff --git a/src/renderer/helpers/dataTransfer.ts b/src/renderer/helpers/dataTransfer.ts index 26bbd33fa..96052c5a7 100644 --- a/src/renderer/helpers/dataTransfer.ts +++ b/src/renderer/helpers/dataTransfer.ts @@ -2,7 +2,6 @@ import { extname } from 'path'; import { Edge, Node, XYPosition } from 'reactflow'; import { EdgeData, NodeData, SchemaId } from '../../common/common-types'; import { log } from '../../common/log'; - import { ParsedSaveData, openSaveFile } from '../../common/SaveFile'; import { SchemaMap } from '../../common/SchemaMap'; import { createUniqueId, deriveUniqueId } from '../../common/util'; diff --git a/src/renderer/helpers/nodeScreenshot.ts b/src/renderer/helpers/nodeScreenshot.ts index b38d63427..f95694f5f 100644 --- a/src/renderer/helpers/nodeScreenshot.ts +++ b/src/renderer/helpers/nodeScreenshot.ts @@ -2,7 +2,6 @@ import { toPng } from 'html-to-image'; import { Node, ReactFlowInstance } from 'reactflow'; import { EdgeData, NodeData } from '../../common/common-types'; import { log } from '../../common/log'; - import { delay } from '../../common/util'; import { ipcRenderer } from '../safeIpc'; diff --git a/src/renderer/hooks/useInputRefactor.tsx b/src/renderer/hooks/useInputRefactor.tsx index b5e346789..cba42d38f 100644 --- a/src/renderer/hooks/useInputRefactor.tsx +++ b/src/renderer/hooks/useInputRefactor.tsx @@ -17,7 +17,6 @@ import { } from '../../common/common-types'; import { createInputOverrideId } from '../../common/input-override-common'; import { log } from '../../common/log'; - import { createUniqueId } from '../../common/util'; import { BackendContext } from '../contexts/BackendContext'; import { FakeNodeContext } from '../contexts/FakeExampleContext'; From 6c1a943f00fed4d7dc216533b2d25a80791eeec2 Mon Sep 17 00:00:00 2001 From: Joey Ballentine <34788790+joeyballentine@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:56:45 -0400 Subject: [PATCH 19/22] Update src/renderer/contexts/GlobalNodeState.tsx Co-authored-by: Michael Schmidt --- src/renderer/contexts/GlobalNodeState.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index 76804fb30..caee8744a 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -28,7 +28,6 @@ import { log } from '../../common/log'; import { getEffectivelyDisabledNodes } from '../../common/nodes/disabled'; import { ChainLineage } from '../../common/nodes/lineage'; import { TypeState } from '../../common/nodes/TypeState'; - import { ParsedSaveData, SaveData } from '../../common/SaveFile'; import { From fed8b69efb295f6d10c6e697feb54bf33ce454b6 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 18:08:29 -0400 Subject: [PATCH 20/22] Replace IPC clipboard writeText calls with navigator.clipboard --- src/renderer/components/inputs/DirectoryInput.tsx | 4 +--- src/renderer/components/inputs/FileInput.tsx | 4 +--- src/renderer/components/inputs/SliderInput.tsx | 4 +--- src/renderer/components/node/special/NoteNode.tsx | 4 +--- src/renderer/contexts/AlertBoxContext.tsx | 4 ++-- src/renderer/contexts/DependencyContext.tsx | 5 ++--- src/renderer/hooks/useInputRefactor.tsx | 5 ++--- 7 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/renderer/components/inputs/DirectoryInput.tsx b/src/renderer/components/inputs/DirectoryInput.tsx index 91de49cfc..83da97045 100644 --- a/src/renderer/components/inputs/DirectoryInput.tsx +++ b/src/renderer/components/inputs/DirectoryInput.tsx @@ -93,9 +93,7 @@ export const DirectoryInput = memo( isDisabled={!displayDirectory} onClick={() => { if (displayDirectory) { - ipcRenderer - .invoke('clipboard-writeText', displayDirectory) - .catch(log.error); + navigator.clipboard.writeText(displayDirectory).catch(log.error); } }} > diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index 8a5bc335b..8a11aebdd 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -132,9 +132,7 @@ export const FileInput = memo( isDisabled={!filePath} onClick={() => { if (filePath) { - ipcRenderer - .invoke('clipboard-writeText', path.parse(filePath).name) - .catch(log.error); + navigator.clipboard.writeText(filePath).catch(log.error); } }} > diff --git a/src/renderer/components/inputs/SliderInput.tsx b/src/renderer/components/inputs/SliderInput.tsx index 0d0a97d89..39e7240b5 100644 --- a/src/renderer/components/inputs/SliderInput.tsx +++ b/src/renderer/components/inputs/SliderInput.tsx @@ -154,9 +154,7 @@ export const SliderInput = memo( } onClick={() => { - ipcRenderer - .invoke('clipboard-writeText', String(displaySliderValue)) - .catch(log.error); + navigator.clipboard.writeText(String(displaySliderValue)).catch(log.error); }} > {t('inputs.number.copyText', 'Copy Number')} diff --git a/src/renderer/components/node/special/NoteNode.tsx b/src/renderer/components/node/special/NoteNode.tsx index b20a5bd5d..4337f234a 100644 --- a/src/renderer/components/node/special/NoteNode.tsx +++ b/src/renderer/components/node/special/NoteNode.tsx @@ -129,9 +129,7 @@ const NoteNodeInner = memo(({ data, selected }: NodeProps) => { icon={} onClick={() => { if (value !== undefined) { - ipcRenderer - .invoke('clipboard-writeText', value.toString()) - .catch(log.error); + navigator.clipboard.writeText(value.toString()).catch(log.error); } }} > diff --git a/src/renderer/contexts/AlertBoxContext.tsx b/src/renderer/contexts/AlertBoxContext.tsx index ac72dd046..ed751253c 100644 --- a/src/renderer/contexts/AlertBoxContext.tsx +++ b/src/renderer/contexts/AlertBoxContext.tsx @@ -319,8 +319,8 @@ const AlertBoxDialog = memo( icon={} title="Copy to Clipboard" onClick={() => { - ipcRenderer - .invoke('clipboard-writeText', copyText) + navigator.clipboard + .writeText(copyText.toString()) .catch(log.error); }} /> diff --git a/src/renderer/contexts/DependencyContext.tsx b/src/renderer/contexts/DependencyContext.tsx index cbb91614c..ee2664246 100644 --- a/src/renderer/contexts/DependencyContext.tsx +++ b/src/renderer/contexts/DependencyContext.tsx @@ -62,7 +62,6 @@ import { useBackendSetupEventSource, } from '../hooks/useBackendEventSource'; import { useMemoObject } from '../hooks/useMemo'; -import { ipcRenderer } from '../safeIpc'; import { AlertBoxContext, AlertType } from './AlertBoxContext'; import { BackendContext } from './BackendContext'; import { GlobalContext } from './GlobalNodeState'; @@ -491,8 +490,8 @@ export const DependencyProvider = memo(({ children }: React.PropsWithChildren { - ipcRenderer - .invoke('clipboard-writeText', command) + navigator.clipboard + .writeText(command) .then(() => { onPopoverToggle(); setTimeout(() => { diff --git a/src/renderer/hooks/useInputRefactor.tsx b/src/renderer/hooks/useInputRefactor.tsx index cba42d38f..1480f2296 100644 --- a/src/renderer/hooks/useInputRefactor.tsx +++ b/src/renderer/hooks/useInputRefactor.tsx @@ -21,7 +21,6 @@ import { createUniqueId } from '../../common/util'; import { BackendContext } from '../contexts/BackendContext'; import { FakeNodeContext } from '../contexts/FakeExampleContext'; import { GlobalContext } from '../contexts/GlobalNodeState'; -import { ipcRenderer } from '../safeIpc'; const valueNodeMap = { number: 'chainner:utility:number' as SchemaId, @@ -109,8 +108,8 @@ export const useInputRefactor = ( icon={} key="copy override" onClick={() => { - ipcRenderer - .invoke('clipboard-writeText', createInputOverrideId(nodeId, inputId)) + navigator.clipboard + .writeText(createInputOverrideId(nodeId, inputId)) .catch(log.error); }} > From b64a85f627297a45d1c3ea41780e1a26acc85a1e Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 18:11:48 -0400 Subject: [PATCH 21/22] Replace some remaining clipboard calls --- src/renderer/components/inputs/FileInput.tsx | 2 +- src/renderer/components/inputs/NumberInput.tsx | 7 +++---- src/renderer/components/inputs/SliderInput.tsx | 5 ++--- src/renderer/components/inputs/TextInput.tsx | 7 +++---- src/renderer/components/node/special/NoteNode.tsx | 5 ++--- src/renderer/helpers/copyAndPaste.ts | 2 +- 6 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/renderer/components/inputs/FileInput.tsx b/src/renderer/components/inputs/FileInput.tsx index 8a11aebdd..9cccf2a8f 100644 --- a/src/renderer/components/inputs/FileInput.tsx +++ b/src/renderer/components/inputs/FileInput.tsx @@ -143,7 +143,7 @@ export const FileInput = memo( isDisabled={!filePath} onClick={() => { if (filePath) { - ipcRenderer.invoke('clipboard-writeText', filePath).catch(log.error); + navigator.clipboard.writeText(filePath).catch(log.error); } }} > diff --git a/src/renderer/components/inputs/NumberInput.tsx b/src/renderer/components/inputs/NumberInput.tsx index 692bd0920..aade25515 100644 --- a/src/renderer/components/inputs/NumberInput.tsx +++ b/src/renderer/components/inputs/NumberInput.tsx @@ -7,7 +7,6 @@ import { log } from '../../../common/log'; import { areApproximatelyEqual } from '../../../common/util'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; -import { ipcRenderer } from '../../safeIpc'; import { AdvancedNumberInput } from './elements/AdvanceNumberInput'; import { AutoLabel } from './InputContainer'; import { InputProps } from './props'; @@ -59,7 +58,7 @@ export const NumberInput = memo( icon={} isDisabled={!displayString} onClick={() => { - ipcRenderer.invoke('clipboard-writeText', displayString).catch(log.error); + navigator.clipboard.writeText(displayString).catch(log.error); }} > {t('inputs.number.copyText', 'Copy Number')} @@ -67,8 +66,8 @@ export const NumberInput = memo( } onClick={() => { - ipcRenderer - .invoke('clipboard-readText') + navigator.clipboard + .readText() .then((clipboardValue) => { const n = Number(clipboardValue); if ( diff --git a/src/renderer/components/inputs/SliderInput.tsx b/src/renderer/components/inputs/SliderInput.tsx index 39e7240b5..c21743eb3 100644 --- a/src/renderer/components/inputs/SliderInput.tsx +++ b/src/renderer/components/inputs/SliderInput.tsx @@ -12,7 +12,6 @@ import { BackendContext } from '../../contexts/BackendContext'; import { InputContext } from '../../contexts/InputContext'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; -import { ipcRenderer } from '../../safeIpc'; import { AdvancedNumberInput } from './elements/AdvanceNumberInput'; import { LINEAR_SCALE, @@ -162,8 +161,8 @@ export const SliderInput = memo( } onClick={() => { - ipcRenderer - .invoke('clipboard-readText') + navigator.clipboard + .readText() .then((clipboardValue) => { const n = Number(clipboardValue); if (!Number.isNaN(n) && min <= n && max >= n) { diff --git a/src/renderer/components/inputs/TextInput.tsx b/src/renderer/components/inputs/TextInput.tsx index c2c9b1712..c0505df9d 100644 --- a/src/renderer/components/inputs/TextInput.tsx +++ b/src/renderer/components/inputs/TextInput.tsx @@ -10,7 +10,6 @@ import { GlobalVolatileContext } from '../../contexts/GlobalNodeState'; import { typeToString } from '../../helpers/naviHelpers'; import { useContextMenu } from '../../hooks/useContextMenu'; import { useInputRefactor } from '../../hooks/useInputRefactor'; -import { ipcRenderer } from '../../safeIpc'; import { DragHandleSVG } from '../CustomIcons'; import { AutoLabel } from './InputContainer'; import { InputProps } from './props'; @@ -91,7 +90,7 @@ export const TextInput = memo( isDisabled={!displayText} onClick={() => { if (displayText !== undefined) { - ipcRenderer.invoke('clipboard-writeText', displayText).catch(log.error); + navigator.clipboard.writeText(displayText).catch(log.error); } }} > @@ -101,8 +100,8 @@ export const TextInput = memo( icon={} isDisabled={isConnected} onClick={() => { - ipcRenderer - .invoke('clipboard-readText') + navigator.clipboard + .readText() .then((clipboardValue) => { // replace new lines const text = clipboardValue.replace( diff --git a/src/renderer/components/node/special/NoteNode.tsx b/src/renderer/components/node/special/NoteNode.tsx index 4337f234a..385b00011 100644 --- a/src/renderer/components/node/special/NoteNode.tsx +++ b/src/renderer/components/node/special/NoteNode.tsx @@ -28,7 +28,6 @@ import { useNodeStateFromData } from '../../../helpers/nodeState'; import { useContextMenu } from '../../../hooks/useContextMenu'; import { useDisabled } from '../../../hooks/useDisabled'; import { useNodeMenu } from '../../../hooks/useNodeMenu'; -import { ipcRenderer } from '../../../safeIpc'; import { DragHandleSVG, IconFactory } from '../../CustomIcons'; import { Markdown } from '../../Markdown'; @@ -138,8 +137,8 @@ const NoteNodeInner = memo(({ data, selected }: NodeProps) => { } onClick={() => { - ipcRenderer - .invoke('clipboard-readText') + navigator.clipboard + .readText() .then((clipboardValue) => { // replace new lines const text = clipboardValue.replace(/\r?\n|\r/g, '\n'); diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 320760d0a..7103302c7 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -96,7 +96,7 @@ export const pasteFromClipboard = async ( log.debug('Clipboard format', format); switch (format) { case 'text/plain': - log.debug('Clipboard text', ipcRenderer.invoke('clipboard-readText')); + log.debug('Clipboard text', navigator.clipboard.readText()); break; case 'text/html': log.debug('Clipboard html', ipcRenderer.invoke('clipboard-readHTML')); From f7b0983d115950b11ec6e367dc92d8e7e81e90d3 Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Sat, 30 Mar 2024 18:17:36 -0400 Subject: [PATCH 22/22] Fix chain copy and paste --- src/renderer/helpers/copyAndPaste.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 7103302c7..574f53276 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -67,7 +67,7 @@ export const pasteFromClipboard = async ( 'clipboard-readBuffer', 'application/chainner.chain' ); - const chain = JSON.parse(clipboardData.toString()) as ClipboardChain; + const chain = JSON.parse(Buffer.from(clipboardData).toString()) as ClipboardChain; const duplicationId = createUniqueId(); const deriveId = (oldId: string) => deriveUniqueId(duplicationId + oldId);