diff --git a/core/src/browser/fs.ts b/core/src/browser/fs.ts index 3d4b948e9..cca9bb1d3 100644 --- a/core/src/browser/fs.ts +++ b/core/src/browser/fs.ts @@ -55,16 +55,6 @@ const unlinkSync = (...args: any[]) => globalThis.core.api?.unlinkSync(...args) */ const appendFileSync = (...args: any[]) => globalThis.core.api?.appendFileSync(...args) -/** - * Synchronizes a file from a source path to a destination path. - * @param {string} src - The source path of the file to be synchronized. - * @param {string} dest - The destination path where the file will be synchronized to. - * @returns {Promise} - A promise that resolves when the file has been successfully synchronized. - */ -const syncFile: (src: string, dest: string) => Promise = (src, dest) => - globalThis.core.api?.syncFile(src, dest) - - const copyFile: (src: string, dest: string) => Promise = (src, dest) => globalThis.core.api?.copyFile(src, dest) @@ -92,7 +82,6 @@ export const fs = { unlinkSync, appendFileSync, copyFile, - syncFile, fileStat, writeBlob, } diff --git a/core/src/node/api/processors/fsExt.ts b/core/src/node/api/processors/fsExt.ts index 041586b5a..155732cfc 100644 --- a/core/src/node/api/processors/fsExt.ts +++ b/core/src/node/api/processors/fsExt.ts @@ -18,20 +18,6 @@ export class FSExt implements Processor { return func(...args) } - // Handles the 'syncFile' IPC event. This event is triggered to synchronize a file from a source path to a destination path. - syncFile(src: string, dest: string) { - const reflect = require('@alumna/reflect') - validatePath(dest) - return reflect({ - src, - dest, - recursive: true, - delete: false, - overwrite: true, - errorOnExist: false, - }) - } - // Handles the 'getJanDataFolderPath' IPC event. This event is triggered to get the user space path. getJanDataFolderPath() { return Promise.resolve(getPath()) diff --git a/core/src/types/api/index.ts b/core/src/types/api/index.ts index 45f265b5a..e50dce6de 100644 --- a/core/src/types/api/index.ts +++ b/core/src/types/api/index.ts @@ -99,7 +99,6 @@ export enum FileSystemRoute { writeFileSync = 'writeFileSync', } export enum FileManagerRoute { - syncFile = 'syncFile', copyFile = 'copyFile', getJanDataFolderPath = 'getJanDataFolderPath', getResourcePath = 'getResourcePath', diff --git a/electron/preload.ts b/electron/preload.ts index 6ac259e0d..05f48d37a 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -3,8 +3,9 @@ * @module preload */ -import { APIEvents, APIRoutes } from '@janhq/core/node' +import { APIEvents, APIRoutes, AppConfiguration, getAppConfigurations, updateAppConfiguration } from '@janhq/core/node' import { contextBridge, ipcRenderer } from 'electron' +import { readdirSync } from 'fs' const interfaces: { [key: string]: (...args: any[]) => any } = {} @@ -12,7 +13,9 @@ const interfaces: { [key: string]: (...args: any[]) => any } = {} APIRoutes.forEach((method) => { // For each method, create a function on the interfaces object // This function invokes the method on the ipcRenderer with any provided arguments + interfaces[method] = (...args: any[]) => ipcRenderer.invoke(method, ...args) + }) // Loop over each method in APIEvents @@ -22,6 +25,33 @@ APIEvents.forEach((method) => { // The handler for the event is provided as an argument to the function interfaces[method] = (handler: any) => ipcRenderer.on(method, handler) }) + + +interfaces['changeDataFolder'] = async path => { + const appConfiguration: AppConfiguration = await ipcRenderer.invoke('getAppConfigurations') + const currentJanDataFolder = appConfiguration.data_folder + appConfiguration.data_folder = path + const reflect = require('@alumna/reflect') + const { err } = await reflect({ + src: currentJanDataFolder, + dest: path, + recursive: true, + delete: false, + overwrite: true, + errorOnExist: false, + }) + if (err) { + console.error(err) + throw err + } + await ipcRenderer.invoke('updateAppConfiguration', appConfiguration) +} + +interfaces['isDirectoryEmpty'] = async path => { + const dirChildren = await readdirSync(path) + return dirChildren.filter((x) => x !== '.DS_Store').length === 0 +} + // Expose the 'interfaces' object in the main world under the name 'electronAPI' // This allows the renderer process to access these methods directly contextBridge.exposeInMainWorld('electronAPI', { diff --git a/web/containers/Layout/BottomPanel/SystemMonitor/index.tsx b/web/containers/Layout/BottomPanel/SystemMonitor/index.tsx index 0d8938aa1..9d6311e73 100644 --- a/web/containers/Layout/BottomPanel/SystemMonitor/index.tsx +++ b/web/containers/Layout/BottomPanel/SystemMonitor/index.tsx @@ -1,6 +1,6 @@ import { Fragment, useEffect, useState } from 'react' -import { Button, Progress } from '@janhq/joi' +import { Progress } from '@janhq/joi' import { useClickOutside } from '@janhq/joi' import { useAtom, useAtomValue } from 'jotai' import { diff --git a/web/screens/Settings/Advanced/DataFolder/index.tsx b/web/screens/Settings/Advanced/DataFolder/index.tsx index 362a8be58..1ce06979c 100644 --- a/web/screens/Settings/Advanced/DataFolder/index.tsx +++ b/web/screens/Settings/Advanced/DataFolder/index.tsx @@ -1,6 +1,6 @@ import { Fragment, useCallback, useState } from 'react' -import { fs, AppConfiguration, isSubdirectory } from '@janhq/core' +import { AppConfiguration, isSubdirectory } from '@janhq/core' import { Button, Input } from '@janhq/joi' import { useAtomValue, useSetAtom } from 'jotai' import { PencilIcon, FolderOpenIcon } from 'lucide-react' @@ -51,11 +51,10 @@ const DataFolder = () => { return } - const newDestChildren: string[] = await fs.readdirSync(destFolder) - const isNotEmpty = - newDestChildren.filter((x) => x !== '.DS_Store').length > 0 + const isEmpty: boolean = + await window.core?.api?.isDirectoryEmpty(destFolder) - if (isNotEmpty) { + if (!isEmpty) { setDestinationPath(destFolder) showDestNotEmptyConfirm(true) return @@ -74,16 +73,7 @@ const DataFolder = () => { if (!destinationPath) return try { setShowLoader(true) - const appConfiguration: AppConfiguration = - await window.core?.api?.getAppConfigurations() - const currentJanDataFolder = appConfiguration.data_folder - appConfiguration.data_folder = destinationPath - const { err } = await fs.syncFile(currentJanDataFolder, destinationPath) - if (err) throw err - await window.core?.api?.updateAppConfiguration(appConfiguration) - console.debug( - `File sync finished from ${currentJanDataFolder} to ${destinationPath}` - ) + await window.core?.api?.changeDataFolder(destinationPath) localStorage.setItem(SUCCESS_SET_NEW_DESTINATION, 'true') setTimeout(() => { setShowLoader(false) diff --git a/web/screens/Settings/CoreExtensions/ExtensionItem.tsx b/web/screens/Settings/CoreExtensions/ExtensionItem.tsx index ec72f5f43..497b8ac4a 100644 --- a/web/screens/Settings/CoreExtensions/ExtensionItem.tsx +++ b/web/screens/Settings/CoreExtensions/ExtensionItem.tsx @@ -32,8 +32,8 @@ const ExtensionItem: React.FC = ({ item }) => { ) const progress = isInstalling - ? installingExtensions.find((e) => e.extensionId === item.name) - ?.percentage ?? -1 + ? (installingExtensions.find((e) => e.extensionId === item.name) + ?.percentage ?? -1) : -1 useEffect(() => { diff --git a/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx b/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx index 721213f41..26aa7c892 100644 --- a/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/SimpleTextMessage/index.tsx @@ -178,7 +178,7 @@ const SimpleTextMessage: React.FC = (props) => { > {isUser ? props.role - : activeThread?.assistants[0].assistant_name ?? props.role} + : (activeThread?.assistants[0].assistant_name ?? props.role)}

{displayDate(props.created)}