mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-16 03:32:17 +08:00
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
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:
parent
ba484070ae
commit
be04031e82
|
@ -1,3 +1,7 @@
|
|||
### New Features
|
||||
|
||||
- 支持删除 Webdav 备份文件
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 修复拨号网络系统代理问题
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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}`)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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'))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user