feat(settings): set Gemini visibility to false by default

New users will see Claude, Codex, and OpenCode by default, with Gemini hidden.
This commit is contained in:
Jason
2026-01-20 12:28:45 +08:00
parent e7badb1a24
commit 30009ad5f1

View File

@@ -0,0 +1,118 @@
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { ProviderIcon } from "@/components/ProviderIcon";
import type { SettingsFormState } from "@/hooks/useSettings";
import type { VisibleApps } from "@/types";
import type { AppId } from "@/lib/api";
interface AppVisibilitySettingsProps {
settings: SettingsFormState;
onChange: (updates: Partial<SettingsFormState>) => void;
}
const APP_CONFIG: Array<{
id: AppId;
icon: string;
nameKey: string;
}> = [
{ id: "claude", icon: "claude", nameKey: "apps.claude" },
{ id: "codex", icon: "openai", nameKey: "apps.codex" },
{ id: "gemini", icon: "gemini", nameKey: "apps.gemini" },
{ id: "opencode", icon: "opencode", nameKey: "apps.opencode" },
];
export function AppVisibilitySettings({ settings, onChange }: AppVisibilitySettingsProps) {
const { t } = useTranslation();
const visibleApps: VisibleApps = settings.visibleApps ?? {
claude: true,
codex: true,
gemini: false,
opencode: true,
};
// Count how many apps are currently visible
const visibleCount = Object.values(visibleApps).filter(Boolean).length;
const handleToggle = (appId: AppId) => {
const isCurrentlyVisible = visibleApps[appId];
// Prevent disabling the last visible app
if (isCurrentlyVisible && visibleCount <= 1) return;
onChange({
visibleApps: {
...visibleApps,
[appId]: !isCurrentlyVisible,
},
});
};
return (
<section className="space-y-2">
<header className="space-y-1">
<h3 className="text-sm font-medium">{t("settings.appVisibility.title")}</h3>
<p className="text-xs text-muted-foreground">
{t("settings.appVisibility.description")}
</p>
</header>
<div className="inline-flex gap-1 rounded-md border border-border-default bg-background p-1">
{APP_CONFIG.map((app) => {
const isVisible = visibleApps[app.id];
// Disable button if this is the last visible app
const isDisabled = isVisible && visibleCount <= 1;
return (
<AppButton
key={app.id}
active={isVisible}
disabled={isDisabled}
onClick={() => handleToggle(app.id)}
icon={app.icon}
name={t(app.nameKey)}
>
{t(app.nameKey)}
</AppButton>
);
})}
</div>
</section>
);
}
interface AppButtonProps {
active: boolean;
disabled?: boolean;
onClick: () => void;
icon: string;
name: string;
children: React.ReactNode;
}
function AppButton({
active,
disabled,
onClick,
icon,
name,
children,
}: AppButtonProps) {
return (
<Button
type="button"
onClick={onClick}
disabled={disabled}
size="sm"
variant={active ? "default" : "ghost"}
className={cn(
"w-[90px] gap-1.5",
active
? "shadow-sm"
: "text-muted-foreground hover:text-foreground hover:bg-muted",
)}
>
<ProviderIcon icon={icon} name={name} size={14} />
{children}
</Button>
);
}