Compare commits

...
Author SHA1 Message Date
陈大猫 c0932af028 perf(terminal): keep unread activity indicators static 2026-10-22 01:29:03 +08:00
2 changed files with 32 additions and 14 deletions

No files matched your search

+6 -14
View File
@@ -680,21 +680,13 @@ html[data-theme-transition] *::after {
box-shadow: 0 4px 12px hsl(var(--foreground) / 0.06);
}
@keyframes session-activity-breathe {
0%,
100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.1);
opacity: 0.18;
}
}
/* Unread activity remains visible until acknowledged without keeping the
compositor animating after terminal output stops. The 8px status dot plus
its 2px gap and 1px outline fits inside the existing 20px tab content line.
Keep the dot's connection-status color; the extra outline marks unread output. */
.session-activity-dot {
animation: session-activity-breathe 1.4s ease-in-out infinite;
outline: 1px solid color-mix(in srgb, var(--top-tabs-fg, hsl(var(--foreground))) 75%, transparent);
outline-offset: 2px;
}
@keyframes coding-cli-icon-pulse {
+26
View File
@@ -0,0 +1,26 @@
"use strict";
/* global __dirname */
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const test = require("node:test");
const root = path.resolve(__dirname, "..");
const css = fs.readFileSync(path.join(root, "index.css"), "utf8");
const tabs = fs.readFileSync(path.join(root, "components/top-tabs/TopTabItems.tsx"), "utf8");
test("unread terminal activity has a static theme-aware outline, not an endless animation", () => {
const rule = css.match(/\.session-activity-dot\s*\{([^}]+)\}/)?.[1];
assert.ok(rule, "keep a distinct unread activity style");
assert.match(rule, /outline:\s*1px solid color-mix\(in srgb, var\(--top-tabs-fg, hsl\(var\(--foreground\)\)\) 75%, transparent\)/);
assert.match(rule, /outline-offset:\s*2px/);
assert.doesNotMatch(rule, /(?:animation|transition|background|color|transform)\s*:/);
assert.doesNotMatch(css, /session-activity-breathe/);
});
test("static unread styling keeps session status hues and conditional tab/workspace consumers", () => {
assert.match(tabs, /hasActivity && "session-activity-dot"/);
assert.match(tabs, /status === 'connected'[\s\S]*?"bg-emerald-400"[\s\S]*?status === 'connecting'[\s\S]*?"bg-amber-400"[\s\S]*?"bg-rose-500"/);
assert.match(tabs, /sessionStatusDot\(session.status, hasActivity\)/);
assert.match(tabs, /hasActivity && sessionStatusDot\('connected', true\)/);
});