"use client"; import { DropletIcon, LayoutGridIcon, LayoutIcon, ListIcon, MoonIcon, PanelLeftIcon, SunIcon } from "lucide-react"; import { useMemo, type ComponentType, type SVGProps } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; import { useTheme } from "@/contexts/ThemeContext"; import { FONT_SCALE_OPTIONS } from "@/components/font-scale"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Separator } from "@/components/ui/separator"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; import { getStoredAuth } from "@/core/auth"; import { enUS, isLocale, zhCN, type Locale } from "@/core/i18n"; import { useI18n } from "@/core/i18n/hooks"; import { useLocalSettings } from "@/core/settings"; import { useAppearanceSettings, useCitationDisplaySettings, useUpdateAppearanceSettings, useUpdateCitationDisplaySettings, } from "@/core/system-settings/hooks"; import { cn } from "@/lib/utils"; import PrivateSquareSettingsPage from "@/pages/PrivateSquareSettingsPage"; import PublishSquaresSettingsPage from "@/pages/PublishSquaresSettingsPage"; import PromptPrefixSettingsPage from "@/pages/PromptPrefixSettingsPage"; import RecommendedQuestionsPage from "@/pages/RecommendedQuestionsPage"; import { SettingsSection } from "./settings-section"; const languageOptions: { value: Locale; label: string }[] = [ { value: "en-US", label: enUS.locale.localName }, { value: "zh-CN", label: zhCN.locale.localName }, ]; export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) { const { t, locale, changeLocale } = useI18n(); const { theme, setTheme } = useTheme(); const navigate = useNavigate(); const currentTheme = theme; const [settings, setSettings] = useLocalSettings(); const isAdmin = getStoredAuth()?.system_role === "admin"; const { data: appearance } = useAppearanceSettings(); const updateAppearance = useUpdateAppearanceSettings(); const { data: citationDisplay } = useCitationDisplaySettings(); const updateCitationDisplay = useUpdateCitationDisplaySettings(); const globalDefault = appearance?.default_theme ?? "light"; const globalSkillView = appearance?.default_skill_view ?? "list"; const globalAgentView = appearance?.default_agent_view ?? "card"; const cleanupWords = citationDisplay?.cleanup_words ?? settings.display.citationCleanupWords ?? []; const handleSetGlobalDefault = async ( value: "light" | "dark" | "lightblue", ) => { if (value === globalDefault) return; try { await updateAppearance.mutateAsync({ default_theme: value }); const label = value === "light" ? "浅色" : value === "dark" ? "深色" : "浅蓝"; toast.success(`已将系统默认主题设置为${label}`); } catch (e) { toast.error(e instanceof Error ? e.message : "保存失败"); } }; const handleSetDefaultView = async ( kind: "skill" | "agent", value: "card" | "list", ) => { const current = kind === "skill" ? globalSkillView : globalAgentView; if (value === current) return; try { await updateAppearance.mutateAsync( kind === "skill" ? { default_skill_view: value } : { default_agent_view: value }, ); const label = kind === "skill" ? "技能" : "智能体"; toast.success( `已将${label}默认展示模式设置为${value === "card" ? "卡片" : "列表"}`, ); } catch (e) { toast.error(e instanceof Error ? e.message : "保存失败"); } }; const themeOptions = useMemo( () => [ { id: "light", label: t.settings.appearance.light, description: t.settings.appearance.lightDescription, icon: SunIcon, }, { id: "dark", label: t.settings.appearance.dark, description: t.settings.appearance.darkDescription, icon: MoonIcon, }, { id: "lightblue", label: t.settings.appearance.lightblue, description: t.settings.appearance.lightblueDescription, icon: DropletIcon, }, ], [ t.settings.appearance.dark, t.settings.appearance.darkDescription, t.settings.appearance.light, t.settings.appearance.lightDescription, t.settings.appearance.lightblue, t.settings.appearance.lightblueDescription, ], ); return (
当前系统默认: {globalDefault === "light" ? "浅色" : globalDefault === "dark" ? "深色" : "浅蓝"}
当前系统默认:{current === "card" ? "卡片" : "列表"}
在生成回答时显示一个小胶囊,实时估算当前 token/s 并用绿到红的渐变条直观反映快慢。默认开启。
开启后,已配置展示适配的技能结果会在问答中渲染为编号引用或列表,并支持点击跳转。
管理员配置。每行一个词或短句,参考文献卡片和详情弹框会自动移除这些广告词、导航词或免责声明。