feat: change data folder (#3309)
This commit is contained in:
parent
b348110fb7
commit
b43242b9b2
@ -35,6 +35,9 @@ export enum NativeRoute {
|
|||||||
syncModelFileToCortex = 'syncModelFileToCortex',
|
syncModelFileToCortex = 'syncModelFileToCortex',
|
||||||
|
|
||||||
openAppLog = 'openAppLog',
|
openAppLog = 'openAppLog',
|
||||||
|
appDataFolder = 'appDataFolder',
|
||||||
|
changeDataFolder = 'changeDataFolder',
|
||||||
|
isDirectoryEmpty = 'isDirectoryEmpty',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AppEvent {
|
export enum AppEvent {
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
export type AppConfiguration = {
|
export type AppConfiguration = {
|
||||||
data_folder: string
|
dataFolderPath: string,
|
||||||
quick_ask: boolean
|
quickAsk: boolean,
|
||||||
|
cortexCppHost: string,
|
||||||
|
cortexCppPort: number,
|
||||||
|
apiServerHost: string,
|
||||||
|
apiServerPort: number,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,11 @@ import {
|
|||||||
NativeRoute,
|
NativeRoute,
|
||||||
SelectFileProp,
|
SelectFileProp,
|
||||||
SelectFileOption,
|
SelectFileOption,
|
||||||
|
AppConfiguration,
|
||||||
} from '@janhq/core/node'
|
} from '@janhq/core/node'
|
||||||
import { menu } from '../utils/menu'
|
import { menu } from '../utils/menu'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { getAppConfigurations, getJanDataFolderPath } from './../utils/path'
|
import { getAppConfigurations, getJanDataFolderPath, legacyDataPath, updateAppConfiguration } from './../utils/path'
|
||||||
import {
|
import {
|
||||||
readdirSync,
|
readdirSync,
|
||||||
writeFileSync,
|
writeFileSync,
|
||||||
@ -16,8 +17,7 @@ import {
|
|||||||
existsSync,
|
existsSync,
|
||||||
mkdirSync,
|
mkdirSync,
|
||||||
} from 'fs'
|
} from 'fs'
|
||||||
import { dump } from 'js-yaml'
|
import { dump, load } from 'js-yaml'
|
||||||
|
|
||||||
const isMac = process.platform === 'darwin'
|
const isMac = process.platform === 'darwin'
|
||||||
|
|
||||||
export function handleAppIPCs() {
|
export function handleAppIPCs() {
|
||||||
@ -209,7 +209,7 @@ export function handleAppIPCs() {
|
|||||||
|
|
||||||
ipcMain.handle(NativeRoute.openAppLog, async (_event): Promise<void> => {
|
ipcMain.handle(NativeRoute.openAppLog, async (_event): Promise<void> => {
|
||||||
const configuration = getAppConfigurations()
|
const configuration = getAppConfigurations()
|
||||||
const dataFolder = configuration.data_folder
|
const dataFolder = configuration.dataFolderPath
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const errorMessage = await shell.openPath(join(dataFolder))
|
const errorMessage = await shell.openPath(join(dataFolder))
|
||||||
@ -224,11 +224,14 @@ export function handleAppIPCs() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle(NativeRoute.syncModelFileToCortex, async (_event) => {
|
ipcMain.handle(NativeRoute.syncModelFileToCortex, async (_event) => {
|
||||||
const janModelFolderPath = join(getJanDataFolderPath(), 'models')
|
|
||||||
|
// Read models from legacy data folder
|
||||||
|
const janModelFolderPath = join(legacyDataPath(), 'models')
|
||||||
const allModelFolders = readdirSync(janModelFolderPath)
|
const allModelFolders = readdirSync(janModelFolderPath)
|
||||||
|
|
||||||
|
// Latest app configs
|
||||||
const configration = getAppConfigurations()
|
const configration = getAppConfigurations()
|
||||||
const destinationFolderPath = join(configration.data_folder, 'models')
|
const destinationFolderPath = join(configration.dataFolderPath, 'models')
|
||||||
|
|
||||||
if (!existsSync(destinationFolderPath)) mkdirSync(destinationFolderPath)
|
if (!existsSync(destinationFolderPath)) mkdirSync(destinationFolderPath)
|
||||||
|
|
||||||
@ -332,7 +335,7 @@ export function handleAppIPCs() {
|
|||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
NativeRoute.getAllMessagesAndThreads,
|
NativeRoute.getAllMessagesAndThreads,
|
||||||
async (_event): Promise<any> => {
|
async (_event): Promise<any> => {
|
||||||
const janThreadFolderPath = join(getJanDataFolderPath(), 'threads')
|
const janThreadFolderPath = join(legacyDataPath(), 'threads')
|
||||||
// check if exist
|
// check if exist
|
||||||
if (!existsSync(janThreadFolderPath)) {
|
if (!existsSync(janThreadFolderPath)) {
|
||||||
return {
|
return {
|
||||||
@ -382,7 +385,7 @@ export function handleAppIPCs() {
|
|||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
NativeRoute.getAllLocalModels,
|
NativeRoute.getAllLocalModels,
|
||||||
async (_event): Promise<boolean> => {
|
async (_event): Promise<boolean> => {
|
||||||
const janModelsFolderPath = join(getJanDataFolderPath(), 'models')
|
const janModelsFolderPath = join(legacyDataPath(), 'models')
|
||||||
|
|
||||||
if (!existsSync(janModelsFolderPath)) {
|
if (!existsSync(janModelsFolderPath)) {
|
||||||
console.debug('No local models found')
|
console.debug('No local models found')
|
||||||
@ -408,4 +411,50 @@ export function handleAppIPCs() {
|
|||||||
return hasLocalModels
|
return hasLocalModels
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
ipcMain.handle(NativeRoute.appDataFolder, () => {
|
||||||
|
return getJanDataFolderPath()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle(NativeRoute.changeDataFolder, async (_event, path) => {
|
||||||
|
const appConfiguration: AppConfiguration = getAppConfigurations()
|
||||||
|
const currentJanDataFolder = appConfiguration.dataFolderPath
|
||||||
|
|
||||||
|
appConfiguration.dataFolderPath = 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate models
|
||||||
|
const janModelsPath = join(path, 'models')
|
||||||
|
if (existsSync(janModelsPath)) {
|
||||||
|
const modelYamls = readdirSync(janModelsPath).filter((x) =>
|
||||||
|
x.endsWith('.yaml') || x.endsWith('.yml')
|
||||||
|
)
|
||||||
|
for(const yaml of modelYamls) {
|
||||||
|
const modelPath = join(janModelsPath, yaml)
|
||||||
|
const model = load(readFileSync(modelPath, 'utf-8')) as any
|
||||||
|
if('files' in model && Array.isArray(model.files) && model.files.length > 0) {
|
||||||
|
model.files[0] = model.files[0].replace(currentJanDataFolder, path)
|
||||||
|
}
|
||||||
|
writeFileSync(modelPath, dump(model))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await updateAppConfiguration(appConfiguration)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle(NativeRoute.isDirectoryEmpty, async (_event, path) => {
|
||||||
|
const dirChildren = readdirSync(path)
|
||||||
|
return dirChildren.filter((x) => x !== '.DS_Store').length === 0
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,7 @@ app
|
|||||||
.then(() => killProcessesOnPort(cortexJsPort))
|
.then(() => killProcessesOnPort(cortexJsPort))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const appConfiguration = getAppConfigurations()
|
const appConfiguration = getAppConfigurations()
|
||||||
const janDataFolder = appConfiguration.data_folder
|
const janDataFolder = appConfiguration.dataFolderPath
|
||||||
|
|
||||||
start('jan', host, cortexJsPort, cortexCppPort, janDataFolder)
|
start('jan', host, cortexJsPort, cortexCppPort, janDataFolder)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -8,7 +8,7 @@ class TrayManager {
|
|||||||
|
|
||||||
createSystemTray = () => {
|
createSystemTray = () => {
|
||||||
// Feature Toggle for Quick Ask
|
// Feature Toggle for Quick Ask
|
||||||
if (!getAppConfigurations().quick_ask) return
|
if (!getAppConfigurations().quickAsk) return
|
||||||
|
|
||||||
if (this.currentTray) {
|
if (this.currentTray) {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -73,7 +73,7 @@ class WindowManager {
|
|||||||
|
|
||||||
windowManager.mainWindow?.on('close', function (evt) {
|
windowManager.mainWindow?.on('close', function (evt) {
|
||||||
// Feature Toggle for Quick Ask
|
// Feature Toggle for Quick Ask
|
||||||
if (!getAppConfigurations().quick_ask) return
|
if (!getAppConfigurations().quickAsk) return
|
||||||
|
|
||||||
if (!isAppQuitting) {
|
if (!isAppQuitting) {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
|
|||||||
@ -3,9 +3,8 @@
|
|||||||
* @module preload
|
* @module preload
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { APIEvents, APIRoutes, AppConfiguration } from '@janhq/core/node'
|
import { APIEvents, APIRoutes } from '@janhq/core/node'
|
||||||
import { contextBridge, ipcRenderer } from 'electron'
|
import { contextBridge, ipcRenderer } from 'electron'
|
||||||
import { readdirSync } from 'fs'
|
|
||||||
|
|
||||||
const interfaces: { [key: string]: (...args: any[]) => any } = {}
|
const interfaces: { [key: string]: (...args: any[]) => any } = {}
|
||||||
|
|
||||||
@ -25,32 +24,7 @@ APIEvents.forEach((method) => {
|
|||||||
interfaces[method] = (handler: any) => ipcRenderer.on(method, handler)
|
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'
|
// Expose the 'interfaces' object in the main world under the name 'electronAPI'
|
||||||
// This allows the renderer process to access these methods directly
|
// This allows the renderer process to access these methods directly
|
||||||
|
|||||||
@ -3,14 +3,19 @@ import { existsSync, writeFileSync, readFileSync } from 'fs'
|
|||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { AppConfiguration } from '@janhq/core/node'
|
import { AppConfiguration } from '@janhq/core/node'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
|
import { dump, load } from 'js-yaml'
|
||||||
|
|
||||||
const configurationFileName = 'settings.json'
|
const configurationFileName = '.janrc'
|
||||||
|
|
||||||
const defaultJanDataFolder = join(os.homedir(), 'jan')
|
const defaultJanDataFolder = join(os.homedir(), 'jan')
|
||||||
|
|
||||||
const defaultAppConfig: AppConfiguration = {
|
const defaultAppConfig: AppConfiguration = {
|
||||||
data_folder: defaultJanDataFolder,
|
dataFolderPath: defaultJanDataFolder,
|
||||||
quick_ask: false,
|
quickAsk: true,
|
||||||
|
cortexCppHost: '127.0.0.1',
|
||||||
|
cortexCppPort: 3940,
|
||||||
|
apiServerHost: '127.0.0.1',
|
||||||
|
apiServerPort: 1338
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createUserSpace(): Promise<void> {
|
export async function createUserSpace(): Promise<void> {
|
||||||
@ -66,15 +71,14 @@ export const getAppConfigurations = (): AppConfiguration => {
|
|||||||
console.debug(
|
console.debug(
|
||||||
`App config not found, creating default config at ${configurationFile}`
|
`App config not found, creating default config at ${configurationFile}`
|
||||||
)
|
)
|
||||||
writeFileSync(configurationFile, JSON.stringify(defaultAppConfig))
|
writeFileSync(configurationFile, dump(defaultAppConfig))
|
||||||
return defaultAppConfig
|
return defaultAppConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const appConfigurations: AppConfiguration = JSON.parse(
|
const configYaml = readFileSync(configurationFile, 'utf-8')
|
||||||
readFileSync(configurationFile, 'utf-8')
|
const appConfigurations = load(configYaml) as AppConfiguration
|
||||||
)
|
console.debug('app config', appConfigurations)
|
||||||
console.debug('app config', JSON.stringify(appConfigurations))
|
|
||||||
return appConfigurations
|
return appConfigurations
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
@ -84,12 +88,15 @@ export const getAppConfigurations = (): AppConfiguration => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getConfigurationFilePath = () =>
|
// Get configuration file path of the application
|
||||||
join(
|
const getConfigurationFilePath = () => {
|
||||||
global.core?.appPath() ||
|
const homeDir = os.homedir();
|
||||||
process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME'],
|
const configPath = join(
|
||||||
configurationFileName
|
homeDir,
|
||||||
)
|
configurationFileName,
|
||||||
|
);
|
||||||
|
return configPath
|
||||||
|
}
|
||||||
|
|
||||||
export const updateAppConfiguration = (
|
export const updateAppConfiguration = (
|
||||||
configuration: AppConfiguration
|
configuration: AppConfiguration
|
||||||
@ -100,7 +107,7 @@ export const updateAppConfiguration = (
|
|||||||
configurationFile
|
configurationFile
|
||||||
)
|
)
|
||||||
|
|
||||||
writeFileSync(configurationFile, JSON.stringify(configuration))
|
writeFileSync(configurationFile, dump(configuration))
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +117,21 @@ export const updateAppConfiguration = (
|
|||||||
* @returns {string} The data folder path.
|
* @returns {string} The data folder path.
|
||||||
*/
|
*/
|
||||||
export const getJanDataFolderPath = (): string => {
|
export const getJanDataFolderPath = (): string => {
|
||||||
const appConfigurations = getAppConfigurations()
|
return getAppConfigurations().dataFolderPath
|
||||||
return appConfigurations.data_folder
|
}
|
||||||
|
|
||||||
|
// This is to support pulling legacy configs for migration purpose
|
||||||
|
export const legacyConfigs = () => {
|
||||||
|
const legacyConfigFilePath = join(
|
||||||
|
process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME'] ?? '',
|
||||||
|
'settings.json'
|
||||||
|
)
|
||||||
|
const legacyConfigs = JSON.parse(readFileSync(legacyConfigFilePath, 'utf-8')) as any
|
||||||
|
|
||||||
|
return legacyConfigs
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is to support pulling legacy data path for migration purpose
|
||||||
|
export const legacyDataPath = () => {
|
||||||
|
return legacyConfigs().data_path
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { windowManager } from '../managers/window'
|
|||||||
const quickAskHotKey = 'CommandOrControl+J'
|
const quickAskHotKey = 'CommandOrControl+J'
|
||||||
|
|
||||||
export function registerGlobalShortcuts() {
|
export function registerGlobalShortcuts() {
|
||||||
if (!getAppConfigurations().quick_ask) return
|
if (!getAppConfigurations().quickAsk) return
|
||||||
const ret = registerShortcut(quickAskHotKey, (selectedText: string) => {
|
const ret = registerShortcut(quickAskHotKey, (selectedText: string) => {
|
||||||
// Feature Toggle for Quick Ask
|
// Feature Toggle for Quick Ask
|
||||||
if (!windowManager.isQuickAskWindowVisible()) {
|
if (!windowManager.isQuickAskWindowVisible()) {
|
||||||
|
|||||||
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
import { AppConfiguration } from '@janhq/core'
|
|
||||||
|
|
||||||
import { useSetAtom } from 'jotai'
|
import { useSetAtom } from 'jotai'
|
||||||
|
|
||||||
import ClipboardListener from '@/containers/Providers/ClipboardListener'
|
import ClipboardListener from '@/containers/Providers/ClipboardListener'
|
||||||
@ -29,11 +27,9 @@ export default function RootLayout() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.core?.api
|
window.electronAPI?.appDataFolder()?.then((path: string) => {
|
||||||
?.getAppConfigurations()
|
setJanDataFolderPath(path)
|
||||||
?.then((appConfig: AppConfiguration) => {
|
})
|
||||||
setJanDataFolderPath(appConfig.data_folder)
|
|
||||||
})
|
|
||||||
}, [setJanDataFolderPath])
|
}, [setJanDataFolderPath])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import { Fragment, useCallback, useState } from 'react'
|
import { isAbsolute, relative } from 'path'
|
||||||
|
|
||||||
|
import { Fragment, useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { Button, Input } from '@janhq/joi'
|
import { Button, Input } from '@janhq/joi'
|
||||||
import { useAtomValue, useSetAtom } from 'jotai'
|
import { useAtom, useSetAtom } from 'jotai'
|
||||||
import { PencilIcon, FolderOpenIcon } from 'lucide-react'
|
import { PencilIcon, FolderOpenIcon } from 'lucide-react'
|
||||||
|
|
||||||
import Loader from '@/containers/Loader'
|
import Loader from '@/containers/Loader'
|
||||||
@ -29,8 +31,18 @@ const DataFolder = () => {
|
|||||||
const setShowChangeFolderError = useSetAtom(showChangeFolderErrorAtom)
|
const setShowChangeFolderError = useSetAtom(showChangeFolderErrorAtom)
|
||||||
const showDestNotEmptyConfirm = useSetAtom(showDestNotEmptyConfirmAtom)
|
const showDestNotEmptyConfirm = useSetAtom(showDestNotEmptyConfirmAtom)
|
||||||
|
|
||||||
|
const [janDataFolderPath, setJanDataFolderPath] = useAtom(
|
||||||
|
janDataFolderPathAtom
|
||||||
|
)
|
||||||
|
const getAppDataFolder = useCallback(async () => {
|
||||||
|
return window.electronAPI?.appDataFolder().then(setJanDataFolderPath)
|
||||||
|
}, [setJanDataFolderPath])
|
||||||
|
|
||||||
const [destinationPath, setDestinationPath] = useState(undefined)
|
const [destinationPath, setDestinationPath] = useState(undefined)
|
||||||
const janDataFolderPath = useAtomValue(janDataFolderPathAtom)
|
|
||||||
|
useEffect(() => {
|
||||||
|
getAppDataFolder()
|
||||||
|
}, [getAppDataFolder])
|
||||||
|
|
||||||
const onChangeFolderClick = useCallback(async () => {
|
const onChangeFolderClick = useCallback(async () => {
|
||||||
const destFolder = await window.core?.api?.selectDirectory()
|
const destFolder = await window.core?.api?.selectDirectory()
|
||||||
@ -41,14 +53,18 @@ const DataFolder = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// const appConfiguration: AppConfiguration =
|
const currentJanDataFolder = await window.electronAPI?.appDataFolder()
|
||||||
// await window.core?.api?.getAppConfigurations()
|
|
||||||
// const currentJanDataFolder = appConfiguration.data_folder
|
|
||||||
|
|
||||||
// if (await isSubdirectory(currentJanDataFolder, destFolder)) {
|
const relativePath = relative(currentJanDataFolder, destFolder)
|
||||||
// setShowSameDirectory(true)
|
|
||||||
// return
|
if (
|
||||||
// }
|
relativePath &&
|
||||||
|
!relativePath.startsWith('..') &&
|
||||||
|
!isAbsolute(relativePath)
|
||||||
|
) {
|
||||||
|
setShowSameDirectory(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const isEmpty: boolean =
|
const isEmpty: boolean =
|
||||||
await window.core?.api?.isDirectoryEmpty(destFolder)
|
await window.core?.api?.isDirectoryEmpty(destFolder)
|
||||||
@ -106,7 +122,9 @@ const DataFolder = () => {
|
|||||||
<FolderOpenIcon
|
<FolderOpenIcon
|
||||||
size={16}
|
size={16}
|
||||||
className="absolute right-2 top-1/2 z-10 -translate-y-1/2 cursor-pointer"
|
className="absolute right-2 top-1/2 z-10 -translate-y-1/2 cursor-pointer"
|
||||||
onClick={() => window.core?.api?.openAppDirectory()}
|
onClick={() =>
|
||||||
|
window.electronAPI?.openFileExplorer(janDataFolderPath)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { toaster } from '@/containers/Toast'
|
|||||||
import useModelStop from '@/hooks/useModelStop'
|
import useModelStop from '@/hooks/useModelStop'
|
||||||
import { useSettings } from '@/hooks/useSettings'
|
import { useSettings } from '@/hooks/useSettings'
|
||||||
|
|
||||||
|
import DataFolder from './DataFolder'
|
||||||
import CopyOverInstructionItem from './components/CopyOverInstruction'
|
import CopyOverInstructionItem from './components/CopyOverInstruction'
|
||||||
|
|
||||||
import DataMigration from './components/DataMigration'
|
import DataMigration from './components/DataMigration'
|
||||||
@ -79,7 +80,7 @@ const Advanced = () => {
|
|||||||
) => {
|
) => {
|
||||||
const appConfiguration: AppConfiguration =
|
const appConfiguration: AppConfiguration =
|
||||||
await window.core?.api?.getAppConfigurations()
|
await window.core?.api?.getAppConfigurations()
|
||||||
appConfiguration.quick_ask = e
|
appConfiguration.quickAsk = e
|
||||||
await window.core?.api?.updateAppConfiguration(appConfiguration)
|
await window.core?.api?.updateAppConfiguration(appConfiguration)
|
||||||
if (relaunch) window.core?.api?.relaunch()
|
if (relaunch) window.core?.api?.relaunch()
|
||||||
}
|
}
|
||||||
@ -365,7 +366,7 @@ const Advanced = () => {
|
|||||||
{/* </div> */}
|
{/* </div> */}
|
||||||
{/* )} */}
|
{/* )} */}
|
||||||
|
|
||||||
{/* <DataFolder /> */}
|
<DataFolder />
|
||||||
|
|
||||||
{/* Proxy */}
|
{/* Proxy */}
|
||||||
<div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
|
<div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user