代码修改

This commit is contained in:
董宏凯 committed 2026-07-24 14:12:42 +08:00
1 parent 91ba47bf47
commit 25153dbd84
31 files changed
+536 -62

No files matched your search

@@ -580,6 +580,21 @@ html.iceblue .light-topnav-item--active::after {
background: #3d6e96;
}
/* Pale yellow has the same light-banner contrast requirement as ice blue. */
html.lightyellow .light-topnav-item {
color: rgba(48, 61, 35, 0.78);
}
html.lightyellow .light-topnav-item:hover,
html.lightyellow .light-topnav-item--active,
html.lightyellow .light-topnav-item--active:hover {
color: #303d23;
}
html.lightyellow .light-topnav-item--active::after {
background: #4c6330;
}
/* ── 侧边栏:二级图标卡片列(96px)+ 右侧三级列(展开时整体变宽,带过渡)──────── */
.light-sidebar {
position: fixed;
@@ -24,12 +24,52 @@ const AGENT_COLORS_DARK = [
{ from: "#69B1FF", to: "#003EB3" }, // 浅蓝 → 主色按下
] as const;
/** 按 agent id 稳定散列出一对渐变色(from → to)。`isDark` 切换深蓝/浅色调色板。 */
export function agentColor(id: string, isDark: boolean) {
/** 按 agent id 稳定散列出一对渐变色,并根据当前主题返回可读的图标前景色。 */
const AGENT_COLORS_ICEBLUE = [
{ from: "#eff8fd", to: "#b7dcf5" },
{ from: "#e3f2fb", to: "#9bcef1" },
{ from: "#ebf6fb", to: "#add8e9" },
{ from: "#edf2fc", to: "#b7cdef" },
{ from: "#e9f7f5", to: "#afe0dc" },
] as const;
const AGENT_COLORS_LIGHTYELLOW = [
{ from: "#fbfdef", to: "#e4efbf" },
{ from: "#f7fae9", to: "#F3FBD9" },
{ from: "#f9fbe8", to: "#dcebad" },
{ from: "#faf8e9", to: "#e7dfb9" },
{ from: "#f1f8e5", to: "#cce0af" },
] as const;
type AgentAvatarTheme =
| "dark"
| "iceblue"
| "lightyellow"
| "light"
| "lightblue"
| "lightgreen";
/** Returns a stable avatar gradient and readable icon color for each theme. */
export function agentColor(id: string, theme: AgentAvatarTheme) {
let hash = 0;
for (let i = 0; i < id.length; i++) {
hash = (hash * 31 + id.charCodeAt(i)) >>> 0;
}
const palette = isDark ? AGENT_COLORS_DARK : AGENT_COLORS_LIGHT;
return palette[hash % palette.length]!;
const palette =
theme === "dark"
? AGENT_COLORS_DARK
: theme === "iceblue"
? AGENT_COLORS_ICEBLUE
: theme === "lightyellow"
? AGENT_COLORS_LIGHTYELLOW
: AGENT_COLORS_LIGHT;
return {
...palette[hash % palette.length]!,
foreground:
theme === "iceblue"
? "#2d587a"
: theme === "lightyellow"
? "#4c6330"
: "#ffffff",
};
}
@@ -254,7 +254,7 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
{agents.map((agent) => {
const href = `${routeBase}/agents/${agent.id}/chats/new`;
const isActive = agent.id === activeAgentId;
const { from, to } = agentColor(agent.id, isDark);
const { from, to, foreground } = agentColor(agent.id, theme);
return (
<Link
key={agent.id}
@@ -279,6 +279,7 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
)}
style={{
backgroundImage: `linear-gradient(135deg, ${from}, ${to})`,
color: foreground,
}}
>
<Bot className="size-[19px]" />
@@ -206,7 +206,7 @@ export function AgentModuleSidebar({
const renderAgentCard = (agent: Agent, keyPrefix: string) => {
const href = `${routeBase}/agents/${agent.id}/chats/new`;
const isActive = agent.id === activeAgentId;
const { from, to } = agentColor(agent.id, isDark);
const { from, to, foreground } = agentColor(agent.id, theme);
return (
<Link
key={`${keyPrefix}:${agent.id}`}
@@ -236,7 +236,10 @@ export function AgentModuleSidebar({
isActive &&
"ring-2 ring-[#83c1ff]/35 shadow-[0_0_18px_rgba(43,143,254,0.45)]",
)}
style={{ backgroundImage: `linear-gradient(135deg, ${from}, ${to})` }}
style={{
backgroundImage: `linear-gradient(135deg, ${from}, ${to})`,
color: foreground,
}}
>
<Bot className="size-[19px]" />
</span>
@@ -28,12 +28,13 @@ import { buildLightAppUrl } from "@/strategy-components/lib/light-app";
*/
export type AppearanceControlTone = "banner-dark" | "banner-light" | "content";
// 换肤色板:红色=红白主题(light),蓝色=浅蓝主题(lightblue),冰川蓝=柔和浅蓝主题(iceblue),深蓝色=深色主题(dark)
// 换肤色板:红色=红白主题(light),蓝色=浅蓝主题(lightblue),冰川蓝=柔和浅蓝主题(iceblue),浅黄色=柔和黄主题(lightyellow),深蓝色=深色主题(dark)
export const THEME_SWATCHES: { id: ThemeType; label: string; color: string }[] = [
{ id: "light", label: "红色", color: "#cf1322" },
{ id: "lightgreen", label: "绿色", color: "#07c05f" },
{ id: "lightblue", label: "蓝色", color: "#0062d9" },
{ id: "iceblue", label: "冰川蓝", color: "#9BCEF1" },
{ id: "lightyellow", label: "浅黄色", color: "#F3FBD9" },
{ id: "dark", label: "深蓝色", color: "#002466" },
];
@@ -318,7 +318,7 @@ export function GeneralQaSidebar() {
onClick={handleNewChatClick}
style={{ borderColor: "var(--primary)", color: "var(--primary)" }}
className={cn(
"flex h-10 min-w-0 flex-1 items-center justify-center gap-1.5 rounded-[5px] text-[14px] font-semibold transition-colors",
"gq-new-chat-button flex h-10 min-w-0 flex-1 items-center justify-center gap-1.5 rounded-[5px] text-[14px] font-semibold transition-colors",
"border border-solid",
"bg-[rgb(var(--legacy-primary-rgb)/14%)] hover:bg-[rgb(var(--legacy-primary-rgb)/24%)]",
)}
@@ -342,7 +342,7 @@ export function GeneralQaSidebar() {
<div className="mt-1 flex flex-col gap-1">
{frequent.map((agent) => {
const isActive = activeAgentId === agent.id;
const { from, to } = agentColor(agent.id, isDark);
const { from, to, foreground } = agentColor(agent.id, theme);
return (
<button
key={agent.id}
@@ -366,7 +366,10 @@ export function GeneralQaSidebar() {
isActive &&
"ring-2 ring-[#83c1ff]/35 shadow-[0_0_18px_rgba(43,143,254,0.45)]",
)}
style={{ backgroundImage: `linear-gradient(135deg, ${from}, ${to})` }}
style={{
backgroundImage: `linear-gradient(135deg, ${from}, ${to})`,
color: foreground,
}}
>
<Bot className="size-[19px]" />
</span>
@@ -464,9 +467,9 @@ export function GeneralQaSidebar() {
<Link
href={href}
className={cn(
"relative flex h-9 min-w-0 flex-1 items-center gap-2 rounded-lg px-2.5 text-[13px] transition-colors",
"gq-history-item relative flex h-9 min-w-0 flex-1 items-center gap-2 rounded-lg px-2.5 text-[13px] transition-colors",
isActive
? "border border-primary/40 bg-primary/5 font-medium text-primary"
? "gq-history-item--active border border-primary/40 bg-primary/5 font-medium text-primary"
: "text-muted-foreground hover:bg-accent/60 hover:text-foreground",
)}
>
@@ -214,7 +214,7 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
};
const handleSetGlobalDefault = async (
value: "light" | "dark" | "lightblue" | "lightgreen" | "iceblue",
value: "light" | "dark" | "lightblue" | "lightgreen" | "iceblue" | "lightyellow",
) => {
if (value === globalDefault) return;
try {
@@ -228,7 +228,9 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
? "绿色"
: value === "iceblue"
? "冰川蓝"
: "浅蓝";
: value === "lightyellow"
? "浅黄色"
: "浅蓝";
toast.success(`已将系统默认主题设置为${label}`);
} catch (e) {
toast.error(e instanceof Error ? e.message : "保存失败");
@@ -396,6 +398,12 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
description: t.settings.appearance.iceblueDescription,
icon: SnowflakeIcon,
},
{
id: "lightyellow",
label: t.settings.appearance.lightyellow,
description: t.settings.appearance.lightyellowDescription,
icon: SunIcon,
},
],
[
t.settings.appearance.dark,
@@ -408,6 +416,8 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
t.settings.appearance.lightgreenDescription,
t.settings.appearance.iceblue,
t.settings.appearance.iceblueDescription,
t.settings.appearance.lightyellow,
t.settings.appearance.lightyellowDescription,
],
);
@@ -425,7 +435,7 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
label={option.label}
description={option.description}
active={currentTheme === option.id}
mode={option.id as "light" | "dark" | "lightblue" | "lightgreen" | "iceblue"}
mode={option.id as "light" | "dark" | "lightblue" | "lightgreen" | "iceblue" | "lightyellow"}
onSelect={(value) => setTheme(value)}
/>
))}
@@ -597,6 +607,16 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
<SnowflakeIcon className="mr-1.5 size-4" />
冰川蓝
</Button>
<Button
type="button"
variant={globalDefault === "lightyellow" ? "default" : "outline"}
size="sm"
onClick={() => void handleSetGlobalDefault("lightyellow")}
disabled={updateAppearance.isPending}
>
<SunIcon className="mr-1.5 size-4" />
浅黄色
</Button>
<p className="text-muted-foreground ml-2 text-xs">
当前系统默认:
{globalDefault === "light"
@@ -607,7 +627,9 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
? "绿色"
: globalDefault === "iceblue"
? "冰川蓝"
: "浅蓝"}
: globalDefault === "lightyellow"
? "浅黄色"
: "浅蓝"}
</p>
</div>
</SettingsSection>
@@ -1124,8 +1146,8 @@ function ThemePreviewCard({
label: string;
description: string;
active: boolean;
mode: "light" | "dark" | "lightblue" | "lightgreen" | "iceblue";
onSelect: (mode: "light" | "dark" | "lightblue" | "lightgreen" | "iceblue") => void;
mode: "light" | "dark" | "lightblue" | "lightgreen" | "iceblue" | "lightyellow";
onSelect: (mode: "light" | "dark" | "lightblue" | "lightgreen" | "iceblue" | "lightyellow") => void;
}) {
const previewMode = mode;
return (
@@ -1161,7 +1183,9 @@ function ThemePreviewCard({
? "border-emerald-200 bg-white text-emerald-950"
: previewMode === "iceblue"
? "border-sky-200 bg-[#F7FBFE] text-[#18324A]"
: "border-slate-200 bg-white text-slate-900",
: previewMode === "lightyellow"
? "border-lime-200 bg-[#FCFDF5] text-[#303D23]"
: "border-slate-200 bg-white text-slate-900",
)}
>
<div className="border-border/50 flex items-center gap-2 border-b px-3 py-2">
@@ -1176,7 +1200,9 @@ function ThemePreviewCard({
? "bg-[#07c05f]"
: previewMode === "iceblue"
? "bg-[#9BCEF1]"
: "bg-[#cf1322]",
: previewMode === "lightyellow"
? "bg-[#F3FBD9]"
: "bg-[#cf1322]",
)}
/>
<div className="h-2 w-10 rounded-full bg-current/20" />
@@ -23,19 +23,19 @@ import { cn } from "@/lib/utils";
// 普通导航项:默认中性色,激活态与「新对话」一致——主色浅底 + 主色文字/图标
const NAV_ITEM_CLASS =
"text-sidebar-foreground/80 hover:text-primary rounded-xl h-9 px-3 transition-colors hover:bg-primary/10 " +
"workspace-nav-item text-sidebar-foreground/80 hover:text-primary rounded-xl h-9 px-3 transition-colors hover:bg-primary/10 " +
"data-[active=true]:bg-primary/15 data-[active=true]:text-primary data-[active=true]:shadow-none " +
"dark:hover:bg-primary/15 dark:data-[active=true]:bg-primary/25 dark:data-[active=true]:text-primary-foreground";
// 「新对话」专属:默认仅主色文字/图标(显眼但不是选中态),命中 /chats/new 时才上主色底
const NEW_CHAT_CLASS =
"rounded-xl h-9 px-3 text-primary transition-colors hover:bg-primary/10 hover:text-primary " +
"workspace-nav-new-chat rounded-xl h-9 px-3 text-primary transition-colors hover:bg-primary/10 hover:text-primary " +
"data-[active=true]:bg-primary/15 data-[active=true]:text-primary data-[active=true]:shadow-none " +
"dark:text-primary-foreground dark:hover:bg-primary/15 dark:data-[active=true]:bg-primary/25";
// 紧凑模式(CM 参考图):白卡描边、居中、主色 + 图标
const NEW_CHAT_COMPACT_CLASS =
"h-9 justify-center gap-2 rounded-xl bg-card text-[13px] font-semibold text-foreground transition-colors " +
"workspace-compact-new-chat h-9 justify-center gap-2 rounded-xl bg-card text-[13px] font-semibold text-foreground transition-colors " +
"border border-[rgb(var(--legacy-primary-rgb)/18%)] " +
"hover:bg-[rgb(var(--legacy-primary-rgb)/4%)] hover:text-[var(--primary)] hover:border-[rgb(var(--legacy-primary-rgb)/32%)] " +
"data-[active=true]:bg-card data-[active=true]:text-[var(--primary)] data-[active=true]:shadow-none";