feat: polish logo card with svg transitions

This commit is contained in:
JOJO 2025-11-22 00:14:40 +08:00
parent 411cbf71ee
commit 6e8321cf7e
4 changed files with 110 additions and 56 deletions

View File

@ -71,7 +71,8 @@ const ICONS = Object.freeze({
triangleAlert: '/static/icons/triangle-alert.svg', triangleAlert: '/static/icons/triangle-alert.svg',
user: '/static/icons/user.svg', user: '/static/icons/user.svg',
wrench: '/static/icons/wrench.svg', wrench: '/static/icons/wrench.svg',
x: '/static/icons/x.svg' x: '/static/icons/x.svg',
zap: '/static/icons/zap.svg'
}); });
const TOOL_ICON_MAP = Object.freeze({ const TOOL_ICON_MAP = Object.freeze({
@ -219,12 +220,12 @@ async function bootstrapApp() {
autoScrollEnabled: true, autoScrollEnabled: true,
// 面板宽度控制 // 面板宽度控制
leftWidth: 280, leftWidth: 350,
rightWidth: 420, rightWidth: 420,
rightCollapsed: true, rightCollapsed: true,
isResizing: false, isResizing: false,
resizingPanel: null, resizingPanel: null,
minPanelWidth: 200, minPanelWidth: 350,
maxPanelWidth: 600, maxPanelWidth: 600,
// 工具状态跟踪 // 工具状态跟踪

13
static/icons/zap.svg Normal file
View File

@ -0,0 +1,13 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M13 2L3 14h9l-1 8 10-12h-9z" />
</svg>

After

Width:  |  Height:  |  Size: 251 B

View File

@ -168,21 +168,30 @@
<aside class="sidebar left-sidebar" :style="{ width: leftWidth + 'px' }"> <aside class="sidebar left-sidebar" :style="{ width: leftWidth + 'px' }">
<div class="sidebar-status"> <div class="sidebar-status">
<div class="compact-status-card"> <div class="compact-status-card">
<div class="status-top"> <div class="status-line">
<span class="logo icon-label"> <div class="status-brand">
<span class="icon icon-md" <span class="icon icon-lg status-logo"
:style="iconStyle('bot')" :style="iconStyle('bot')"
aria-hidden="true"></span> aria-hidden="true"></span>
<span>AI Agent</span> <div class="brand-text">
</span> <span class="brand-name">AI Agent</span>
<span class="agent-version" v-if="agentVersion">{{ agentVersion }}</span> <span class="agent-version" v-if="agentVersion">{{ agentVersion }}</span>
</div> </div>
<div class="status-bottom"> </div>
<span class="thinking-chip">{{ thinkingMode ? '思考模式' : '快速模式' }}</span> <div class="status-indicators">
<span class="connection-chip" :class="{ connected: isConnected }"> <span class="mode-indicator"
<span class="status-dot" :class="{ active: isConnected }"></span> :class="{ thinking: thinkingMode, fast: !thinkingMode }">
{{ isConnected ? '已连接' : '未连接' }} <transition name="mode-icon" mode="out-in">
</span> <span class="icon icon-sm"
:style="iconStyle(thinkingMode ? 'brain' : 'zap')"
:key="thinkingMode ? 'brain' : 'zap'"
aria-hidden="true"></span>
</transition>
</span>
<span class="connection-dot"
:class="{ active: isConnected }"
:title="isConnected ? '已连接' : '未连接'"></span>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -108,7 +108,7 @@ body {
.agent-version { .agent-version {
color: var(--claude-text-secondary); color: var(--claude-text-secondary);
font-size: 14px; font-size: 16px;
} }
.header-right { .header-right {
@ -135,19 +135,6 @@ body {
gap: 6px; gap: 6px;
} }
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--claude-muted);
transition: all 0.3s ease;
}
.status-dot.active {
background: var(--claude-success);
box-shadow: 0 0 8px rgba(118, 176, 134, 0.45);
}
/* 主容器 */ /* 主容器 */
.main-container { .main-container {
display: flex; display: flex;
@ -650,47 +637,91 @@ o-conversations {
padding: 14px 16px; padding: 14px 16px;
box-shadow: 0 12px 30px rgba(61, 57, 41, 0.12); box-shadow: 0 12px 30px rgba(61, 57, 41, 0.12);
display: flex; display: flex;
flex-direction: column; align-items: center;
gap: 10px;
} }
.status-top { .status-line {
display: flex; display: flex;
align-items: center;
justify-content: space-between; justify-content: space-between;
align-items: center; width: 100%;
font-size: 15px; gap: 18px;
} }
.status-bottom { .status-brand {
display: flex;
align-items: center;
gap: 12px;
}
.status-logo {
color: var(--claude-accent);
}
.brand-text {
display: flex;
align-items: baseline;
gap: 8px;
font-weight: 600;
color: var(--claude-text);
}
.brand-name {
font-size: 16px;
}
.status-indicators {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
flex-wrap: wrap;
} }
.thinking-chip { .mode-indicator {
background: var(--claude-accent); width: 36px;
color: #fffef8; height: 36px;
padding: 4px 14px; border-radius: 18px;
border-radius: 999px;
font-size: 12px;
letter-spacing: 0.02em;
}
.connection-chip {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 6px; justify-content: center;
padding: 4px 12px; background: var(--claude-accent);
border-radius: 999px; color: #fffef8;
border: 1px solid rgba(118, 103, 84, 0.3); box-shadow: 0 8px 20px rgba(189, 93, 58, 0.25);
font-size: 12px; transition: background 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
color: var(--claude-text-secondary);
} }
.connection-chip.connected { .mode-indicator.fast {
border-color: rgba(94, 159, 109, 0.5); background: #ffcc4d;
color: var(--claude-text); box-shadow: 0 8px 20px rgba(255, 204, 77, 0.35);
}
.mode-indicator .icon {
--icon-size: 18px;
color: inherit;
}
.connection-dot {
width: 12px;
height: 12px;
border-radius: 6px;
background: var(--claude-muted);
box-shadow: 0 0 0 4px rgba(121, 109, 94, 0.18);
transition: background 0.2s ease, box-shadow 0.2s ease;
}
.connection-dot.active {
background: var(--claude-success);
box-shadow: 0 0 0 6px rgba(118, 176, 134, 0.25);
}
.mode-icon-enter-active,
.mode-icon-leave-active {
transition: opacity 0.2s ease, transform 0.2s ease;
}
.mode-icon-enter-from,
.mode-icon-leave-to {
opacity: 0;
transform: scale(0.5) rotate(8deg);
} }
.sidebar-header { .sidebar-header {