add autoSync in WebDav
This commit is contained in:
parent
0739758469
commit
87c3716f75
@ -222,6 +222,7 @@
|
||||
"assistant.added.content": "Assistant added successfully",
|
||||
"backup.failed": "Backup failed",
|
||||
"backup.success": "Backup successful",
|
||||
"backup.start.success": "Backup started",
|
||||
"chat.completion.paused": "Chat completion paused",
|
||||
"copied": "Copied!",
|
||||
"error.enter.api.host": "Please enter your API host first",
|
||||
@ -363,6 +364,8 @@
|
||||
"webdav.password": "WebDAV Password",
|
||||
"webdav.path": "WebDAV Path",
|
||||
"webdav.path.placeholder": "/backup",
|
||||
"webdav.autoSync": "Auto Sync",
|
||||
"webdav.minutes": "Minutes",
|
||||
"webdav.restore.button": "Restore from WebDAV",
|
||||
"webdav.title": "WebDAV",
|
||||
"webdav.user": "WebDAV User"
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"assistant.added.content": "Ассистент успешно добавлен",
|
||||
"backup.failed": "Создание резервной копии не удалось",
|
||||
"backup.success": "Резервная копия успешно создана",
|
||||
"backup.start.success": "Создание резервной копии начато",
|
||||
"chat.completion.paused": "Завершение чата приостановлено",
|
||||
"copied": "Скопировано!",
|
||||
"error.enter.api.host": "Пожалуйста, введите ваш API хост",
|
||||
@ -363,6 +364,8 @@
|
||||
"webdav.password": "Пароль WebDAV",
|
||||
"webdav.path": "Путь WebDAV",
|
||||
"webdav.path.placeholder": "/backup",
|
||||
"webdav.autoSync": "Автоматическая синхронизация",
|
||||
"webdav.minutes": "минут",
|
||||
"webdav.restore.button": "Восстановление с WebDAV",
|
||||
"webdav.title": "WebDAV",
|
||||
"webdav.user": "Пользователь WebDAV"
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"assistant.added.content": "智能体添加成功",
|
||||
"backup.failed": "备份失败",
|
||||
"backup.success": "备份成功",
|
||||
"backup.start.success": "开始备份",
|
||||
"chat.completion.paused": "会话已停止",
|
||||
"copied": "已复制",
|
||||
"error.enter.api.host": "请输入您的 API 地址",
|
||||
@ -363,6 +364,8 @@
|
||||
"webdav.password": "WebDAV 密码",
|
||||
"webdav.path": "WebDAV 路径",
|
||||
"webdav.path.placeholder": "/backup",
|
||||
"webdav.autoSync": "自动同步",
|
||||
"webdav.minutes": "分钟",
|
||||
"webdav.restore.button": "从 WebDAV 恢复",
|
||||
"webdav.title": "WebDAV",
|
||||
"webdav.user": "WebDAV 用户名"
|
||||
@ -513,4 +516,4 @@
|
||||
"visualization": "可视化"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,6 +222,7 @@
|
||||
"assistant.added.content": "智能體添加成功",
|
||||
"backup.failed": "備份失敗",
|
||||
"backup.success": "備份成功",
|
||||
"backup.start.success": "開始備份",
|
||||
"chat.completion.paused": "聊天完成已暫停",
|
||||
"copied": "已複製",
|
||||
"error.enter.api.host": "請先輸入您的 API 主機地址",
|
||||
@ -363,6 +364,8 @@
|
||||
"webdav.password": "WebDAV 密碼",
|
||||
"webdav.path": "WebDAV Path",
|
||||
"webdav.path.placeholder": "/backup",
|
||||
"webdav.autoSync": "自動同步",
|
||||
"webdav.minutes": "分鐘",
|
||||
"webdav.restore.button": "從 WebDAV 恢復",
|
||||
"webdav.title": "WebDAV",
|
||||
"webdav.user": "WebDAV 使用者名稱"
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
import { FolderOpenOutlined, SaveOutlined } from '@ant-design/icons'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import { backupToWebdav, restoreFromWebdav } from '@renderer/services/BackupService'
|
||||
import { backupToWebdav, restoreFromWebdav, startAutoSync, stopAutoSync } from '@renderer/services/BackupService'
|
||||
import { useAppDispatch } from '@renderer/store'
|
||||
import {
|
||||
setWebdavAutoSync,
|
||||
setWebdavHost as _setWebdavHost,
|
||||
setWebdavPass as _setWebdavPass,
|
||||
setWebdavPath as _setWebdavPath,
|
||||
setWebdavSyncInterval as _setWebdavSyncInterval,
|
||||
setWebdavUser as _setWebdavUser
|
||||
} from '@renderer/store/settings'
|
||||
import { Button, Input } from 'antd'
|
||||
import { Button, Input, Select, Switch } from 'antd'
|
||||
import { FC, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
@ -20,7 +22,9 @@ const WebDavSettings: FC = () => {
|
||||
webdavHost: webDAVHost,
|
||||
webdavUser: webDAVUser,
|
||||
webdavPass: webDAVPass,
|
||||
webdavPath: webDAVPath
|
||||
webdavPath: webDAVPath,
|
||||
webdavAutoSync: webDAVAutoSync,
|
||||
webdavSyncInterval: webDAVSyncInterval
|
||||
} = useSettings()
|
||||
|
||||
const [webdavHost, setWebdavHost] = useState<string | undefined>(webDAVHost)
|
||||
@ -28,6 +32,9 @@ const WebDavSettings: FC = () => {
|
||||
const [webdavPass, setWebdavPass] = useState<string | undefined>(webDAVPass)
|
||||
const [webdavPath, setWebdavPath] = useState<string | undefined>(webDAVPath)
|
||||
|
||||
const [autoSync, setAutoSync] = useState<boolean>(webDAVAutoSync)
|
||||
const [syncInterval, setSyncInterval] = useState<number>(webDAVSyncInterval)
|
||||
|
||||
const [backuping, setBackuping] = useState(false)
|
||||
const [restoring, setRestoring] = useState(false)
|
||||
|
||||
@ -56,6 +63,19 @@ const WebDavSettings: FC = () => {
|
||||
await restoreFromWebdav()
|
||||
setRestoring(false)
|
||||
}
|
||||
const onToggleAutoSync = (checked: boolean) => {
|
||||
dispatch(setWebdavAutoSync(checked))
|
||||
|
||||
if (checked) {
|
||||
startAutoSync()
|
||||
} else {
|
||||
stopAutoSync()
|
||||
}
|
||||
}
|
||||
const onSyncIntervalChange = (value: number) => {
|
||||
setSyncInterval(value)
|
||||
dispatch(_setWebdavSyncInterval(value))
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -106,6 +126,32 @@ const WebDavSettings: FC = () => {
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitle>{t('settings.data.webdav.autoSync')}</SettingRowTitle>
|
||||
<HStack gap="10px" alignItems="center">
|
||||
<Switch
|
||||
checked={autoSync}
|
||||
onChange={(checked) => {
|
||||
setAutoSync(checked)
|
||||
onToggleAutoSync(checked)
|
||||
}}
|
||||
disabled={!webdavHost}
|
||||
/>
|
||||
<Select
|
||||
value={syncInterval}
|
||||
onChange={onSyncIntervalChange}
|
||||
disabled={!webdavHost || !autoSync}
|
||||
style={{ width: 120 }}>
|
||||
<Select.Option value={1}>1 {t('settings.data.webdav.minutes')}</Select.Option>
|
||||
<Select.Option value={5}>5 {t('settings.data.webdav.minutes')}</Select.Option>
|
||||
<Select.Option value={15}>15 {t('settings.data.webdav.minutes')}</Select.Option>
|
||||
<Select.Option value={30}>30 {t('settings.data.webdav.minutes')}</Select.Option>
|
||||
<Select.Option value={60}>60 {t('settings.data.webdav.minutes')}</Select.Option>
|
||||
<Select.Option value={120}>120 {t('settings.data.webdav.minutes')}</Select.Option>
|
||||
</Select>
|
||||
</HStack>
|
||||
</SettingRow>
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitle>{t('settings.general.backup.title')}</SettingRowTitle>
|
||||
<HStack gap="5px" justifyContent="space-between">
|
||||
|
||||
@ -108,6 +108,49 @@ export async function restoreFromWebdav() {
|
||||
}
|
||||
}
|
||||
|
||||
let syncInterval: NodeJS.Timeout | null = null
|
||||
export function startAutoSync() {
|
||||
const { webdavAutoSync, webdavHost, webdavSyncInterval } = store.getState().settings
|
||||
|
||||
if (syncInterval) {
|
||||
stopAutoSync()
|
||||
}
|
||||
|
||||
if (webdavAutoSync && webdavHost) {
|
||||
console.log('[AutoSync] Starting auto sync with interval:', webdavSyncInterval, 'minutes')
|
||||
|
||||
const performBackup = async () => {
|
||||
try {
|
||||
console.log('[AutoSync] Performing backup...')
|
||||
await backupToWebdav()
|
||||
window.message.success({
|
||||
content: i18n.t('message.backup.start.success'),
|
||||
key: 'webdav-sync'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[AutoSync] Backup failed:', error)
|
||||
window.message.error({
|
||||
content: i18n.t('message.backup.failed'),
|
||||
key: 'webdav-sync'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
performBackup()
|
||||
|
||||
syncInterval = setInterval(performBackup, webdavSyncInterval * 60 * 1000)
|
||||
console.log('[AutoSync] Sync interval set up:', syncInterval)
|
||||
}
|
||||
}
|
||||
|
||||
export function stopAutoSync() {
|
||||
if (syncInterval) {
|
||||
console.log('[AutoSync] Stopping auto sync')
|
||||
clearInterval(syncInterval)
|
||||
syncInterval = null
|
||||
}
|
||||
}
|
||||
|
||||
async function getBackupData() {
|
||||
return JSON.stringify({
|
||||
time: new Date().getTime(),
|
||||
|
||||
@ -36,6 +36,8 @@ export interface SettingsState {
|
||||
webdavUser: string
|
||||
webdavPass: string
|
||||
webdavPath: string
|
||||
webdavAutoSync: boolean
|
||||
webdavSyncInterval: number
|
||||
translateModelPrompt: string
|
||||
autoTranslateWithSpace: boolean
|
||||
enableTopicNaming: boolean
|
||||
@ -75,6 +77,8 @@ const initialState: SettingsState = {
|
||||
webdavUser: '',
|
||||
webdavPass: '',
|
||||
webdavPath: '/cherry-studio',
|
||||
webdavAutoSync: false,
|
||||
webdavSyncInterval: 5,
|
||||
translateModelPrompt: TRANSLATE_PROMPT,
|
||||
autoTranslateWithSpace: false,
|
||||
enableTopicNaming: true,
|
||||
@ -165,6 +169,12 @@ const settingsSlice = createSlice({
|
||||
setWebdavPath: (state, action: PayloadAction<string>) => {
|
||||
state.webdavPath = action.payload
|
||||
},
|
||||
setWebdavAutoSync: (state, action: PayloadAction<boolean>) => {
|
||||
state.webdavAutoSync = action.payload
|
||||
},
|
||||
setWebdavSyncInterval: (state, action: PayloadAction<number>) => {
|
||||
state.webdavSyncInterval = action.payload
|
||||
},
|
||||
setCodeShowLineNumbers: (state, action: PayloadAction<boolean>) => {
|
||||
state.codeShowLineNumbers = action.payload
|
||||
},
|
||||
@ -228,6 +238,8 @@ export const {
|
||||
setWebdavUser,
|
||||
setWebdavPass,
|
||||
setWebdavPath,
|
||||
setWebdavAutoSync,
|
||||
setWebdavSyncInterval,
|
||||
setCodeShowLineNumbers,
|
||||
setCodeCollapsible,
|
||||
setMathEngine,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user