Polish agent stream spacing, alignment, and metadata
- Centralize horizontal alignment: StreamItemWrapper / contentWrapper own the chat rail (paddingHorizontal: 8). Stream items stop setting their own outer horizontal padding. Copy icons get negative margins so the visible icon sits flush with the rail edges. - Unify the inline working indicator and assistant turn footer into a shared slot (minHeight: 24, paddingBottom: 24). No layout shift on streaming -> idle, and both gain breathing room above the composer and the next user bubble. - Equalize the gap on both sides of an assistant message adjacent to a tool call (20px each). Drop assistantMessageStylesheet.containerSpacing, which was a redundant marginBottom that only fired in one direction and duplicated getGapBetween's responsibility. - Scale up the chevron via transform (size stays 12, viewBox padding no longer dominates), iconBadge dimensions unchanged. Tool icon and chevron now read as similar visual weight. - Shared STREAM_METADATA_FONT_SIZE (13) for user message timestamp, assistant footer duration/timestamp, and the live elapsed timer. - formatDuration: one rule for static and live displays - 0-10s as X.Xs, 10-60s as Xs, minutes/hours integers only. Drops the `mode` parameter. - formatMessageTimestamp: explicitly carry the resolved hourCycle so the runtime applies an OS-level 24h preference when the platform exposes it (e.g. AppleICUForce24HourTime on macOS).
This commit is contained in:
@@ -2,36 +2,32 @@ import { describe, it, expect } from "vitest";
|
||||
import { formatDuration, formatMessageTimestamp } from "./time";
|
||||
|
||||
describe("formatDuration", () => {
|
||||
it("renders static durations as integers", () => {
|
||||
expect(formatDuration(5_600)).toBe("5s");
|
||||
expect(formatDuration(0)).toBe("0s");
|
||||
it("renders 0-10s with one decimal", () => {
|
||||
expect(formatDuration(0)).toBe("0.0s");
|
||||
expect(formatDuration(5_600)).toBe("5.6s");
|
||||
expect(formatDuration(9_900)).toBe("9.9s");
|
||||
});
|
||||
|
||||
it("renders 10s-60s as whole seconds", () => {
|
||||
expect(formatDuration(47_000)).toBe("47s");
|
||||
expect(formatDuration(10_400)).toBe("10s");
|
||||
expect(formatDuration(12_340)).toBe("12s");
|
||||
expect(formatDuration(47_000)).toBe("47s");
|
||||
});
|
||||
|
||||
it("renders minutes and remainder seconds", () => {
|
||||
it("renders minutes and remainder seconds without decimals", () => {
|
||||
expect(formatDuration(75_230)).toBe("1m 15s");
|
||||
expect(formatDuration(132_000)).toBe("2m 12s");
|
||||
expect(formatDuration(120_000)).toBe("2m");
|
||||
});
|
||||
|
||||
it("renders hours and remainder minutes", () => {
|
||||
it("renders hours and remainder minutes without decimals", () => {
|
||||
expect(formatDuration(3_900_000)).toBe("1h 5m");
|
||||
expect(formatDuration(3_600_000)).toBe("1h");
|
||||
});
|
||||
|
||||
it("guards against negative and NaN", () => {
|
||||
expect(formatDuration(-1)).toBe("0s");
|
||||
expect(formatDuration(Number.NaN)).toBe("0s");
|
||||
});
|
||||
|
||||
it("keeps one decimal for live durations", () => {
|
||||
expect(formatDuration(5_600, { mode: "live" })).toBe("5.6s");
|
||||
expect(formatDuration(12_340, { mode: "live" })).toBe("12.3s");
|
||||
expect(formatDuration(75_230, { mode: "live" })).toBe("1m 15.2s");
|
||||
expect(formatDuration(0, { mode: "live" })).toBe("0.0s");
|
||||
expect(formatDuration(-1)).toBe("0.0s");
|
||||
expect(formatDuration(Number.NaN)).toBe("0.0s");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user