From 728555480a09f7fcee86523ae22790fd33112315 Mon Sep 17 00:00:00 2001 From: jnjpng Date: Thu, 26 Feb 2026 14:39:51 -0800 Subject: [PATCH] fix: normalize animated logo frame width (#1172) Co-authored-by: Letta --- src/cli/components/AnimatedLogo.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/cli/components/AnimatedLogo.tsx b/src/cli/components/AnimatedLogo.tsx index 92072a3..c4cd323 100644 --- a/src/cli/components/AnimatedLogo.tsx +++ b/src/cli/components/AnimatedLogo.tsx @@ -2,6 +2,8 @@ import { useSyncExternalStore } from "react"; import { colors } from "./colors"; import { Text } from "./Text"; +const LOGO_WIDTH = 10; + // Define animation frames - 3D rotation effect with gradient (█ → ▓ → ▒ → ░) // Each frame is ~10 chars wide, 5 lines tall - matches login dialog asciiLogo size const logoFrames = [ @@ -91,6 +93,17 @@ const logoFrames = [ █████▓ `, ]; +function padFrameToFixedWidth(frame: string, width: number): string { + return frame + .split("\n") + .map((line) => line.padEnd(width, " ")) + .join("\n"); +} + +const normalizedLogoFrames = logoFrames.map((frame) => + padFrameToFixedWidth(frame, LOGO_WIDTH), +); + // Shared module-level ticker for animation sync across all AnimatedLogo instances // Single timer, guaranteed sync, no time-jump artifacts let tick = 0; @@ -133,9 +146,9 @@ export function AnimatedLogo({ animate = true, }: AnimatedLogoProps) { const tick = useSyncExternalStore(subscribe, getSnapshot); - const frame = animate ? tick % logoFrames.length : 0; + const frame = animate ? tick % normalizedLogoFrames.length : 0; - const logoLines = logoFrames[frame]?.split("\n") ?? []; + const logoLines = normalizedLogoFrames[frame]?.split("\n") ?? []; return ( <>