From d76a173706ab7f1b157e864ceed4b8c6fa3c5de6 Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Sun, 27 Oct 2024 18:58:23 +0800 Subject: [PATCH] feat: use real file path --- src/main/ipc.ts | 7 +++++-- src/preload/index.d.ts | 1 + src/preload/index.ts | 2 +- src/renderer/src/components/app/Sidebar.tsx | 2 +- src/renderer/src/hooks/useAppInit.ts | 11 +++++++++-- src/renderer/src/hooks/useRuntime.ts | 5 +++++ src/renderer/src/hooks/useStore.ts | 4 ---- src/renderer/src/pages/files/FilesPage.tsx | 3 ++- src/renderer/src/pages/home/Inputbar/Inputbar.tsx | 3 ++- .../pages/home/Messages/MessageAttachments.tsx | 2 +- .../src/pages/home/Messages/MessageTokens.tsx | 2 +- src/renderer/src/pages/home/Messages/Messages.tsx | 2 +- src/renderer/src/services/file.ts | 15 ++++++++++++++- src/renderer/src/store/runtime.ts | 9 +++++++-- 14 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 src/renderer/src/hooks/useRuntime.ts diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 4e3a32e2..b62c576e 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -1,3 +1,5 @@ +import path from 'node:path' + import { BrowserWindow, ipcMain, session, shell } from 'electron' import { appConfig, titleBarOverlayDark, titleBarOverlayLight } from './config' @@ -14,10 +16,11 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { const { autoUpdater } = new AppUpdater(mainWindow) // IPC - ipcMain.handle('get-app-info', () => ({ + ipcMain.handle('app:info', () => ({ version: app.getVersion(), isPackaged: app.isPackaged, - appPath: app.getAppPath() + appPath: app.getAppPath(), + filesPath: path.join(app.getPath('userData'), 'Data', 'Files') })) ipcMain.handle('open-website', (_, url: string) => { diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index 864e5ff0..358556ca 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -12,6 +12,7 @@ declare global { version: string isPackaged: boolean appPath: string + filesPath: string }> checkForUpdate: () => void openWebsite: (url: string) => void diff --git a/src/preload/index.ts b/src/preload/index.ts index 8a3b3d97..0057d26c 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -4,7 +4,7 @@ import { contextBridge, ipcRenderer, OpenDialogOptions } from 'electron' // Custom APIs for renderer const api = { - getAppInfo: () => ipcRenderer.invoke('get-app-info'), + getAppInfo: () => ipcRenderer.invoke('app:info'), checkForUpdate: () => ipcRenderer.invoke('check-for-update'), openWebsite: (url: string) => ipcRenderer.invoke('open-website', url), setProxy: (proxy: string) => ipcRenderer.invoke('set-proxy', proxy), diff --git a/src/renderer/src/components/app/Sidebar.tsx b/src/renderer/src/components/app/Sidebar.tsx index 27b02277..fad745e3 100644 --- a/src/renderer/src/components/app/Sidebar.tsx +++ b/src/renderer/src/components/app/Sidebar.tsx @@ -2,8 +2,8 @@ import { FileSearchOutlined, FolderOutlined, TranslationOutlined } from '@ant-de import { isMac } from '@renderer/config/constant' import { isLocalAi, UserAvatar } from '@renderer/config/env' import useAvatar from '@renderer/hooks/useAvatar' +import { useRuntime } from '@renderer/hooks/useRuntime' import { useSettings } from '@renderer/hooks/useSettings' -import { useRuntime } from '@renderer/hooks/useStore' import { Avatar } from 'antd' import { FC } from 'react' import { useTranslation } from 'react-i18next' diff --git a/src/renderer/src/hooks/useAppInit.ts b/src/renderer/src/hooks/useAppInit.ts index 9293ef64..fdd70f61 100644 --- a/src/renderer/src/hooks/useAppInit.ts +++ b/src/renderer/src/hooks/useAppInit.ts @@ -3,14 +3,14 @@ import { isLocalAi } from '@renderer/config/env' import db from '@renderer/databases' import i18n from '@renderer/i18n' import { useAppDispatch } from '@renderer/store' -import { setAvatar } from '@renderer/store/runtime' +import { setAvatar, setFilesPath } from '@renderer/store/runtime' import { runAsyncFunction } from '@renderer/utils' import { useLiveQuery } from 'dexie-react-hooks' import { useEffect } from 'react' import { useDefaultModel } from './useAssistant' +import { useRuntime } from './useRuntime' import { useSettings } from './useSettings' -import { useRuntime } from './useStore' export function useAppInit() { const dispatch = useAppDispatch() @@ -56,4 +56,11 @@ export function useAppInit() { } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) + + useEffect(() => { + // set files path + window.api.getAppInfo().then((info) => { + dispatch(setFilesPath(info.filesPath)) + }) + }, [dispatch]) } diff --git a/src/renderer/src/hooks/useRuntime.ts b/src/renderer/src/hooks/useRuntime.ts new file mode 100644 index 00000000..d7ed75bf --- /dev/null +++ b/src/renderer/src/hooks/useRuntime.ts @@ -0,0 +1,5 @@ +import { useAppSelector } from '@renderer/store' + +export function useRuntime() { + return useAppSelector((state) => state.runtime) +} diff --git a/src/renderer/src/hooks/useStore.ts b/src/renderer/src/hooks/useStore.ts index 6b148e3e..c5d5a416 100644 --- a/src/renderer/src/hooks/useStore.ts +++ b/src/renderer/src/hooks/useStore.ts @@ -21,7 +21,3 @@ export function useShowTopics() { toggleShowTopics: () => dispatch(toggleShowTopics()) } } - -export function useRuntime() { - return useAppSelector((state) => state.runtime) -} diff --git a/src/renderer/src/pages/files/FilesPage.tsx b/src/renderer/src/pages/files/FilesPage.tsx index a514ce13..fcfb0ab8 100644 --- a/src/renderer/src/pages/files/FilesPage.tsx +++ b/src/renderer/src/pages/files/FilesPage.tsx @@ -17,7 +17,8 @@ const FilesPage: FC = () => { const dataSource = files?.map((file) => { const isImage = file.type === FileTypes.IMAGE - const ImageView = + const ImageView = + console.log(FileManager.getFileUrl(file)) return { key: file.id, file: isImage ? ImageView : {file.origin_name}, diff --git a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx index 0c4eb8be..f700e720 100644 --- a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx +++ b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx @@ -11,8 +11,9 @@ import { documentExts, imageExts, textExts } from '@renderer/config/constant' import { isVisionModel } from '@renderer/config/models' import db from '@renderer/databases' import { useAssistant } from '@renderer/hooks/useAssistant' +import { useRuntime } from '@renderer/hooks/useRuntime' import { useSettings } from '@renderer/hooks/useSettings' -import { useRuntime, useShowTopics } from '@renderer/hooks/useStore' +import { useShowTopics } from '@renderer/hooks/useStore' import { addAssistantMessagesToTopic, getDefaultTopic } from '@renderer/services/assistant' import { EVENT_NAMES, EventEmitter } from '@renderer/services/event' import FileManager from '@renderer/services/file' diff --git a/src/renderer/src/pages/home/Messages/MessageAttachments.tsx b/src/renderer/src/pages/home/Messages/MessageAttachments.tsx index 0eef8b6f..8bcb5a89 100644 --- a/src/renderer/src/pages/home/Messages/MessageAttachments.tsx +++ b/src/renderer/src/pages/home/Messages/MessageAttachments.tsx @@ -16,7 +16,7 @@ const MessageAttachments: FC = ({ message }) => { if (message?.files && message.files[0]?.type === FileTypes.IMAGE) { return ( - {message.files?.map((image) => )} + {message.files?.map((image) => )} ) } diff --git a/src/renderer/src/pages/home/Messages/MessageTokens.tsx b/src/renderer/src/pages/home/Messages/MessageTokens.tsx index f893233d..21b53673 100644 --- a/src/renderer/src/pages/home/Messages/MessageTokens.tsx +++ b/src/renderer/src/pages/home/Messages/MessageTokens.tsx @@ -1,4 +1,4 @@ -import { useRuntime } from '@renderer/hooks/useStore' +import { useRuntime } from '@renderer/hooks/useRuntime' import { EVENT_NAMES, EventEmitter } from '@renderer/services/event' import { Message } from '@renderer/types' import styled from 'styled-components' diff --git a/src/renderer/src/pages/home/Messages/Messages.tsx b/src/renderer/src/pages/home/Messages/Messages.tsx index 11e3b223..f2248969 100644 --- a/src/renderer/src/pages/home/Messages/Messages.tsx +++ b/src/renderer/src/pages/home/Messages/Messages.tsx @@ -188,7 +188,7 @@ const Messages: FC = ({ assistant, topic, setActiveTopic }) => { useEffect(() => { scrollToBottom() - }, []) + }, [scrollToBottom]) const memoizedMessages = useMemo(() => reverse([...messages]), [messages]) diff --git a/src/renderer/src/services/file.ts b/src/renderer/src/services/file.ts index cb4eb610..a639a6a5 100644 --- a/src/renderer/src/services/file.ts +++ b/src/renderer/src/services/file.ts @@ -1,4 +1,5 @@ import db from '@renderer/databases' +import store from '@renderer/store' import { FileType } from '@renderer/types' import { getFileDirectory } from '@renderer/utils' @@ -27,7 +28,14 @@ class FileManager { } static async getFile(id: string): Promise { - return db.files.get(id) + const file = await db.files.get(id) + + if (file) { + const filesPath = store.getState().runtime.filesPath + file.path = filesPath + file.id + } + + return file } static async deleteFile(id: string): Promise { @@ -61,6 +69,11 @@ class FileManager { static getSafePath(file: FileType) { return this.isDangerFile(file) ? getFileDirectory(file.path) : file.path } + + static getFileUrl(file: FileType) { + const filesPath = store.getState().runtime.filesPath + return 'file://' + filesPath + '/' + file.id + file.ext + } } export default FileManager diff --git a/src/renderer/src/store/runtime.ts b/src/renderer/src/store/runtime.ts index d42c72e8..06eb72d3 100644 --- a/src/renderer/src/store/runtime.ts +++ b/src/renderer/src/store/runtime.ts @@ -6,13 +6,15 @@ export interface RuntimeState { generating: boolean minappShow: boolean searching: boolean + filesPath: string } const initialState: RuntimeState = { avatar: UserAvatar, generating: false, minappShow: false, - searching: false + searching: false, + filesPath: '' } const runtimeSlice = createSlice({ @@ -30,10 +32,13 @@ const runtimeSlice = createSlice({ }, setSearching: (state, action: PayloadAction) => { state.searching = action.payload + }, + setFilesPath: (state, action: PayloadAction) => { + state.filesPath = action.payload } } }) -export const { setAvatar, setGenerating, setMinappShow, setSearching } = runtimeSlice.actions +export const { setAvatar, setGenerating, setMinappShow, setSearching, setFilesPath } = runtimeSlice.actions export default runtimeSlice.reducer