Compare commits

...
Author SHA1 Message Date
renovate[bot] d8e5e58f8f chore(deps): update cargo dependencies 2026-11-02 05:31:20 +00:00
Tunglies 067a9f7cad fix(webdav): allow clearing saved configuration
Close #8495
2026-11-02 03:26:36 +08:00
7 changed files with 36 additions and 30 deletions
+3 -3
View File
@@ -63,18 +63,18 @@ tracing = "0.1.44"
tauri = { version = "2.12.4" } tauri = { version = "2.12.4" }
tauri-plugin-clipboard-manager = "2.5.0" tauri-plugin-clipboard-manager = "2.5.0"
parking_lot = { version = "0.12.5", features = ["hardware-lock-elision"] } parking_lot = { version = "0.13.0", features = ["hardware-lock-elision"] }
anyhow = "1.0.104" anyhow = "1.0.104"
chrono = "0.4.45" chrono = "0.4.45"
criterion = { version = "0.8.2", features = ["async_tokio"] } criterion = { version = "0.8.2", features = ["async_tokio"] }
tokio = { version = "1.53.3", features = [ tokio = { version = "1.54.1", features = [
"rt-multi-thread", "rt-multi-thread",
"macros", "macros",
"time", "time",
"sync", "sync",
] } ] }
flexi_logger = "0.31.10" flexi_logger = "0.31.10"
log = "0.4.34" log = "0.4.35"
regex = "1.13.1" regex = "1.13.1"
reqwest = { version = "0.13.5", features = [ reqwest = { version = "0.13.5", features = [
"json", "json",
+1
View File
@@ -13,6 +13,7 @@
- 修复 代理 页展开分组后不显示最新测速结果,需切换节点才刷新 - 修复 代理 页展开分组后不显示最新测速结果,需切换节点才刷新
- 修复 代理 在全局模式下无法展开节点组 - 修复 代理 在全局模式下无法展开节点组
- 修复 自定义 CSS 无法修改编辑器字体和字号的问题 - 修复 自定义 CSS 无法修改编辑器字体和字号的问题
- 修复 WebDAV 设置清空后无法保存
**🍎 macOS** **🍎 macOS**
+1 -1
View File
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
specta = { version = "=2.0.0-rc.25", features = ["derive", "function"] } specta = { version = "=2.0.0-rc.27", features = ["derive", "function"] }
clash-verge-logging = { workspace = true } clash-verge-logging = { workspace = true }
chrono = { workspace = true } chrono = { workspace = true }
log = { workspace = true } log = { workspace = true }
@@ -5,14 +5,14 @@ edition = "2024"
rust-version = "1.91" rust-version = "1.91"
[dependencies] [dependencies]
specta = { version = "=2.0.0-rc.25", features = ["derive", "function"] } specta = { version = "=2.0.0-rc.27", features = ["derive", "function"] }
tauri = { workspace = true } tauri = { workspace = true }
tauri-plugin-clipboard-manager = { workspace = true } tauri-plugin-clipboard-manager = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
# sysinfo 0.38.2 conflicts with dark-light # sysinfo 0.38.2 conflicts with dark-light
# see https://github.com/GuillaumeGomez/sysinfo/issues/1623 # see https://github.com/GuillaumeGomez/sysinfo/issues/1623
sysinfo = { version = "0.39.6", features = ["network", "system"] } sysinfo = { version = "0.40.1", features = ["network", "system"] }
[target.'cfg(not(windows))'.dependencies] [target.'cfg(not(windows))'.dependencies]
libc = "0.2.191" libc = "0.2.191"
+8 -8
View File
@@ -58,8 +58,8 @@ smartstring = { workspace = true, features = ["serde"] }
bitflags = { workspace = true } bitflags = { workspace = true }
socket2 = { workspace = true } socket2 = { workspace = true }
warp = { version = "0.4.3", features = ["server"] } warp = { version = "0.4.3", features = ["server"] }
open = "5.4.4" open = "5.4.5"
rfd = { version = "0.16.0", default-features = false, features = ["common-controls-v6"] } rfd = { version = "0.17.2", default-features = false, features = ["common-controls-v6"] }
dirs = "7.0.0" dirs = "7.0.0"
dunce = "1.0.5" dunce = "1.0.5"
nanoid = "0.5" nanoid = "0.5"
@@ -79,7 +79,7 @@ tauri-plugin-fs = "2.7.1"
tauri-plugin-process = "2.4.0" tauri-plugin-process = "2.4.0"
tauri-plugin-deep-link = "2.6.2" tauri-plugin-deep-link = "2.6.2"
tauri-plugin-window-state = "2.5.0" tauri-plugin-window-state = "2.5.0"
zip = "9.1.3" zip = "9.2.2"
flate2 = "1.1.10" flate2 = "1.1.10"
reqwest_dav = "0.3.3" reqwest_dav = "0.3.3"
aes-gcm = { version = "0.11.1" } aes-gcm = { version = "0.11.1" }
@@ -98,19 +98,19 @@ tracing = { workspace = true }
tauri-plugin-devtools = { version = "2.2.2", optional = true } tauri-plugin-devtools = { version = "2.2.2", optional = true }
tauri-plugin-mihomo = { git = "https://github.com/clash-verge-rev/tauri-plugin-mihomo", rev = "7a03d16f4d39b1bb885b7babe66b9e153e34b615" } tauri-plugin-mihomo = { git = "https://github.com/clash-verge-rev/tauri-plugin-mihomo", rev = "7a03d16f4d39b1bb885b7babe66b9e153e34b615" }
async-trait = "0.1.92" async-trait = "0.1.92"
clash_verge_service_ipc = { git = "https://github.com/clash-verge-rev/clash-verge-service-ipc.git", tag = "v2.7.6", version = "2.7.6", features = [ clash_verge_service_ipc = { git = "https://github.com/clash-verge-rev/clash-verge-service-ipc.git", tag = "v2.7.7", version = "2.7.6", features = [
"client", "client",
] } ] }
arc-swap = "1.9.2" arc-swap = "1.9.3"
tokio-rustls = "0.26.6" tokio-rustls = "0.26.6"
rustls = { version = "0.23.46", features = ["ring"] } rustls = { version = "0.23.46", features = ["ring"] }
webpki-roots = "1.0.9" webpki-roots = "1.0.11"
dark-light = "3.0.0" dark-light = "3.0.0"
bytes = "1.12.1" bytes = "1.12.1"
tokio-util = { version = "0.7.20", features = ["time"] } tokio-util = { version = "0.7.20", features = ["time"] }
specta = { version = "=2.0.0-rc.25", features = ["derive", "function", "serde_json"] } specta = { version = "=2.0.0-rc.27", features = ["derive", "function", "serde_json"] }
tauri-specta = { version = "=2.0.0-rc.25", features = ["derive", "typescript"] } tauri-specta = { version = "=2.0.0-rc.25", features = ["derive", "typescript"] }
specta-typescript = "=0.0.12" specta-typescript = "=0.0.14"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = "0.2.191" libc = "0.2.191"
@@ -40,9 +40,9 @@ export const BackupConfigViewer = memo(
const { register, handleSubmit, watch } = useForm<IWebDavConfig>({ const { register, handleSubmit, watch } = useForm<IWebDavConfig>({
defaultValues: { defaultValues: {
url: webdav_url!, url: webdav_url ?? '',
username: webdav_username!, username: webdav_username ?? '',
password: webdav_password!, password: webdav_password ?? '',
}, },
}) })
const url = watch('url') const url = watch('url')
@@ -50,9 +50,9 @@ export const BackupConfigViewer = memo(
const password = watch('password') const password = watch('password')
const webdavChanged = const webdavChanged =
webdav_url !== url || (webdav_url ?? '') !== url ||
webdav_username !== username || (webdav_username ?? '') !== username ||
webdav_password !== password (webdav_password ?? '') !== password
const webdavSignature = buildWebdavSignature(verge) const webdavSignature = buildWebdavSignature(verge)
const webdavStatus = getWebdavStatus(webdavSignature) const webdavStatus = getWebdavStatus(webdavSignature)
@@ -69,9 +69,9 @@ export const BackupConfigViewer = memo(
}, [webdav_url, webdav_username, webdav_password, onInit, shouldAutoInit]) }, [webdav_url, webdav_username, webdav_password, onInit, shouldAutoInit])
const checkForm = () => { const checkForm = () => {
const username = usernameRef.current?.value const username = usernameRef.current?.value.trim()
const password = passwordRef.current?.value const password = passwordRef.current?.value
const url = urlRef.current?.value const url = urlRef.current?.value.trim()
if (!url) { if (!url) {
urlRef.current?.focus() urlRef.current?.focus()
@@ -95,14 +95,15 @@ export const BackupConfigViewer = memo(
} }
const save = useLockFn(async (data: IWebDavConfig) => { const save = useLockFn(async (data: IWebDavConfig) => {
checkForm() const trimmedUrl = data.url.trim()
const trimmedUsername = data.username.trim()
const isClearing = !trimmedUrl && !trimmedUsername && !data.password
if (!isClearing) checkForm()
const signature = buildWebdavSignature({ const signature = buildWebdavSignature({
webdav_url: data.url, webdav_url: data.url,
webdav_username: data.username, webdav_username: data.username,
webdav_password: data.password, webdav_password: data.password,
}) })
const trimmedUrl = data.url.trim()
const trimmedUsername = data.username.trim()
try { try {
setLoading(true) setLoading(true)
@@ -127,7 +128,7 @@ export const BackupConfigViewer = memo(
) )
setWebdavStatus(signature, 'unknown') setWebdavStatus(signature, 'unknown')
showNotice.success('settings.modals.backup.messages.webdavConfigSaved') showNotice.success('settings.modals.backup.messages.webdavConfigSaved')
await onSaveSuccess(signature) if (!isClearing) await onSaveSuccess(signature)
} catch (error) { } catch (error) {
showNotice.error( showNotice.error(
'settings.modals.backup.messages.webdavConfigSaveFailed', 'settings.modals.backup.messages.webdavConfigSaveFailed',
@@ -223,9 +224,9 @@ export const BackupConfigViewer = memo(
}} }}
> >
{webdavChanged || {webdavChanged ||
webdav_url === undefined || !webdav_url ||
webdav_username === undefined || !webdav_username ||
webdav_password === undefined ? ( !webdav_password ? (
<Button <Button
variant="contained" variant="contained"
color={'primary'} color={'primary'}
+5 -1
View File
@@ -43,7 +43,11 @@ export const getWebdavStatus = (signature: string): WebdavStatus => {
} }
export const setWebdavStatus = (signature: string, status: WebdavStatus) => { export const setWebdavStatus = (signature: string, status: WebdavStatus) => {
if (!signature || !canUseStorage()) return if (!canUseStorage()) return
if (!signature) {
localStorage.removeItem(WEBDAV_STATUS_KEY)
return
}
const payload: WebdavStatusCache = { const payload: WebdavStatusCache = {
signature, signature,