diff --git a/messages/en.json b/messages/en.json index 005c4f7e..c2ff7b34 100644 --- a/messages/en.json +++ b/messages/en.json @@ -303,6 +303,7 @@ "description": "WebDAV is only used as a backup solution and does not support auto-sync, history rollback, and other features.", "backupTo": "Backup to WebDAV", "syncFrom": "Sync from WebDAV", + "testConnection": "Test Connection", "serverUrl": "WebDAV Server URL", "serverUrlDesc": "Enter the URL of the WebDAV server No path included, e.g: https://dav.example.com http://192.8.8.88:9999", "serverUrlPlaceholder": "https://dav.example.com", @@ -327,6 +328,7 @@ "success": "Success", "failed": "Failed", "error": { + "testFailed": "Connection test failed", "pathNotFound": "Path not found or server inaccessible.", "createDirFailed": "Failed to create directory", "connectionTimeOut": "Connection timed out, please check network or server." diff --git a/messages/ja.json b/messages/ja.json index c4d6ccac..1e7e0a13 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -301,6 +301,7 @@ "description": "WebDAVはバックアップソリューションとしてのみ使用され、自動同期や履歴ロールバックなどの機能はサポートしていません。", "backupTo": "WebDAVにバックアップ", "syncFrom": "WebDAVから同期", + "testConnection": "接続テスト", "serverUrl": "WebDAVサーバーURL", "serverUrlDesc": "WebDAVサーバーのURLを入力してくださいパスを含まない、例:https://dav.example.com http://192.8.8.88:9999 ", "serverUrlPlaceholder": "https://dav.example.com", @@ -325,6 +326,7 @@ "success": "成功", "failed": "失敗", "error": { + "testFailed": "接続テストに失敗しました", "pathNotFound": "パスが存在しないか、サーバーにアクセスできません。", "createDirFailed": "ディレクトリの作成に失敗しました", "connectionTimeOut": "接続タイムアウト、ネットワークまたはサーバーを確認してください。" diff --git a/messages/zh.json b/messages/zh.json index 7b9e2de7..e9b44401 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -295,6 +295,7 @@ "description": "WebDAV 仅作为备用备份方案,不支持自动同步、历史回滚等功能。", "backupTo": "备份至 WebDAV", "syncFrom": "从 WebDAV 同步", + "testConnection": "测试连接", "serverUrl": "WebDAV 服务器地址", "serverUrlDesc": "输入WebDAV服务器的URL不含路径,例如:https://dav.example.com http://192.8.8.88:9999 ", "serverUrlPlaceholder": "https://dav.example.com", @@ -319,6 +320,7 @@ "success": "成功", "failed": "失败", "error": { + "testFailed": "连接测试失败", "pathNotFound": "路径不存在或服务器无法访问。", "createDirFailed": "创建目录失败", "connectionTimeOut": "连接超时,请检查网络或服务器。" diff --git a/src/app/core/setting/ai/check.tsx b/src/app/core/setting/ai/check.tsx index 65810e84..34aed412 100644 --- a/src/app/core/setting/ai/check.tsx +++ b/src/app/core/setting/ai/check.tsx @@ -12,7 +12,7 @@ import { debounce } from "lodash-es" // 检测当前 AI 的可用性 export function AiCheck() { const [state, setState] = useState<'ok' | 'error' | 'checking' | 'init'>('init') - const { currentAi, aiModelList } = useSettingStore() + const { currentAi, aiModelList, aiAutoCheck } = useSettingStore() const t = useTranslations('settings.ai') const abortControllerRef = useRef(null) const debouncedCheckRef = useRef | null>(null) @@ -171,12 +171,16 @@ export function AiCheck() { useEffect(() => { const model = aiModelList.find(item => item.key === currentAi) + if (!aiAutoCheck) { + setState('init') + return + } if (model?.model) { debouncedCheckRef.current?.() } else { setState('init') } - }, [aiModelList, currentAi]) + }, [aiModelList, currentAi, aiAutoCheck]) // 组件卸载时清理资源 useEffect(() => { diff --git a/src/app/core/setting/ai/page.tsx b/src/app/core/setting/ai/page.tsx index 1f4e0548..693a0151 100644 --- a/src/app/core/setting/ai/page.tsx +++ b/src/app/core/setting/ai/page.tsx @@ -21,6 +21,7 @@ import { v4 } from 'uuid'; import { confirm } from '@tauri-apps/plugin-dialog'; import { AiCheck } from "./check"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import { Switch } from "@/components/ui/switch"; import { Label } from "@/components/ui/label"; import CreateConfig from "./create"; import { Badge } from "@/components/ui/badge"; @@ -34,7 +35,9 @@ export default function AiPage() { currentAi, setCurrentAi, aiModelList, - setAiModelList + setAiModelList, + aiAutoCheck, + setAiAutoCheck } = useSettingStore() const [apiKey, setApiKey] = useState('') const [baseURL, setBaseURL] = useState('') @@ -256,6 +259,15 @@ export default function AiPage() { + {/* 自动连通性检测开关 */} + + +
+ setAiAutoCheck(!!v)} /> + {aiAutoCheck ? t('enabled', { default: '已开启' }) : t('disabled', { default: '已关闭' })} +
+
+
{/* 模型名称 */} diff --git a/src/app/core/setting/backupSync/webdav-sync.tsx b/src/app/core/setting/backupSync/webdav-sync.tsx index 8388fc1c..4bf74a09 100644 --- a/src/app/core/setting/backupSync/webdav-sync.tsx +++ b/src/app/core/setting/backupSync/webdav-sync.tsx @@ -24,6 +24,7 @@ export default function WebdavSync() { syncState, backupState, createWebDAVDir, + testConnection, } = useWebDAVStore(); const { loadFileTree } = useArticleStore() @@ -108,6 +109,15 @@ export default function WebdavSync() { const [isCreating, setIsCreating] = useState(false); + const handleTestConnection = async () => { + const ok = await testConnection(); + if (ok) { + toast({ title: t("success"), description: t("connectionState.success") }); + } else { + toast({ variant: "destructive", title: t("error.testFailed", { default: "Test failed" } as any), description: t("error.connectionTimeOut") }); + } + }; + const handleCreateDirectory = async () => { if (!path.trim()) { toast({ @@ -158,6 +168,21 @@ export default function WebdavSync() { > {t(`connectionState.${connectionState}`)} + {t("description")} diff --git a/src/stores/setting.ts b/src/stores/setting.ts index ed3cd762..0d47dffe 100644 --- a/src/stores/setting.ts +++ b/src/stores/setting.ts @@ -79,6 +79,10 @@ interface SettingState { tesseractList: string setTesseractList: (tesseractList: string) => void + // AI 设置 - 自动连通性检测 + aiAutoCheck: boolean + setAiAutoCheck: (aiAutoCheck: boolean) => Promise + // Github 相关设置 githubUsername: string setGithubUsername: (githubUsername: string) => Promise @@ -281,6 +285,15 @@ const useSettingStore = create((set, get) => ({ tesseractList: 'eng,chi_sim', setTesseractList: (tesseractList) => set({ tesseractList }), + // AI 设置 - 自动连通性检测(默认开启) + aiAutoCheck: true, + setAiAutoCheck: async (aiAutoCheck: boolean) => { + const store = await Store.load('store.json'); + await store.set('aiAutoCheck', aiAutoCheck) + await store.save() + set({ aiAutoCheck }) + }, + githubUsername: '', setGithubUsername: async (githubUsername) => { set({ githubUsername }) diff --git a/src/stores/webdav.ts b/src/stores/webdav.ts index 728e934a..e71b7d0b 100644 --- a/src/stores/webdav.ts +++ b/src/stores/webdav.ts @@ -1,5 +1,4 @@ import { create } from 'zustand' -import { Store } from '@tauri-apps/plugin-store' import { invoke } from '@tauri-apps/api/core' export enum WebDAVConnectionState { @@ -37,18 +36,6 @@ interface WebDAVState { syncFromWebDAV: () => Promise } -// 防抖函数 -function simpleDebounce any>( - func: T, - wait: number -): (...args: Parameters) => void { - let timeout: NodeJS.Timeout | null = null - - return (...args: Parameters) => { - if (timeout) clearTimeout(timeout) - timeout = setTimeout(() => func(...args), wait) - } -} const useWebDAVStore = create((set, get) => { let isTestingInProgress = false @@ -101,56 +88,25 @@ const useWebDAVStore = create((set, get) => { } } - // 使用防抖 - const debouncedTest = simpleDebounce(performConnectionTest, 300) - return { url: '', setUrl: async (url: string) => { set({ url }) - try { - const store = await Store.load('store.json') - await store.set('webdavUrl', url) - } catch (error) { - console.error('Failed to save URL:', error) - } - debouncedTest() }, username: '', setUsername: async (username: string) => { set({ username }) - try { - const store = await Store.load('store.json') - await store.set('webdavUsername', username) - } catch (error) { - console.error('Failed to save username:', error) - } - debouncedTest() }, password: '', setPassword: async (password: string) => { set({ password }) - try { - const store = await Store.load('store.json') - await store.set('webdavPassword', password) - } catch (error) { - console.error('Failed to save password:', error) - } - debouncedTest() }, path: '', setPath: async (path: string) => { set({ path }) - try { - const store = await Store.load('store.json') - await store.set('webdavPath', path) - } catch (error) { - console.error('Failed to save path:', error) - } - debouncedTest() }, connectionState: WebDAVConnectionState.fail, @@ -163,21 +119,8 @@ const useWebDAVStore = create((set, get) => { }, initWebDAVData: async () => { - try { - const store = await Store.load('store.json') - const url = await store.get('webdavUrl') || '' - const username = await store.get('webdavUsername') || '' - const password = await store.get('webdavPassword') || '' - const path = await store.get('webdavPath') || '' - - set({ url, username, password, path }) - - if (url && username && password) { - setTimeout(() => performConnectionTest(), 100) - } - } catch (error) { - console.error('Failed to load WebDAV data:', error) - } + // 不再从本地存储加载连接参数,也不做自动连测 + set({ url: '', username: '', password: '', path: '' }) }, backupState: false,