support delete backup file
Some checks are pending
Build / windows (arm64) (push) Waiting to run
Build / windows (ia32) (push) Waiting to run
Build / windows (x64) (push) Waiting to run
Build / linux (arm64) (push) Waiting to run
Build / linux (x64) (push) Waiting to run
Build / macos (arm64) (push) Waiting to run
Build / macos (x64) (push) Waiting to run
Build / updater (push) Blocked by required conditions
Build / aur-release-updater (mihomo-party) (push) Blocked by required conditions
Build / aur-release-updater (mihomo-party-bin) (push) Blocked by required conditions
Build / aur-release-updater (mihomo-party-electron) (push) Blocked by required conditions
Build / aur-release-updater (mihomo-party-electron-bin) (push) Blocked by required conditions
Build / aur-git-updater (push) Waiting to run

This commit is contained in:
pompurin404 2024-08-23 14:59:03 +08:00
parent ba484070ae
commit be04031e82
No known key found for this signature in database
7 changed files with 85 additions and 32 deletions

View File

@ -1,3 +1,7 @@
### New Features
- 支持删除 Webdav 备份文件
### Bug Fixes
- 修复拨号网络系统代理问题

View File

@ -26,6 +26,7 @@
"@mihomo-party/sysproxy": "^2.0.0",
"adm-zip": "^0.5.15",
"axios": "^1.7.3",
"dayjs": "^1.11.13",
"webdav": "^5.7.1",
"ws": "^8.18.0",
"yaml": "^2.5.0"
@ -38,6 +39,7 @@
"@electron-toolkit/eslint-config-ts": "^2.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@nextui-org/react": "^2.4.6",
"@types/adm-zip": "^0.5.5",
"@types/node": "^22.1.0",
"@types/pubsub-js": "^1.8.6",
"@types/react": "^18.3.3",
@ -46,7 +48,6 @@
"@vitejs/plugin-react": "^4.3.1",
"apexcharts": "^3.52.0",
"autoprefixer": "^10.4.20",
"dayjs": "^1.11.12",
"electron": "^31.3.1",
"electron-builder": "^25.0.3",
"electron-vite": "^2.3.0",

View File

@ -23,6 +23,9 @@ importers:
axios:
specifier: ^1.7.3
version: 1.7.4
dayjs:
specifier: ^1.11.13
version: 1.11.13
webdav:
specifier: ^5.7.1
version: 5.7.1
@ -54,6 +57,9 @@ importers:
'@nextui-org/react':
specifier: ^2.4.6
version: 2.4.6(@types/react@18.3.3)(framer-motion@11.3.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.10)
'@types/adm-zip':
specifier: ^0.5.5
version: 0.5.5
'@types/node':
specifier: ^22.1.0
version: 22.4.0
@ -78,9 +84,6 @@ importers:
autoprefixer:
specifier: ^10.4.20
version: 10.4.20(postcss@8.4.41)
dayjs:
specifier: ^1.11.12
version: 1.11.12
electron:
specifier: ^31.3.1
version: 31.4.0
@ -1961,6 +1964,9 @@ packages:
resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
engines: {node: '>= 10'}
'@types/adm-zip@0.5.5':
resolution: {integrity: sha512-YCGstVMjc4LTY5uK9/obvxBya93axZOVOyf2GSUulADzmLhYE45u2nAssCs/fWBs1Ifq5Vat75JTPwd5XZoPJw==}
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
@ -2583,8 +2589,8 @@ packages:
resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
engines: {node: '>= 0.4'}
dayjs@1.11.12:
resolution: {integrity: sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==}
dayjs@1.11.13:
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
debug@4.3.6:
resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
@ -7531,6 +7537,10 @@ snapshots:
'@tootallnate/once@2.0.0': {}
'@types/adm-zip@0.5.5':
dependencies:
'@types/node': 22.4.0
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.25.3
@ -8304,7 +8314,7 @@ snapshots:
es-errors: 1.3.0
is-data-view: 1.0.1
dayjs@1.11.12: {}
dayjs@1.11.13: {}
debug@4.3.6:
dependencies:

View File

