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