enhance: dark mode icon

This commit is contained in:
Wendong-Fan 2026-02-02 05:22:21 +08:00
parent dd98dc4d1c
commit 6fe0e62bb7
7 changed files with 199 additions and 83 deletions

69
backend/uv.lock generated
View file

@ -244,6 +244,7 @@ dependencies = [
[package.dev-dependencies]
dev = [
{ name = "babel" },
{ name = "pre-commit" },
{ name = "pytest" },
{ name = "pytest-asyncio" },
]
@ -273,6 +274,7 @@ requires-dist = [
[package.metadata.requires-dev]
dev = [
{ name = "babel", specifier = ">=2.17.0" },
{ name = "pre-commit", specifier = ">=4.0.0" },
{ name = "pytest", specifier = ">=8.4.1" },
{ name = "pytest-asyncio", specifier = ">=1.1.0" },
]
@ -391,6 +393,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790 },
]
[[package]]
name = "cfgv"
version = "3.5.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445 },
]
[[package]]
name = "chardet"
version = "5.2.0"
@ -587,6 +598,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c9/7a/cef76fd8438a42f96db64ddaa85280485a9c395e7df3db8158cfec1eee34/dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7", size = 116252 },
]
[[package]]
name = "distlib"
version = "0.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047 },
]
[[package]]
name = "distro"
version = "1.9.0"
@ -1020,6 +1040,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794 },
]
[[package]]
name = "identify"
version = "2.6.16"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5b/8d/e8b97e6bd3fb6fb271346f7981362f1e04d6a7463abd0de79e1fda17c067/identify-2.6.16.tar.gz", hash = "sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980", size = 99360 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b8/58/40fbbcefeda82364720eba5cf2270f98496bdfa19ea75b4cccae79c698e6/identify-2.6.16-py2.py3-none-any.whl", hash = "sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0", size = 99202 },
]
[[package]]
name = "idna"
version = "3.11"
@ -1388,6 +1417,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/da/d9/f7f9379981e39b8c2511c9e0326d212accacb82f12fbfdc1aa2ce2a7b2b6/multiprocess-0.70.16-py39-none-any.whl", hash = "sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3", size = 133351 },
]
[[package]]
name = "nodeenv"
version = "1.10.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438 },
]
[[package]]
name = "nodejs-wheel"
version = "24.13.0"
@ -1681,6 +1719,22 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 },
]
[[package]]
name = "pre-commit"
version = "4.5.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cfgv" },
{ name = "identify" },
{ name = "nodeenv" },
{ name = "pyyaml" },
{ name = "virtualenv" },
]
sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437 },
]
[[package]]
name = "propcache"
version = "0.4.1"
@ -2473,6 +2527,21 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/bb/ce/8491fd370b0230deb5eac69c7aae35b3be527e25a911c0acdffb922dc1cd/uvloop-0.22.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1489cf791aa7b6e8c8be1c5a080bae3a672791fcb4e9e12249b05862a2ca9cec", size = 3615261 },
]
[[package]]
name = "virtualenv"
version = "20.36.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "distlib" },
{ name = "filelock" },
{ name = "platformdirs" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/aa/a3/4d310fa5f00863544e1d0f4de93bddec248499ccf97d4791bc3122c9d4f3/virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba", size = 6032239 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f", size = 6008258 },
]
[[package]]
name = "watchfiles"
version = "1.1.1"

View file

