From bc01f445142b865ca327ca0eee102011715e2095 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 10 Jun 2026 08:53:36 +0800 Subject: [PATCH] feat(usage): app-aware hero icon and neutral Codex theme - Replace the fixed Zap glyph in the usage hero with the selected app's brand icon via a new AppGlyph component, reusing APP_ICON_MAP (cloneElement scales 14px -> 20px); falls back to Zap for the "all" view. - Recolor the Codex title theme from emerald to neutral gray to match OpenAI's monochrome branding. neutral-500/10 stays visible in both light and dark modes, unlike a flat black tint. --- src/components/usage/UsageHero.tsx | 32 +++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/components/usage/UsageHero.tsx b/src/components/usage/UsageHero.tsx index a3173bf77..3ade773f1 100644 --- a/src/components/usage/UsageHero.tsx +++ b/src/components/usage/UsageHero.tsx @@ -1,8 +1,11 @@ +import { cloneElement, isValidElement } from "react"; import { useTranslation } from "react-i18next"; import { motion } from "framer-motion"; import { Card, CardContent } from "@/components/ui/card"; import { useUsageSummaryByApp } from "@/lib/query/usage"; import { cn } from "@/lib/utils"; +import { APP_ICON_MAP } from "@/config/appConfig"; +import type { AppId } from "@/lib/api/types"; import { Activity, ArrowDownToLine, @@ -47,8 +50,10 @@ const TITLE_THEMES: Record = { iconBg: "bg-amber-500/10", }, codex: { - accent: "text-emerald-600 dark:text-emerald-400", - iconBg: "bg-emerald-500/10", + // OpenAI/Codex 走黑白单色调;中性灰在深浅模式都能透出方块底色, + // 不像纯黑 bg-black/10 在深色背景下会糊掉。 + accent: "text-neutral-700 dark:text-neutral-300", + iconBg: "bg-neutral-500/10", }, gemini: { accent: "text-sky-600 dark:text-sky-400", @@ -130,6 +135,27 @@ function deriveCacheWriteState(appTypes: string[]): CacheWriteState { return "partial"; } +/** + * Hero 标题图标:选中具体应用时显示该应用的品牌图标,"全部"时回退到通用闪电。 + * 复用 APP_ICON_MAP(与侧边栏 / 应用切换器同一套图标),用 cloneElement 放大到 + * 与原闪电一致的 20px;品牌图标自带配色,外层方块仍按 titleTheme 主题色着色。 + */ +function AppGlyph({ + appType, + accentClass, +}: { + appType?: string; + accentClass: string; +}) { + if (appType && appType in APP_ICON_MAP) { + const base = APP_ICON_MAP[appType as AppId].icon; + if (isValidElement<{ size?: number }>(base)) { + return cloneElement(base, { size: 20 }); + } + } + return ; +} + export function UsageHero({ range, appType, @@ -217,7 +243,7 @@ export function UsageHero({ titleTheme.iconBg, )} > - +