feat(settings): add enableLocalProxy toggle to gate main page proxy UI

New users often accidentally trigger ProxyToggle/FailoverToggle on the
main page. Add a settings toggle (default off) so the proxy controls
only appear when explicitly enabled. The proxy service start/stop in
settings remains independent of this visibility flag.
This commit is contained in:
Jason
2026-02-19 23:06:22 +08:00
parent 1b71dc721c
commit 0fa6b33b5e
9 changed files with 46 additions and 20 deletions

View File

@@ -187,6 +187,9 @@ pub struct AppSettings {
/// 静默启动(程序启动时不显示主窗口,仅托盘运行)
#[serde(default)]
pub silent_startup: bool,
/// 是否在主页面启用本地代理功能(默认关闭)
#[serde(default)]
pub enable_local_proxy: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
@@ -262,6 +265,7 @@ impl Default for AppSettings {
skip_claude_onboarding: false,
launch_on_startup: false,
silent_startup: false,
enable_local_proxy: false,
language: None,
visible_apps: None,
claude_config_dir: None,

View File

@@ -1046,21 +1046,23 @@ function App() {
)}
{currentView === "providers" && (
<>
{activeApp !== "opencode" && activeApp !== "openclaw" && (
<>
<ProxyToggle activeApp={activeApp} />
<div
className={cn(
"transition-all duration-300 ease-in-out overflow-hidden",
isCurrentAppTakeoverActive
? "opacity-100 max-w-[100px] scale-100"
: "opacity-0 max-w-0 scale-75 pointer-events-none",
)}
>
<FailoverToggle activeApp={activeApp} />
</div>
</>
)}
{activeApp !== "opencode" &&
activeApp !== "openclaw" &&
settingsData?.enableLocalProxy && (
<>
<ProxyToggle activeApp={activeApp} />
<div
className={cn(
"transition-all duration-300 ease-in-out overflow-hidden",
isCurrentAppTakeoverActive
? "opacity-100 max-w-[100px] scale-100"
: "opacity-0 max-w-0 scale-75 pointer-events-none",
)}
>
<FailoverToggle activeApp={activeApp} />
</div>
</>
)}
<AppSwitcher
activeApp={activeApp}

View File

@@ -408,9 +408,6 @@ export function ProxyPanel() {
</div>
) : (
<div className="space-y-6">
{/* 空白区域避免冲突 */}
<div className="h-4"></div>
{/* 基础设置 - 监听地址/端口 */}
<div className="rounded-lg border border-border bg-muted/40 p-4 space-y-4">
<div>

View File

@@ -55,6 +55,7 @@ import { useImportExport } from "@/hooks/useImportExport";
import { useTranslation } from "react-i18next";
import type { SettingsFormState } from "@/hooks/useSettings";
import { Switch } from "@/components/ui/switch";
import { ToggleRow } from "@/components/ui/toggle-row";
import { Badge } from "@/components/ui/badge";
import { useProxyStatus } from "@/hooks/useProxyStatus";
@@ -356,8 +357,21 @@ export function SettingsPage({
/>
</div>
</AccordionPrimitive.Header>
<AccordionContent className="px-6 pb-6 pt-0 border-t border-border/50">
<ProxyPanel />
<AccordionContent className="px-6 pb-6 pt-4 border-t border-border/50">
<ToggleRow
icon={<Zap className="h-4 w-4 text-green-500" />}
title={t("settings.advanced.proxy.enableFeature")}
description={t(
"settings.advanced.proxy.enableFeatureDescription",
)}
checked={settings?.enableLocalProxy ?? false}
onCheckedChange={(checked) =>
handleAutoSave({ enableLocalProxy: checked })
}
/>
<div className="mt-4">
<ProxyPanel />
</div>
</AccordionContent>
</AccordionItem>

View File

@@ -192,6 +192,8 @@
"proxy": {
"title": "Local Proxy",
"description": "Control proxy service toggle, view status and port info",
"enableFeature": "Show Proxy Toggle on Main Page",
"enableFeatureDescription": "When enabled, the proxy and failover toggles will appear at the top of the main page",
"running": "Running",
"stopped": "Stopped"
},

View File

@@ -192,6 +192,8 @@
"proxy": {
"title": "ローカルプロキシ",
"description": "プロキシサービスの切り替え、ステータスとポート情報を表示",
"enableFeature": "メインページにプロキシ切り替えを表示",
"enableFeatureDescription": "有効にすると、メインページ上部にプロキシとフェイルオーバーの切り替えが表示されます",
"running": "実行中",
"stopped": "停止中"
},

View File

@@ -192,6 +192,8 @@
"proxy": {
"title": "本地代理",
"description": "控制代理服务开关、查看状态与端口信息",
"enableFeature": "在主页面显示本地代理开关",
"enableFeatureDescription": "开启后,主页面顶部将显示代理和故障转移开关",
"running": "运行中",
"stopped": "已停止"
},

View File

@@ -14,6 +14,7 @@ export const settingsSchema = z.object({
enableClaudePluginIntegration: z.boolean().optional(),
skipClaudeOnboarding: z.boolean().optional(),
launchOnStartup: z.boolean().optional(),
enableLocalProxy: z.boolean().optional(),
language: z.enum(["en", "zh", "ja"]).optional(),
// 设备级目录覆盖

View File

@@ -212,6 +212,8 @@ export interface Settings {
launchOnStartup?: boolean;
// 静默启动(程序启动时不显示主窗口)
silentStartup?: boolean;
// 是否启用主页面本地代理功能(默认关闭)
enableLocalProxy?: boolean;
// 首选语言(可选,默认中文)
language?: "en" | "zh" | "ja";