Merge pull request #5035 from menloresearch/chore/data-folder
chore: show location data folder and ui for let user change folder
This commit is contained in:
commit
c4d32c72d1
@ -44,6 +44,7 @@ uuid = { version = "1.7", features = ["v4"] }
|
|||||||
env = "1.0.1"
|
env = "1.0.1"
|
||||||
futures-util = "0.3.31"
|
futures-util = "0.3.31"
|
||||||
tokio-util = "0.7.14"
|
tokio-util = "0.7.14"
|
||||||
|
tauri-plugin-dialog = "2.2.1"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||||
tauri-plugin-updater = "2"
|
tauri-plugin-updater = "2"
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
"core:window:allow-set-focus",
|
"core:window:allow-set-focus",
|
||||||
"os:default",
|
"os:default",
|
||||||
"log:default",
|
"log:default",
|
||||||
|
"dialog:default",
|
||||||
"core:webview:allow-create-webview-window",
|
"core:webview:allow-create-webview-window",
|
||||||
{
|
{
|
||||||
"identifier": "http:default",
|
"identifier": "http:default",
|
||||||
|
|||||||
@ -16,6 +16,7 @@ use reqwest::blocking::Client;
|
|||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_os::init())
|
.plugin(tauri_plugin_os::init())
|
||||||
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_http::init())
|
.plugin(tauri_plugin_http::init())
|
||||||
.plugin(tauri_plugin_store::Builder::new().build())
|
.plugin(tauri_plugin_store::Builder::new().build())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
"@tanstack/react-router": "^1.116.0",
|
"@tanstack/react-router": "^1.116.0",
|
||||||
"@tanstack/react-router-devtools": "^1.116.0",
|
"@tanstack/react-router-devtools": "^1.116.0",
|
||||||
"@tauri-apps/api": "^2.5.0",
|
"@tauri-apps/api": "^2.5.0",
|
||||||
|
"@tauri-apps/plugin-dialog": "^2.2.1",
|
||||||
"@tauri-apps/plugin-os": "^2.2.1",
|
"@tauri-apps/plugin-os": "^2.2.1",
|
||||||
"@types/react-syntax-highlighter": "^15.5.13",
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
|
|||||||
@ -8,6 +8,9 @@ import { Card, CardItem } from '@/containers/Card'
|
|||||||
import LanguageSwitcher from '@/containers/LanguageSwitcher'
|
import LanguageSwitcher from '@/containers/LanguageSwitcher'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useGeneralSetting } from '@/hooks/useGeneralSetting'
|
import { useGeneralSetting } from '@/hooks/useGeneralSetting'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogClose,
|
DialogClose,
|
||||||
@ -18,7 +21,8 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from '@/components/ui/dialog'
|
} from '@/components/ui/dialog'
|
||||||
import { factoryReset } from '@/services/app'
|
import { factoryReset, getJanDataFolder } from '@/services/app'
|
||||||
|
import { IconFolder } from '@tabler/icons-react'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export const Route = createFileRoute(route.settings.general as any)({
|
export const Route = createFileRoute(route.settings.general as any)({
|
||||||
@ -28,6 +32,16 @@ export const Route = createFileRoute(route.settings.general as any)({
|
|||||||
function General() {
|
function General() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { spellCheckChatInput, setSpellCheckChatInput } = useGeneralSetting()
|
const { spellCheckChatInput, setSpellCheckChatInput } = useGeneralSetting()
|
||||||
|
const [janDataFolder, setJanDataFolder] = useState<string | undefined>()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchDataFolder = async () => {
|
||||||
|
const path = await getJanDataFolder()
|
||||||
|
setJanDataFolder(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchDataFolder()
|
||||||
|
}, [])
|
||||||
|
|
||||||
const resetApp = async () => {
|
const resetApp = async () => {
|
||||||
// TODO: Loading indicator
|
// TODO: Loading indicator
|
||||||
@ -71,10 +85,47 @@ function General() {
|
|||||||
title={t('settings.dataFolder.appData', {
|
title={t('settings.dataFolder.appData', {
|
||||||
ns: 'settings',
|
ns: 'settings',
|
||||||
})}
|
})}
|
||||||
description={t('settings.dataFolder.appDataDesc', {
|
align="start"
|
||||||
ns: 'settings',
|
description={
|
||||||
})}
|
<>
|
||||||
actions={<></>}
|
<span>
|
||||||
|
{t('settings.dataFolder.appDataDesc', {
|
||||||
|
ns: 'settings',
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
title={janDataFolder}
|
||||||
|
className="bg-main-view-fg/10 text-xs mt-1 px-1 py-0.5 rounded-sm text-main-view-fg/80 line-clamp-1"
|
||||||
|
>
|
||||||
|
{janDataFolder}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
actions={
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
size="sm"
|
||||||
|
className="hover:no-underline"
|
||||||
|
onClick={async () => {
|
||||||
|
const selectedPath = await open({
|
||||||
|
multiple: false,
|
||||||
|
directory: true,
|
||||||
|
defaultPath: janDataFolder,
|
||||||
|
})
|
||||||
|
if (selectedPath === janDataFolder) return
|
||||||
|
if (selectedPath !== null) {
|
||||||
|
setJanDataFolder(selectedPath)
|
||||||
|
// TODO: we need function to move everything into new folder selectedPath
|
||||||
|
// eg like this
|
||||||
|
// await window.core?.api?.moveDataFolder(selectedPath)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="size-6 cursor-pointer flex items-center justify-center rounded hover:bg-main-view-fg/15 bg-main-view-fg/10 transition-all duration-200 ease-in-out">
|
||||||
|
<IconFolder size={18} className="text-main-view-fg/50" />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<CardItem
|
<CardItem
|
||||||
title={t('settings.dataFolder.appLogs', {
|
title={t('settings.dataFolder.appLogs', {
|
||||||
|
|||||||
@ -7,10 +7,7 @@ import { invoke } from '@tauri-apps/api/core'
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
export const factoryReset = async () => {
|
export const factoryReset = async () => {
|
||||||
const appConfiguration: AppConfiguration | undefined =
|
const janDataFolderPath = await getJanDataFolder()
|
||||||
await window.core?.api?.getAppConfigurations()
|
|
||||||
|
|
||||||
const janDataFolderPath = appConfiguration?.data_folder
|
|
||||||
if (janDataFolderPath) await fs.rm(janDataFolderPath)
|
if (janDataFolderPath) await fs.rm(janDataFolderPath)
|
||||||
window.localStorage.clear()
|
window.localStorage.clear()
|
||||||
await window.core?.api?.installExtensions()
|
await window.core?.api?.installExtensions()
|
||||||
@ -50,3 +47,20 @@ export const parseLogLine = (line: string) => {
|
|||||||
message,
|
message,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description This function is used to get the Jan data folder path.
|
||||||
|
* It retrieves the path from the app configuration.
|
||||||
|
* @returns {Promise<string | undefined>} The Jan data folder path or undefined if not found
|
||||||
|
*/
|
||||||
|
export const getJanDataFolder = async (): Promise<string | undefined> => {
|
||||||
|
try {
|
||||||
|
const appConfiguration: AppConfiguration | undefined =
|
||||||
|
await window.core?.api?.getAppConfigurations()
|
||||||
|
|
||||||
|
return appConfiguration?.data_folder
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to get Jan data folder:', error)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user