diff --git a/ui-tui/src/components/appChrome.tsx b/ui-tui/src/components/appChrome.tsx index 23c4a4e8e..4c4faef0e 100644 --- a/ui-tui/src/components/appChrome.tsx +++ b/ui-tui/src/components/appChrome.tsx @@ -55,7 +55,7 @@ function ctxBar(pct: number | undefined, w = 10) { return '█'.repeat(filled) + '░'.repeat(w - filled) } -function SessionDuration({ lastUserAt, startedAt }: { lastUserAt?: null | number; startedAt: number }) { +function SessionDuration({ startedAt }: { startedAt: number }) { const [now, setNow] = useState(() => Date.now()) useEffect(() => { @@ -65,9 +65,20 @@ function SessionDuration({ lastUserAt, startedAt }: { lastUserAt?: null | number return () => clearInterval(id) }, [startedAt]) - const total = fmtDuration(now - startedAt) + return fmtDuration(now - startedAt) +} - return lastUserAt ? `${fmtDuration(now - lastUserAt)}/${total}` : total +export function IdleSinceLastMsg({ lastUserAt, t }: { lastUserAt: number; t: Theme }) { + const [now, setNow] = useState(() => Date.now()) + + useEffect(() => { + setNow(Date.now()) + const id = setInterval(() => setNow(Date.now()), 1000) + + return () => clearInterval(id) + }, [lastUserAt]) + + return {fmtDuration(now - lastUserAt)} } export function GoodVibesHeart({ tick, t }: { tick: number; t: Theme }) { @@ -100,7 +111,6 @@ export function StatusRule({ model, usage, bgCount, - lastUserAt, sessionStartedAt, showCost, voiceLabel, @@ -135,7 +145,7 @@ export function StatusRule({ {sessionStartedAt ? ( {' │ '} - + ) : null} {voiceLabel ? │ {voiceLabel} : null} @@ -290,7 +300,6 @@ interface StatusRuleProps { busy: boolean cols: number cwdLabel: string - lastUserAt?: null | number model: string sessionStartedAt?: null | number showCost: boolean diff --git a/ui-tui/src/components/appLayout.tsx b/ui-tui/src/components/appLayout.tsx index d711edca8..7b5b25ae8 100644 --- a/ui-tui/src/components/appLayout.tsx +++ b/ui-tui/src/components/appLayout.tsx @@ -9,7 +9,7 @@ import { PLACEHOLDER } from '../content/placeholders.js' import type { Theme } from '../theme.js' import type { DetailsMode } from '../types.js' -import { GoodVibesHeart, StatusRule, StickyPromptTracker, TranscriptScrollbar } from './appChrome.js' +import { GoodVibesHeart, IdleSinceLastMsg, StatusRule, StickyPromptTracker, TranscriptScrollbar } from './appChrome.js' import { FloatingOverlays, PromptZone } from './appOverlays.js' import { Banner, Panel, SessionPanel } from './branding.js' import { MessageLine } from './messageLine.js' @@ -188,7 +188,6 @@ const ComposerPane = memo(function ComposerPane({ busy={ui.busy} cols={composer.cols} cwdLabel={status.cwdLabel} - lastUserAt={status.lastUserAt} model={ui.info?.model?.split('/').pop() ?? ''} sessionStartedAt={status.sessionStartedAt} showCost={ui.showCost} @@ -243,7 +242,9 @@ const ComposerPane = memo(function ComposerPane({ value={composer.input} /> - + + {!ui.busy && status.lastUserAt ? : null} +