From 3152e0de59463878d21da6c5aae2c9d09a4e21b3 Mon Sep 17 00:00:00 2001 From: zhom <2717306+zhom@users.noreply.github.com> Date: Sun, 19 Apr 2026 19:34:14 +0400 Subject: [PATCH] feat: shadowsocks --- src-tauri/src/browser.rs | 2 +- src-tauri/src/proxy_manager.rs | 4 +++ src/components/proxy-form-dialog.tsx | 40 ++++++++++++++++++++++------ src/i18n/locales/en.json | 7 +++-- src/i18n/locales/es.json | 7 +++-- src/i18n/locales/fr.json | 7 +++-- src/i18n/locales/ja.json | 7 +++-- src/i18n/locales/pt.json | 7 +++-- src/i18n/locales/ru.json | 7 +++-- src/i18n/locales/zh.json | 7 +++-- src/types.ts | 2 +- 11 files changed, 73 insertions(+), 24 deletions(-) diff --git a/src-tauri/src/browser.rs b/src-tauri/src/browser.rs index 4ab742f..74dc7aa 100644 --- a/src-tauri/src/browser.rs +++ b/src-tauri/src/browser.rs @@ -4,7 +4,7 @@ use utoipa::ToSchema; #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct ProxySettings { - pub proxy_type: String, // "http", "https", "socks4", or "socks5" + pub proxy_type: String, // "http", "https", "socks4", "socks5", or "ss" (Shadowsocks) pub host: String, pub port: u16, pub username: Option, diff --git a/src-tauri/src/proxy_manager.rs b/src-tauri/src/proxy_manager.rs index d4970a2..bf9f177 100644 --- a/src-tauri/src/proxy_manager.rs +++ b/src-tauri/src/proxy_manager.rs @@ -1368,6 +1368,10 @@ impl ProxyManager { ("socks5", rest) } else if let Some(rest) = line.strip_prefix("socks://") { ("socks5", rest) // Default socks to socks5 + } else if let Some(rest) = line.strip_prefix("ss://") { + ("ss", rest) + } else if let Some(rest) = line.strip_prefix("shadowsocks://") { + ("ss", rest) } else { return None; }; diff --git a/src/components/proxy-form-dialog.tsx b/src/components/proxy-form-dialog.tsx index af3ddea..8bce393 100644 --- a/src/components/proxy-form-dialog.tsx +++ b/src/components/proxy-form-dialog.tsx @@ -94,6 +94,19 @@ export function ProxyFormDialog({ return; } + if ( + form.proxy_type === "ss" && + (!form.username.trim() || !form.password.trim()) + ) { + toast.error( + t( + "proxies.form.ssCipherRequired", + "Cipher and password are required for Shadowsocks", + ), + ); + return; + } + setIsSubmitting(true); try { const payload = { @@ -136,7 +149,12 @@ export function ProxyFormDialog({ }, [isSubmitting, onClose]); const isFormValid = - form.name.trim() && form.host.trim() && form.port > 0 && form.port <= 65535; + form.name.trim() && + form.host.trim() && + form.port > 0 && + form.port <= 65535 && + (form.proxy_type !== "ss" || + (form.username.trim() && form.password.trim())); return ( @@ -174,9 +192,9 @@ export function ProxyFormDialog({ - {["http", "https", "socks4", "socks5"].map((type) => ( + {["http", "https", "socks4", "socks5", "ss"].map((type) => ( - {type.toUpperCase()} + {type === "ss" ? "Shadowsocks" : type.toUpperCase()} ))} @@ -220,8 +238,9 @@ export function ProxyFormDialog({
{ setForm({ ...form, username: e.target.value }); }} - placeholder={t("proxies.form.usernamePlaceholder")} + placeholder={ + form.proxy_type === "ss" + ? t("proxies.form.cipherPlaceholder") + : t("proxies.form.usernamePlaceholder") + } disabled={isSubmitting} />