@ -1,4 +1,5 @@
import { getAppConfig } from '../config'
import dayjs from 'dayjs'
import AdmZip from 'adm-zip'
import {
appConfigPath,
@ -23,7 +24,8 @@ export async function webdavBackup(): Promise<boolean> {
zip.addLocalFile(overrideConfigPath())
zip.addLocalFolder(profilesDir(), 'profiles')
zip.addLocalFolder(overrideDir(), 'override')
const zipFileName = `backup-${new Date().toISOString().replace(/:/g, '-')}.zip`
const date = new Date()
const zipFileName = `Backup_${dayjs(date).format('YYYY-MM-DD_HH-mm-ss')}.zip`
const client = createClient(webdavUrl, {
username: webdavUsername,
@ -47,8 +49,8 @@ export async function webdavRestore(filename: string): Promise<void> {
username: webdavUsername,
password: webdavPassword
})
const zipData = await client.getFileContents(`/mihomo-party/${filename}`)
const zip = new AdmZip(zipData)
const zipData = await client.getFileContents(`mihomo-party/${filename}`)
const zip = new AdmZip(zipData as Buffer)
zip.extractAllTo(dataDir(), true)
app.relaunch()
app.quit()
@ -70,3 +72,15 @@ export async function listWebdavBackups(): Promise<string[]> {
return files.data.map((file) => file.basename)
}
}
export async function webdavDelete(filename: string): Promise<void> {
const webdav = await import('webdav')
const createClient = webdav.createClient
const { webdavUrl = '', webdavUsername = '', webdavPassword = '' } = await getAppConfig()
const client = createClient(webdavUrl, {
username: webdavUsername,
password: webdavPassword
})
await client.deleteFile(`mihomo-party/${filename}`)
}

View File

@ -52,7 +52,7 @@ import { checkUpdate, downloadAndInstallUpdate } from '../resolve/autoUpdater'
import { getFilePath, openUWPTool, readTextFile, setNativeTheme, setupFirewall } from '../sys/misc'
import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory'
import { isPortable, setPortable } from './dirs'
import { listWebdavBackups, webdavBackup, webdavRestore } from '../resolve/backup'
import { listWebdavBackups, webdavBackup, webdavDelete, webdavRestore } from '../resolve/backup'
import { getInterfaces } from '../sys/interface'
import { copyEnv } from '../resolve/tray'
import { registerShortcut } from '../resolve/shortcut'
@ -162,6 +162,7 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('webdavBackup', ipcErrorWrapper(webdavBackup))
ipcMain.handle('webdavRestore', (_e, filename) => ipcErrorWrapper(webdavRestore)(filename))
ipcMain.handle('listWebdavBackups', ipcErrorWrapper(listWebdavBackups))
ipcMain.handle('webdavDelete', (_e, filename) => ipcErrorWrapper(webdavDelete)(filename))
ipcMain.handle('registerShortcut', (_e, oldShortcut, newShortcut, action) =>
ipcErrorWrapper(registerShortcut)(oldShortcut, newShortcut, action)
)

View File

@ -1,12 +1,14 @@
import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from '@nextui-org/react'
import { webdavRestore } from '@renderer/utils/ipc'
import { webdavDelete, webdavRestore } from '@renderer/utils/ipc'
import React, { useState } from 'react'
import { MdDeleteForever } from 'react-icons/md'
interface Props {
filenames: string[]
onClose: () => void
}
const WebdavRestoreModal: React.FC<Props> = (props) => {
const { filenames, onClose } = props
const { filenames: names, onClose } = props
const [filenames, setFilenames] = useState<string[]>(names)
const [restoring, setRestoring] = useState(false)
return (
@ -24,25 +26,42 @@ const WebdavRestoreModal: React.FC<Props> = (props) => {
<div className="flex justify-center"></div>
) : (
filenames.map((filename) => (
<Button
size="sm"
fullWidth
key={filename}
isLoading={restoring}
variant="flat"
onPress={async () => {
setRestoring(true)
try {
await webdavRestore(filename)
} catch (e) {
alert(`恢复失败: ${e}`)
} finally {
setRestoring(false)
}
}}
>
{filename}
</Button>
<div className="flex" key={filename}>
<Button
size="sm"
fullWidth
isLoading={restoring}
variant="flat"
onPress={async () => {
setRestoring(true)
try {
await webdavRestore(filename)
} catch (e) {
alert(`恢复失败: ${e}`)
} finally {
setRestoring(false)
}
}}
>
{filename}
</Button>
<Button
size="sm"
color="warning"
variant="flat"
className="ml-2"
onClick={async () => {
try {
await webdavDelete(filename)
setFilenames(filenames.filter((name) => name !== filename))
} catch (e) {
alert(`删除失败: ${e}`)
}
}}
>
<MdDeleteForever className="text-lg" />
</Button>
</div>
))
)}
</ModalBody>

View File

@ -283,6 +283,10 @@ export async function listWebdavBackups(): Promise<string[]> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('listWebdavBackups'))
}
export async function webdavDelete(filename: string): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('webdavDelete', filename))
}
export async function quitApp(): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('quitApp'))
}