diff --git a/src/renderer/components/workspace-panel.ts b/src/renderer/components/workspace-panel.ts index 833e803..a887ae7 100644 --- a/src/renderer/components/workspace-panel.ts +++ b/src/renderer/components/workspace-panel.ts @@ -47,6 +47,22 @@ let fileTree: FileNode[] = []; let previewFile: { name: string; content: string; path: string } | null = null; let _counter = 0; +// ── 空闲状态轮转贴士 ── +const IDLE_TIPS = [ + '💡 可以让我读取文件、搜索代码、执行命令', + '💡 试试说"帮我看看这个目录里有什么"', + '💡 我可以联网搜索并抓取网页内容', + '💡 支持 Git 操作:状态查看、提交、分支管理', + '💡 我能记住你说过的重要信息,跨会话保留', + '💡 上传图片让我分析,支持 Vision 模型', + '💡 说"搜索..."我会自动联网查找最新信息', + '💡 我会从成功经验中学习,越用越聪明', + '💡 可以让我对比文件差异、批量替换文本', + '💡 支持浏览器控制,帮你操作网页', +]; +let tipIndex = Math.floor(Math.random() * IDLE_TIPS.length); +let tipTimer: ReturnType | null = null; + /** 工具调用卡片列表 */ let toolCards: ToolCallRecord[] = []; let toolAutoScroll = true; @@ -491,8 +507,17 @@ function renderTerminal(): void { return; } + // 空闲状态:显示 Logo + 信息 + 贴士 + if (session.lines.length === 0 && !session.running) { + renderIdleState(container); + startTipRotation(container); + return; + } + + // 有内容时停止贴士轮转 + stopTipRotation(); + // 使用 DocumentFragment 优化渲染 - const fragment = document.createDocumentFragment(); const wrapper = document.createElement('div'); for (const line of session.lines) { @@ -516,6 +541,74 @@ function renderTerminal(): void { }; } +/** 渲染空闲状态 */ +function renderIdleState(container: HTMLElement): void { + const tip = IDLE_TIPS[tipIndex]; + const dirDisplay = workspaceDir + ? workspaceDir.replace(/.*[/\\]/, '~/.') + : '未设置'; + + // 截取目录最后一段 + const shortDir = workspaceDir + ? '...' + workspaceDir.slice(-30) + : '未设置'; + + container.innerHTML = ` +
+ +
+
+ 工作空间 + ${escapeHtml(shortDir)} +
+
+
+
${escapeHtml(tip)}
+
+ `; + + // 重置滚动 + container.scrollTop = 0; +} + +/** 启动贴士轮转 */ +function startTipRotation(container: HTMLElement): void { + if (tipTimer) return; + tipTimer = setInterval(() => { + // 只在空闲状态时轮转 + const session = getActiveSession(); + if (!session || session.lines.length > 0 || session.running) { + stopTipRotation(); + return; + } + tipIndex = (tipIndex + 1) % IDLE_TIPS.length; + const tipEl = container.querySelector('#wsIdleTip'); + if (tipEl) { + tipEl.classList.add('fading'); + setTimeout(() => { + tipEl.textContent = IDLE_TIPS[tipIndex]; + tipEl.classList.remove('fading'); + }, 300); + } + }, 6000); +} + +/** 停止贴士轮转 */ +function stopTipRotation(): void { + if (tipTimer) { + clearInterval(tipTimer); + tipTimer = null; + } +} + function renderFileList(): void { const container = document.querySelector('#wsFileList') as HTMLElement; if (!container) return; diff --git a/src/renderer/styles/style.css b/src/renderer/styles/style.css index 5233dc8..a6cc084 100644 --- a/src/renderer/styles/style.css +++ b/src/renderer/styles/style.css @@ -2351,6 +2351,89 @@ html, body { font-family: var(--font); } +/* ── 终端空闲状态 ── */ +.ws-idle-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + padding: 20px 16px; + gap: 16px; +} + +.ws-idle-logo { + text-align: center; +} + +.ws-idle-ascii { + font-family: var(--font-mono); + font-size: 13px; + line-height: 1.4; + color: rgba(232, 115, 74, 0.65); + margin: 0; + white-space: pre; + text-shadow: 0 0 20px rgba(232, 115, 74, 0.15); + animation: idle-glow 3s ease-in-out infinite; +} + +@keyframes idle-glow { + 0%, 100% { text-shadow: 0 0 20px rgba(232, 115, 74, 0.1); } + 50% { text-shadow: 0 0 25px rgba(232, 115, 74, 0.25); } +} + +.ws-idle-info { + display: flex; + flex-direction: column; + gap: 6px; + width: 100%; + max-width: 260px; +} + +.ws-idle-info-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + font-size: 11px; +} + +.ws-idle-label { + color: rgba(245, 240, 232, 0.35); + font-family: var(--font); + flex-shrink: 0; +} + +.ws-idle-value { + color: rgba(245, 240, 232, 0.6); + font-family: var(--font-mono); + font-size: 10px; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ws-idle-divider { + width: 60px; + height: 1px; + background: linear-gradient(90deg, transparent, rgba(232, 115, 74, 0.3), transparent); +} + +.ws-idle-tip { + font-size: 11px; + color: rgba(245, 240, 232, 0.45); + font-family: var(--font); + text-align: center; + line-height: 1.5; + max-width: 240px; + transition: opacity 0.3s ease; +} + +.ws-idle-tip.fading { + opacity: 0; +} + /* 工具调用 Tab */ .ws-tools-output { flex: 1;