diff --git a/src/client/components/SessionViewer.tsx b/src/client/components/SessionViewer.tsx
index 4cf02f0..c47fde4 100644
--- a/src/client/components/SessionViewer.tsx
+++ b/src/client/components/SessionViewer.tsx
@@ -58,7 +58,22 @@ export function SessionViewer({
}
}, [focusedIndex]);
- // Build display list with redacted dividers.
+ // Auto-scroll to hash anchor on load
+ useEffect(() => {
+ const hash = window.location.hash;
+ if (hash && hash.startsWith("#msg-") && messages.length > 0) {
+ requestAnimationFrame(() => {
+ const el = document.getElementById(hash.slice(1));
+ if (el) {
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
+ el.classList.add("search-match-focused", "rounded-xl");
+ setTimeout(() => el.classList.remove("search-match-focused"), 3000);
+ }
+ });
+ }
+ }, [messages.length]);
+
+ // Build display list with redacted dividers and time gaps.
// Must be called before any early returns to satisfy Rules of Hooks.
const displayItems = useMemo(() => {
if (messages.length === 0) return [];
@@ -67,9 +82,11 @@ export function SessionViewer({
const items: Array<
| { type: "message"; message: ParsedMessage; messageIndex: number }
| { type: "redacted_divider"; key: string }
+ | { type: "time_gap"; key: string; duration: string }
> = [];
let prevWasRedactedGap = false;
+ let prevTimestamp: string | undefined;
let messageIndex = 0;
for (const msg of allMessages) {
if (redactedUuids.has(msg.uuid)) {
@@ -86,6 +103,20 @@ export function SessionViewer({
});
prevWasRedactedGap = false;
}
+ // Insert time gap indicator if > 5 minutes between visible messages
+ if (prevTimestamp && msg.timestamp) {
+ const currTime = new Date(msg.timestamp).getTime();
+ const prevTime = new Date(prevTimestamp).getTime();
+ const gap = currTime - prevTime;
+ if (!isNaN(gap) && gap > 5 * 60 * 1000) {
+ items.push({
+ type: "time_gap",
+ key: `gap-${msg.uuid}`,
+ duration: formatDuration(gap),
+ });
+ }
+ }
+ if (msg.timestamp) prevTimestamp = msg.timestamp;
items.push({ type: "message", message: msg, messageIndex });
messageIndex++;
}
@@ -154,6 +185,17 @@ export function SessionViewer({
if (item.type === "redacted_divider") {
return