mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 23:10:20 +08:00
chore(WebDav): remove useless webdav restore (#7347)
- remove webdav restore modal - fix i18n keys
This commit is contained in:
parent
23e9184323
commit
115470fce6
@ -1,16 +1,9 @@
|
|||||||
import { backupToWebdav, restoreFromWebdav } from '@renderer/services/BackupService'
|
import { backupToWebdav } from '@renderer/services/BackupService'
|
||||||
import { formatFileSize } from '@renderer/utils'
|
import { Input, Modal } from 'antd'
|
||||||
import { Input, Modal, Select, Spin } from 'antd'
|
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { useCallback, useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
interface BackupFile {
|
|
||||||
fileName: string
|
|
||||||
modifiedTime: string
|
|
||||||
size: number
|
|
||||||
}
|
|
||||||
|
|
||||||
interface WebdavModalProps {
|
interface WebdavModalProps {
|
||||||
isModalVisible: boolean
|
isModalVisible: boolean
|
||||||
handleBackup: () => void
|
handleBackup: () => void
|
||||||
@ -87,156 +80,3 @@ export function WebdavBackupModal({
|
|||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WebdavRestoreModalProps {
|
|
||||||
isRestoreModalVisible: boolean
|
|
||||||
handleRestore: () => void
|
|
||||||
handleCancel: () => void
|
|
||||||
restoring: boolean
|
|
||||||
selectedFile: string | null
|
|
||||||
setSelectedFile: (value: string | null) => void
|
|
||||||
loadingFiles: boolean
|
|
||||||
backupFiles: BackupFile[]
|
|
||||||
}
|
|
||||||
|
|
||||||
interface UseWebdavRestoreModalProps {
|
|
||||||
webdavHost: string | undefined
|
|
||||||
webdavUser: string | undefined
|
|
||||||
webdavPass: string | undefined
|
|
||||||
webdavPath: string | undefined
|
|
||||||
restoreMethod?: typeof restoreFromWebdav
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useWebdavRestoreModal({
|
|
||||||
webdavHost,
|
|
||||||
webdavUser,
|
|
||||||
webdavPass,
|
|
||||||
webdavPath,
|
|
||||||
restoreMethod
|
|
||||||
}: UseWebdavRestoreModalProps) {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const [isRestoreModalVisible, setIsRestoreModalVisible] = useState(false)
|
|
||||||
const [restoring, setRestoring] = useState(false)
|
|
||||||
const [selectedFile, setSelectedFile] = useState<string | null>(null)
|
|
||||||
const [loadingFiles, setLoadingFiles] = useState(false)
|
|
||||||
const [backupFiles, setBackupFiles] = useState<BackupFile[]>([])
|
|
||||||
|
|
||||||
const showRestoreModal = useCallback(async () => {
|
|
||||||
if (!webdavHost) {
|
|
||||||
window.message.error({ content: t('message.error.invalid.webdav'), key: 'webdav-error' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsRestoreModalVisible(true)
|
|
||||||
setLoadingFiles(true)
|
|
||||||
try {
|
|
||||||
const files = await window.api.backup.listWebdavFiles({
|
|
||||||
webdavHost,
|
|
||||||
webdavUser,
|
|
||||||
webdavPass,
|
|
||||||
webdavPath
|
|
||||||
})
|
|
||||||
setBackupFiles(files)
|
|
||||||
} catch (error: any) {
|
|
||||||
window.message.error({ content: error.message, key: 'list-files-error' })
|
|
||||||
} finally {
|
|
||||||
setLoadingFiles(false)
|
|
||||||
}
|
|
||||||
}, [webdavHost, webdavUser, webdavPass, webdavPath, t])
|
|
||||||
|
|
||||||
const handleRestore = useCallback(async () => {
|
|
||||||
if (!selectedFile || !webdavHost) {
|
|
||||||
window.message.error({
|
|
||||||
content: !selectedFile ? t('message.error.no.file.selected') : t('message.error.invalid.webdav'),
|
|
||||||
key: 'restore-error'
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
window.modal.confirm({
|
|
||||||
title: t('settings.data.webdav.restore.confirm.title'),
|
|
||||||
content: t('settings.data.webdav.restore.confirm.content'),
|
|
||||||
centered: true,
|
|
||||||
onOk: async () => {
|
|
||||||
setRestoring(true)
|
|
||||||
try {
|
|
||||||
await (restoreMethod ?? restoreFromWebdav)(selectedFile)
|
|
||||||
setIsRestoreModalVisible(false)
|
|
||||||
} catch (error: any) {
|
|
||||||
window.message.error({ content: error.message, key: 'restore-error' })
|
|
||||||
} finally {
|
|
||||||
setRestoring(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [selectedFile, webdavHost, t, restoreMethod])
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsRestoreModalVisible(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
isRestoreModalVisible,
|
|
||||||
handleRestore,
|
|
||||||
handleCancel,
|
|
||||||
restoring,
|
|
||||||
selectedFile,
|
|
||||||
setSelectedFile,
|
|
||||||
loadingFiles,
|
|
||||||
backupFiles,
|
|
||||||
showRestoreModal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function WebdavRestoreModal({
|
|
||||||
isRestoreModalVisible,
|
|
||||||
handleRestore,
|
|
||||||
handleCancel,
|
|
||||||
restoring,
|
|
||||||
selectedFile,
|
|
||||||
setSelectedFile,
|
|
||||||
loadingFiles,
|
|
||||||
backupFiles
|
|
||||||
}: WebdavRestoreModalProps) {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
title={t('settings.data.webdav.restore.modal.title')}
|
|
||||||
open={isRestoreModalVisible}
|
|
||||||
onOk={handleRestore}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
okButtonProps={{ loading: restoring }}
|
|
||||||
width={600}
|
|
||||||
transitionName="animation-move-down"
|
|
||||||
centered>
|
|
||||||
<div style={{ position: 'relative' }}>
|
|
||||||
<Select
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
placeholder={t('settings.data.webdav.restore.modal.select.placeholder')}
|
|
||||||
value={selectedFile}
|
|
||||||
onChange={setSelectedFile}
|
|
||||||
options={backupFiles.map(formatFileOption)}
|
|
||||||
loading={loadingFiles}
|
|
||||||
showSearch
|
|
||||||
filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())}
|
|
||||||
/>
|
|
||||||
{loadingFiles && (
|
|
||||||
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>
|
|
||||||
<Spin />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatFileOption(file: BackupFile) {
|
|
||||||
const date = dayjs(file.modifiedTime).format('YYYY-MM-DD HH:mm:ss')
|
|
||||||
const size = formatFileSize(file.size)
|
|
||||||
return {
|
|
||||||
label: `${file.fileName} (${date}, ${size})`,
|
|
||||||
value: file.fileName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1227,8 +1227,6 @@
|
|||||||
"restore.confirm.content": "Restoring from WebDAV will overwrite current data. Do you want to continue?",
|
"restore.confirm.content": "Restoring from WebDAV will overwrite current data. Do you want to continue?",
|
||||||
"restore.confirm.title": "Confirm Restore",
|
"restore.confirm.title": "Confirm Restore",
|
||||||
"restore.content": "Restore from WebDAV will overwrite the current data, continue?",
|
"restore.content": "Restore from WebDAV will overwrite the current data, continue?",
|
||||||
"restore.modal.select.placeholder": "Please select a backup file to restore",
|
|
||||||
"restore.modal.title": "Restore from WebDAV",
|
|
||||||
"restore.title": "Restore from WebDAV",
|
"restore.title": "Restore from WebDAV",
|
||||||
"syncError": "Backup Error",
|
"syncError": "Backup Error",
|
||||||
"syncStatus": "Backup Status",
|
"syncStatus": "Backup Status",
|
||||||
|
|||||||
@ -804,7 +804,19 @@
|
|||||||
"vision": "画像",
|
"vision": "画像",
|
||||||
"websearch": "ウェブ検索"
|
"websearch": "ウェブ検索"
|
||||||
},
|
},
|
||||||
"rerank_model_not_support_provider": "現在、並べ替えモデルはこのプロバイダー ({{provider}}) をサポートしていません。"
|
"rerank_model_not_support_provider": "現在、並べ替えモデルはこのプロバイダー ({{provider}}) をサポートしていません。",
|
||||||
|
"price": {
|
||||||
|
"cost": "コスト",
|
||||||
|
"currency": "通貨",
|
||||||
|
"custom": "カスタム",
|
||||||
|
"custom_currency": "カスタム通貨",
|
||||||
|
"custom_currency_placeholder": "カスタム通貨を入力してください",
|
||||||
|
"input": "入力価格",
|
||||||
|
"million_tokens": "百万トークン",
|
||||||
|
"output": "出力価格",
|
||||||
|
"price": "価格"
|
||||||
|
},
|
||||||
|
"reasoning": "思考"
|
||||||
},
|
},
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"expand": "ダイアログを展開",
|
"expand": "ダイアログを展開",
|
||||||
@ -965,17 +977,6 @@
|
|||||||
"required_field": "必須項目",
|
"required_field": "必須項目",
|
||||||
"uploaded_input": "アップロード済みの入力"
|
"uploaded_input": "アップロード済みの入力"
|
||||||
},
|
},
|
||||||
"price": {
|
|
||||||
"cost": "コスト",
|
|
||||||
"currency": "通貨",
|
|
||||||
"custom": "カスタム",
|
|
||||||
"custom_currency": "カスタム通貨",
|
|
||||||
"custom_currency_placeholder": "カスタム通貨を入力してください",
|
|
||||||
"input": "入力価格",
|
|
||||||
"million_tokens": "百万トークン",
|
|
||||||
"output": "出力価格",
|
|
||||||
"price": "価格"
|
|
||||||
},
|
|
||||||
"prompts": {
|
"prompts": {
|
||||||
"explanation": "この概念を説明してください",
|
"explanation": "この概念を説明してください",
|
||||||
"summarize": "このテキストを要約してください",
|
"summarize": "このテキストを要約してください",
|
||||||
@ -1206,8 +1207,6 @@
|
|||||||
"restore.confirm.content": "WebDAV から復元すると現在のデータが上書きされます。続行しますか?",
|
"restore.confirm.content": "WebDAV から復元すると現在のデータが上書きされます。続行しますか?",
|
||||||
"restore.confirm.title": "復元を確認",
|
"restore.confirm.title": "復元を確認",
|
||||||
"restore.content": "WebDAVから復元すると現在のデータが上書きされます。続行しますか?",
|
"restore.content": "WebDAVから復元すると現在のデータが上書きされます。続行しますか?",
|
||||||
"restore.modal.select.placeholder": "復元するバックアップファイルを選択してください",
|
|
||||||
"restore.modal.title": "WebDAV から復元",
|
|
||||||
"restore.title": "WebDAVから復元",
|
"restore.title": "WebDAVから復元",
|
||||||
"syncError": "バックアップエラー",
|
"syncError": "バックアップエラー",
|
||||||
"syncStatus": "バックアップ状態",
|
"syncStatus": "バックアップ状態",
|
||||||
|
|||||||
@ -804,7 +804,19 @@
|
|||||||
"vision": "Визуальные",
|
"vision": "Визуальные",
|
||||||
"websearch": "Веб-поисковые"
|
"websearch": "Веб-поисковые"
|
||||||
},
|
},
|
||||||
"rerank_model_not_support_provider": "В настоящее время модель переупорядочивания не поддерживает этого провайдера ({{provider}})"
|
"rerank_model_not_support_provider": "В настоящее время модель переупорядочивания не поддерживает этого провайдера ({{provider}})",
|
||||||
|
"price": {
|
||||||
|
"cost": "Стоимость",
|
||||||
|
"currency": "Валюта",
|
||||||
|
"custom": "Пользовательский",
|
||||||
|
"custom_currency": "Пользовательская валюта",
|
||||||
|
"custom_currency_placeholder": "Введите пользовательскую валюту",
|
||||||
|
"input": "Цена ввода",
|
||||||
|
"million_tokens": "M Tokens",
|
||||||
|
"output": "Цена вывода",
|
||||||
|
"price": "Цена"
|
||||||
|
},
|
||||||
|
"reasoning": "Рассуждение"
|
||||||
},
|
},
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"expand": "Развернуть диалоговое окно",
|
"expand": "Развернуть диалоговое окно",
|
||||||
@ -962,30 +974,8 @@
|
|||||||
"per_image": "за изображение",
|
"per_image": "за изображение",
|
||||||
"per_images": "за изображения",
|
"per_images": "за изображения",
|
||||||
"required_field": "Обязательное поле",
|
"required_field": "Обязательное поле",
|
||||||
"uploaded_input": "Загруженный ввод"
|
"uploaded_input": "Загруженный ввод",
|
||||||
},
|
"prompt_placeholder_en": "[to be translated]:Enter your image description, currently Imagen only supports English prompts"
|
||||||
"plantuml": {
|
|
||||||
"download": {
|
|
||||||
"failed": "下载失败,请检查网络",
|
|
||||||
"png": "下载 PNG",
|
|
||||||
"svg": "下载 SVG"
|
|
||||||
},
|
|
||||||
"tabs": {
|
|
||||||
"preview": "Предпросмотр",
|
|
||||||
"source": "Исходный код"
|
|
||||||
},
|
|
||||||
"title": "PlantUML 图表"
|
|
||||||
},
|
|
||||||
"price": {
|
|
||||||
"cost": "Стоимость",
|
|
||||||
"currency": "Валюта",
|
|
||||||
"custom": "Пользовательский",
|
|
||||||
"custom_currency": "Пользовательская валюта",
|
|
||||||
"custom_currency_placeholder": "Введите пользовательскую валюту",
|
|
||||||
"input": "Цена ввода",
|
|
||||||
"million_tokens": "M Tokens",
|
|
||||||
"output": "Цена вывода",
|
|
||||||
"price": "Цена"
|
|
||||||
},
|
},
|
||||||
"prompts": {
|
"prompts": {
|
||||||
"explanation": "Объясните мне этот концепт",
|
"explanation": "Объясните мне этот концепт",
|
||||||
@ -1235,8 +1225,6 @@
|
|||||||
"restore.confirm.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?",
|
"restore.confirm.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?",
|
||||||
"restore.confirm.title": "Подтверждение восстановления",
|
"restore.confirm.title": "Подтверждение восстановления",
|
||||||
"restore.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?",
|
"restore.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?",
|
||||||
"restore.modal.select.placeholder": "Выберите файл резервной копии для восстановления",
|
|
||||||
"restore.modal.title": "Восстановление с WebDAV",
|
|
||||||
"restore.title": "Восстановление с WebDAV",
|
"restore.title": "Восстановление с WebDAV",
|
||||||
"syncError": "Ошибка резервного копирования",
|
"syncError": "Ошибка резервного копирования",
|
||||||
"syncStatus": "Статус резервного копирования",
|
"syncStatus": "Статус резервного копирования",
|
||||||
|
|||||||
@ -1229,8 +1229,6 @@
|
|||||||
"restore.confirm.content": "从 WebDAV 恢复将会覆盖当前数据,是否继续?",
|
"restore.confirm.content": "从 WebDAV 恢复将会覆盖当前数据,是否继续?",
|
||||||
"restore.confirm.title": "确认恢复",
|
"restore.confirm.title": "确认恢复",
|
||||||
"restore.content": "从 WebDAV 恢复将覆盖当前数据,是否继续?",
|
"restore.content": "从 WebDAV 恢复将覆盖当前数据,是否继续?",
|
||||||
"restore.modal.select.placeholder": "请选择要恢复的备份文件",
|
|
||||||
"restore.modal.title": "从 WebDAV 恢复",
|
|
||||||
"restore.title": "从 WebDAV 恢复",
|
"restore.title": "从 WebDAV 恢复",
|
||||||
"syncError": "备份错误",
|
"syncError": "备份错误",
|
||||||
"syncStatus": "备份状态",
|
"syncStatus": "备份状态",
|
||||||
|
|||||||
@ -804,7 +804,19 @@
|
|||||||
"vision": "視覺",
|
"vision": "視覺",
|
||||||
"websearch": "網路搜尋"
|
"websearch": "網路搜尋"
|
||||||
},
|
},
|
||||||
"rerank_model_not_support_provider": "目前,重新排序模型不支援此提供者({{provider}})"
|
"rerank_model_not_support_provider": "目前,重新排序模型不支援此提供者({{provider}})",
|
||||||
|
"price": {
|
||||||
|
"cost": "花費",
|
||||||
|
"currency": "幣種",
|
||||||
|
"custom": "自訂",
|
||||||
|
"custom_currency": "自訂幣種",
|
||||||
|
"custom_currency_placeholder": "請輸入自訂幣種",
|
||||||
|
"input": "輸入價格",
|
||||||
|
"million_tokens": "M Tokens",
|
||||||
|
"output": "輸出價格",
|
||||||
|
"price": "價格"
|
||||||
|
},
|
||||||
|
"reasoning": "推理"
|
||||||
},
|
},
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"expand": "伸縮對話框",
|
"expand": "伸縮對話框",
|
||||||
@ -965,17 +977,6 @@
|
|||||||
"required_field": "必填欄位",
|
"required_field": "必填欄位",
|
||||||
"uploaded_input": "已上傳輸入"
|
"uploaded_input": "已上傳輸入"
|
||||||
},
|
},
|
||||||
"price": {
|
|
||||||
"cost": "花費",
|
|
||||||
"currency": "幣種",
|
|
||||||
"custom": "自訂",
|
|
||||||
"custom_currency": "自訂幣種",
|
|
||||||
"custom_currency_placeholder": "請輸入自訂幣種",
|
|
||||||
"input": "輸入價格",
|
|
||||||
"million_tokens": "M Tokens",
|
|
||||||
"output": "輸出價格",
|
|
||||||
"price": "價格"
|
|
||||||
},
|
|
||||||
"prompts": {
|
"prompts": {
|
||||||
"explanation": "幫我解釋一下這個概念",
|
"explanation": "幫我解釋一下這個概念",
|
||||||
"summarize": "幫我總結一下這段話",
|
"summarize": "幫我總結一下這段話",
|
||||||
@ -1226,8 +1227,6 @@
|
|||||||
"restore.confirm.content": "從 WebDAV 恢復將覆蓋目前資料,是否繼續?",
|
"restore.confirm.content": "從 WebDAV 恢復將覆蓋目前資料,是否繼續?",
|
||||||
"restore.confirm.title": "復元確認",
|
"restore.confirm.title": "復元確認",
|
||||||
"restore.content": "從 WebDAV 恢復將覆蓋目前資料,是否繼續?",
|
"restore.content": "從 WebDAV 恢復將覆蓋目前資料,是否繼續?",
|
||||||
"restore.modal.select.placeholder": "請選擇要恢復的備份文件",
|
|
||||||
"restore.modal.title": "從 WebDAV 恢復",
|
|
||||||
"restore.title": "從 WebDAV 恢復",
|
"restore.title": "從 WebDAV 恢復",
|
||||||
"syncError": "備份錯誤",
|
"syncError": "備份錯誤",
|
||||||
"syncStatus": "備份狀態",
|
"syncStatus": "備份狀態",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user