feat: add optional activity header timestamps in chat settings

Add a new Chat checkbox to toggle timestamps for tool, reasoning, and justification headers (default off).
Keep assistant message footer timestamps visible and switch to a more readable compact date format.
Preserve hover timestamp overlays with chat-surface background when the new setting is enabled.
This commit is contained in:
Bohdan Triapitsyn
2026-03-04 20:08:52 +02:00
parent d1a41000ca
commit 895d1ffa9a
7 changed files with 86 additions and 48 deletions
@@ -115,9 +115,9 @@ const VisualSectionContent: React.FC = () => {
]} />;
};
// Chat section: Default Tool Output, User message rendering, Diff layout, Mobile status bar, Show reasoning traces, Queue mode, Persist draft
// Chat section: Default Tool Output, User message rendering, Diff layout, Mobile status bar, Show reasoning traces, Justification activity, Activity header timestamps, Queue mode, Persist draft
const ChatSectionContent: React.FC = () => {
return <OpenChamberVisualSettings visibleSettings={['toolOutput', 'mermaidRendering', 'userMessageRendering', 'stickyUserHeader', 'diffLayout', 'mobileStatusBar', 'dotfiles', 'reasoning', 'textJustificationActivity', 'queueMode', 'persistDraft']} />;
return <OpenChamberVisualSettings visibleSettings={['toolOutput', 'mermaidRendering', 'userMessageRendering', 'stickyUserHeader', 'diffLayout', 'mobileStatusBar', 'dotfiles', 'reasoning', 'textJustificationActivity', 'activityHeaderTimestamps', 'queueMode', 'persistDraft']} />;
};
// Sessions section: Default model & agent, Session retention, Memory limits
@@ -124,7 +124,7 @@ const normalizeUserMessageRenderingMode = (mode: unknown): 'markdown' | 'plain'
return mode === 'markdown' ? 'markdown' : 'plain';
};
export type VisibleSetting = 'theme' | 'pwaInstallName' | 'fontSize' | 'terminalFontSize' | 'spacing' | 'cornerRadius' | 'inputBarOffset' | 'navRail' | 'toolOutput' | 'mermaidRendering' | 'userMessageRendering' | 'stickyUserHeader' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'reasoning' | 'queueMode' | 'textJustificationActivity' | 'terminalQuickKeys' | 'persistDraft';
export type VisibleSetting = 'theme' | 'pwaInstallName' | 'fontSize' | 'terminalFontSize' | 'spacing' | 'cornerRadius' | 'inputBarOffset' | 'navRail' | 'toolOutput' | 'mermaidRendering' | 'userMessageRendering' | 'stickyUserHeader' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'reasoning' | 'queueMode' | 'textJustificationActivity' | 'activityHeaderTimestamps' | 'terminalQuickKeys' | 'persistDraft';
interface OpenChamberVisualSettingsProps {
/** Which settings to show. If undefined, shows all. */
@@ -139,6 +139,8 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
const setShowReasoningTraces = useUIStore(state => state.setShowReasoningTraces);
const showTextJustificationActivity = useUIStore(state => state.showTextJustificationActivity);
const setShowTextJustificationActivity = useUIStore(state => state.setShowTextJustificationActivity);
const showActivityHeaderTimestamps = useUIStore(state => state.showActivityHeaderTimestamps);
const setShowActivityHeaderTimestamps = useUIStore(state => state.setShowActivityHeaderTimestamps);
const toolCallExpansion = useUIStore(state => state.toolCallExpansion);
const setToolCallExpansion = useUIStore(state => state.setToolCallExpansion);
const mermaidRenderingMode = useUIStore(state => state.mermaidRenderingMode);
@@ -242,6 +244,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|| shouldShow('reasoning')
|| shouldShow('queueMode')
|| shouldShow('textJustificationActivity')
|| shouldShow('activityHeaderTimestamps')
|| shouldShow('persistDraft');
const selectedToolExpansionOption = TOOL_EXPANSION_OPTIONS.find((option) => option.value === toolCallExpansion);
@@ -1056,6 +1059,29 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
<span className="typography-ui-label text-foreground">Show Justification Activity</span>
</div>
)}
{shouldShow('activityHeaderTimestamps') && (
<div
className="group flex cursor-pointer items-center gap-2 py-1.5"
role="button"
tabIndex={0}
aria-pressed={showActivityHeaderTimestamps}
onClick={() => setShowActivityHeaderTimestamps(!showActivityHeaderTimestamps)}
onKeyDown={(event) => {
if (event.key === ' ' || event.key === 'Enter') {
event.preventDefault();
setShowActivityHeaderTimestamps(!showActivityHeaderTimestamps);
}
}}
>
<Checkbox
checked={showActivityHeaderTimestamps}
onChange={setShowActivityHeaderTimestamps}
ariaLabel="Show tool and reasoning header timestamps"
/>
<span className="typography-ui-label text-foreground">Show Activity Header Timestamps</span>
</div>
)}
</section>
)}