@ -133,7 +133,7 @@ export default function FolderComponent({ selectedFile }: Props) {
return (
<div
className="w-full overflow-auto"
className="folder-component-content w-full overflow-auto text-text-primary"
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
/>
);

View file

@ -12,8 +12,8 @@
// limitations under the License.
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
import { ZoomOut, ZoomIn, RotateCcw } from "lucide-react";
import { Button } from "../ui/button";
import { RotateCcw, ZoomIn, ZoomOut } from 'lucide-react';
import { Button } from '../ui/button';
// Zoom Controls Component
interface ZoomControlsProps {
@ -23,40 +23,47 @@ interface ZoomControlsProps {
onZoomReset: () => void;
}
export const ZoomControls = ({ zoom, onZoomIn, onZoomOut, onZoomReset }: ZoomControlsProps) => {
export const ZoomControls = ({
zoom,
onZoomIn,
onZoomOut,
onZoomReset,
}: ZoomControlsProps) => {
return (
<div className="absolute top-0 left-1/2 -translate-x-1/2 z-10 group">
<div className="flex items-center gap-1 px-3 py-1.5 bg-surface-hover-subtle/90 backdrop-blur-xl rounded-full shadow-lg border border-border-subtle-strong/50 translate-y-[calc(-100%-8px)] group-hover:translate-y-[20px] transition-transform duration-300 ease-out">
<div className="group absolute left-1/2 top-0 z-10 -translate-x-1/2">
<div className="bg-surface-hover-subtle/90 border-border-subtle-strong/50 flex translate-y-[calc(-100%-8px)] items-center gap-1 rounded-full border px-3 py-1.5 shadow-lg backdrop-blur-xl transition-transform duration-300 ease-out group-hover:translate-y-[20px]">
<Button
size="icon"
variant="ghost"
onClick={onZoomOut}
title="Zoom Out"
className="h-7 w-7 hover:bg-gray-200/60 text-gray-700 hover:text-gray-900"
className="h-7 w-7 text-text-secondary hover:bg-fill-fill-transparent-hover hover:text-text-primary"
>
<ZoomOut className="w-3.5 h-3.5" />
<ZoomOut className="h-3.5 w-3.5" />
</Button>
<span className="text-xs text-gray-800 min-w-[2.5rem] text-center font-medium tabular-nums">{zoom}%</span>
<span className="min-w-[2.5rem] text-center text-xs font-medium tabular-nums text-text-primary">
{zoom}%
</span>
<Button
size="icon"
variant="ghost"
onClick={onZoomIn}
title="Zoom In"
className="h-7 w-7 hover:bg-gray-200/60 text-gray-700 hover:text-gray-900"
className="h-7 w-7 text-text-secondary hover:bg-fill-fill-transparent-hover hover:text-text-primary"
>
<ZoomIn className="w-3.5 h-3.5" />
<ZoomIn className="h-3.5 w-3.5" />
</Button>
<div className="w-px h-4 bg-gray-300/60 mx-0.5" />
<div className="mx-0.5 h-4 w-px bg-border-secondary" />
<Button
size="icon"
variant="ghost"
onClick={onZoomReset}
title="Reset Zoom"
className="h-7 w-7 hover:bg-gray-200/60 text-gray-700 hover:text-gray-900"
className="h-7 w-7 text-text-secondary hover:bg-fill-fill-transparent-hover hover:text-text-primary"
>
<RotateCcw className="w-3.5 h-3.5" />
<RotateCcw className="h-3.5 w-3.5" />
</Button>
</div>
</div>
);
}
};

View file

@ -129,8 +129,9 @@ const FileTree: React.FC<FileTreeProps> = ({
)}
<span
className={`truncate text-[13px] leading-5 ${child.isFolder ? 'font-semibold' : 'font-medium'
}`}
className={`truncate text-[13px] leading-5 ${
child.isFolder ? 'font-semibold' : 'font-medium'
}`}
>
{child.name}
</span>
@ -421,7 +422,7 @@ export default function Folder({ data: _data }: { data?: Agent }) {
<div
className={`${
isCollapsed ? 'w-16' : 'w-64'
} flex flex-shrink-0 flex-col border-[0px] border-r !border-solid border-r-border-subtle border-border-subtle-strong transition-all duration-300 ease-in-out`}
} flex flex-shrink-0 flex-col border-[0px] border-r !border-solid border-border-subtle-strong border-r-border-subtle transition-all duration-300 ease-in-out`}
>
{/* head */}
<div
@ -449,12 +450,13 @@ export default function Folder({ data: _data }: { data?: Agent }) {
variant="ghost"
size="icon"
onClick={() => setIsCollapsed(!isCollapsed)}
className={`${isCollapsed ? 'w-full' : ''
} flex items-center justify-center`}
className={`${
isCollapsed ? 'w-full' : ''
} flex items-center justify-center`}
title={isCollapsed ? t('chat.open') : t('chat.close')}
>
<ChevronsLeft
className={`h-6 w-6 text-zinc-500 ${
className={`h-6 w-6 text-icon-secondary ${
isCollapsed ? 'rotate-180' : ''
} transition-transform ease-in-out`}
/>
@ -506,8 +508,8 @@ export default function Folder({ data: _data }: { data?: Agent }) {
onClick={() => selectedFileChange(file, isShowSourceCode)}
className={`flex w-full items-center justify-center rounded-md p-2 transition-colors hover:bg-fill-fill-primary-hover ${
selectedFile?.name === file.name
? 'bg-blue-50 text-blue-700'
: 'text-zinc-600'
? 'bg-surface-information text-text-information'
: 'text-text-secondary'
}`}
title={file.name}
>
@ -548,7 +550,7 @@ export default function Folder({ data: _data }: { data?: Agent }) {
{selectedFile.name}
</span>
<Button size="icon" variant="ghost">
<Download className="h-4 w-4 text-zinc-500" />
<Download className="h-4 w-4 text-icon-secondary" />
</Button>
</div>
<Button
@ -557,7 +559,7 @@ export default function Folder({ data: _data }: { data?: Agent }) {
className="flex-shrink-0"
onClick={() => isShowSourceCodeChange()}
>
<CodeXml className="h-4 w-4 text-zinc-500" />
<CodeXml className="h-4 w-4 text-icon-secondary" />
</Button>
</div>
</div>
@ -591,8 +593,8 @@ export default function Folder({ data: _data }: { data?: Agent }) {
title={selectedFile.name}
/>
) : ['csv', 'doc', 'docx', 'pptx', 'xlsx'].includes(
selectedFile.type
) ? (
selectedFile.type
) ? (
<FolderComponent selectedFile={selectedFile} />
) : selectedFile.type === 'html' ? (
isShowSourceCode ? (
@ -604,9 +606,9 @@ export default function Folder({ data: _data }: { data?: Agent }) {
/>
)
) : selectedFile.type === 'zip' ? (
<div className="flex h-full items-center justify-center text-zinc-500">
<div className="flex h-full items-center justify-center text-text-secondary">
<div className="text-center">
<FileText className="mx-auto mb-4 h-12 w-12 text-zinc-300" />
<FileText className="mx-auto mb-4 h-12 w-12 text-text-tertiary" />
<p className="text-sm">
{t('folder.zip-file-is-not-supported-yet')}
</p>
@ -625,7 +627,7 @@ export default function Folder({ data: _data }: { data?: Agent }) {
<ImageLoader selectedFile={selectedFile} />
</div>
) : (
<pre className="overflow-x-auto whitespace-pre-wrap break-words font-mono text-sm text-zinc-700">
<pre className="overflow-x-auto whitespace-pre-wrap break-words font-mono text-sm text-text-primary">
{selectedFile.content}
</pre>
)
@ -633,14 +635,16 @@ export default function Folder({ data: _data }: { data?: Agent }) {
<div className="flex h-full items-center justify-center">
<div className="text-center">
<div className="mx-auto mb-4 h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600"></div>
<p className="text-sm text-zinc-500">{t('chat.loading')}</p>
<p className="text-sm text-text-secondary">
{t('chat.loading')}
</p>
</div>
</div>
)
) : (
<div className="flex h-full items-center justify-center text-zinc-500">
<div className="flex h-full items-center justify-center text-text-secondary">
<div className="text-center">
<FileText className="mx-auto mb-4 h-12 w-12 text-zinc-300" />
<FileText className="mx-auto mb-4 h-12 w-12 text-text-tertiary" />
<p className="text-sm">
{t('chat.select-a-file-to-view-its-contents')}
</p>

View file

@ -18,16 +18,16 @@ import {
proxyFetchDelete,
proxyFetchGet,
} from '@/api/http';
import folderIconWhite from '@/assets/logo/icon_white.svg';
import folderIconBlack from '@/assets/logo/icon_black.svg';
import giftIcon from '@/assets/gift.svg';
import giftWhiteIcon from '@/assets/gift-white.svg';
import giftIcon from '@/assets/gift.svg';
import folderIconBlack from '@/assets/logo/icon_black.svg';
import folderIconWhite from '@/assets/logo/icon_white.svg';
import EndNoticeDialog from '@/components/Dialog/EndNotice';
import { Button } from '@/components/ui/button';
import { TooltipSimple } from '@/components/ui/tooltip';
import useChatStoreAdapter from '@/hooks/useChatStoreAdapter';
import { share } from '@/lib/share';
import { getAuthStore, useAuthStore } from '@/store/authStore';
import { useAuthStore } from '@/store/authStore';
import { useSidebarStore } from '@/store/sidebarStore';
import {
ChevronDown,
@ -63,7 +63,7 @@ function HeaderWin() {
const p = window.electronAPI.getPlatform();
setPlatform(p);
}, []);
const logoSrc = appearance === 'light' ? folderIconBlack : folderIconWhite;
const logoSrc = appearance === 'dark' ? folderIconWhite : folderIconBlack;
const exportLog = async () => {
try {
@ -399,7 +399,7 @@ function HeaderWin() {
className="no-drag"
>
<img
src={appearance === 'light' ? giftIcon : giftWhiteIcon}
src={appearance === 'dark' ? giftWhiteIcon : giftIcon}
alt="gift-icon"
className="h-4 w-4"
/>

View file

@ -73,17 +73,23 @@ body {
button .lucide,
a .lucide,
.lucide[data-state="active"] {
.lucide[data-state='active'] {
color: var(--icon-primary);
}
:is(.bg-white, .bg-white-100, .bg-white-50, [class*="bg-white-100%"], [class*="bg-white-50"]) {
:is(
.bg-white,
.bg-white-100,
.bg-white-50,
[class*='bg-white-100%'],
[class*='bg-white-50']
) {
color: var(--text-primary);
background-color: var(--surface-card) !important;
box-shadow: none;
}
[class*="bg-white-50"] {
[class*='bg-white-50'] {
background-color: var(--surface-tertiary) !important;
}
@ -92,11 +98,11 @@ body {
transition: filter 150ms ease;
}
[data-theme="dark"] .theme-image-invert-dark {
[data-theme='dark'] .theme-image-invert-dark {
filter: brightness(0) invert(1);
}
[data-theme="transparent"] .theme-image-invert-dark {
[data-theme='transparent'] .theme-image-invert-dark {
filter: brightness(0) invert(1);
}
}
@ -488,3 +494,35 @@ code {
padding-left: 1rem;
font-size: 12px; /* text-sm */
}
/* Dark mode overrides for FolderComponent (CSV/table content) */
[data-theme='dark'] .folder-component-content {
color: var(--text-primary);
}
[data-theme='dark'] .folder-component-content * {
color: inherit;
}
[data-theme='dark'] .folder-component-content table {
border-collapse: collapse;
}
[data-theme='dark'] .folder-component-content table th,
[data-theme='dark'] .folder-component-content table td {
border-color: #30363d !important;
color: var(--text-primary) !important;
}
[data-theme='dark'] .folder-component-content table th {
background-color: #161b22 !important;
}
[data-theme='dark'] .folder-component-content table tr {
background-color: transparent !important;
border-top-color: #30363d !important;
}
[data-theme='dark'] .folder-component-content table tr:nth-child(2n) {
background-color: rgba(110, 118, 129, 0.1) !important;
}

View file

@ -154,55 +154,53 @@
border: 0;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
.markdown-body {
color: #e6edf3;
}
/* Dark mode support - matches app's data-theme attribute */
[data-theme='dark'] .markdown-body {
color: #e6edf3;
}
.markdown-body h1,
.markdown-body h2 {
border-bottom-color: #30363d;
}
[data-theme='dark'] .markdown-body h1,
[data-theme='dark'] .markdown-body h2 {
border-bottom-color: #30363d;
}
.markdown-body pre {
background-color: #161b22;
}
[data-theme='dark'] .markdown-body pre {
background-color: #161b22;
}
.markdown-body code {
background-color: rgba(110, 118, 129, 0.4);
}
[data-theme='dark'] .markdown-body code {
background-color: rgba(110, 118, 129, 0.4);
}
.markdown-body table th {
background-color: #161b22;
}
[data-theme='dark'] .markdown-body table th {
background-color: #161b22;
}
.markdown-body table th,
.markdown-body table td {
border-color: #30363d;
}
[data-theme='dark'] .markdown-body table th,
[data-theme='dark'] .markdown-body table td {
border-color: #30363d;
}
.markdown-body table tr {
background-color: transparent;
border-top-color: #30363d;
}
[data-theme='dark'] .markdown-body table tr {
background-color: transparent;
border-top-color: #30363d;
}
.markdown-body table tr:nth-child(2n) {
background-color: rgba(110, 118, 129, 0.1);
}
[data-theme='dark'] .markdown-body table tr:nth-child(2n) {
background-color: rgba(110, 118, 129, 0.1);
}
.markdown-body blockquote {
color: #8b949e;
border-left-color: #30363d;
}
[data-theme='dark'] .markdown-body blockquote {
color: #8b949e;
border-left-color: #30363d;
}
.markdown-body a {
color: #58a6ff;
}
[data-theme='dark'] .markdown-body a {
color: #58a6ff;
}
.markdown-body hr {
background-color: #30363d;
}
[data-theme='dark'] .markdown-body hr {
background-color: #30363d;
}
/* Task list styling */