fix(sidebar): use first message time for thread recency timestamp#1030
fix(sidebar): use first message time for thread recency timestamp#1030jeheskielSunloy77 wants to merge 1 commit intopingdotgg:mainfrom
Conversation
Sidebar thread timestamps were based on thread.createdAt, which measures when the thread shell was created rather than when the conversation actually started. In practice that made draft or pre-created threads look older or newer than the underlying conversation, and it caused the visible timestamp to communicate a different concept than users infer from the sidebar. Use the first message createdAt as the sidebar timestamp source, with a fallback to thread.createdAt when a thread has no messages yet. Apply the same derived timestamp to thread ordering and recent-thread focus so the label and sort order stay aligned. This keeps empty threads stable while making active threads reflect real conversation start time instead of internal object creation time.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can use OpenGrep to find security vulnerabilities and bugs across 17+ programming languages.OpenGrep is compatible with Semgrep configurations. Add an |
There was a problem hiding this comment.
Pull request overview
Updates sidebar thread ordering and display timestamps to use the first message's createdAt instead of the thread container's createdAt, better reflecting when the conversation actually started.
Changes:
- Added
getThreadSidebarTimestamphelper that finds the earliest message timestamp (falling back tothread.createdAtfor empty threads) - Applied the new timestamp to both sorting locations and the displayed relative time in the sidebar
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| function getThreadSidebarTimestamp(thread: Thread): string { | ||
| if (thread.messages.length === 0) { | ||
| return thread.createdAt; | ||
| } | ||
|
|
||
| let earliestTimestamp = thread.messages[0]?.createdAt ?? thread.createdAt; | ||
| let earliestTime = new Date(earliestTimestamp).getTime(); | ||
|
|
||
| for (const message of thread.messages) { | ||
| const messageTime = new Date(message.createdAt).getTime(); | ||
| if (messageTime < earliestTime) { | ||
| earliestTimestamp = message.createdAt; | ||
| earliestTime = messageTime; | ||
| } | ||
| } | ||
|
|
||
| return earliestTimestamp; | ||
| } |
| if (thread.messages.length === 0) { | ||
| return thread.createdAt; | ||
| } | ||
|
|
||
| let earliestTimestamp = thread.messages[0]?.createdAt ?? thread.createdAt; | ||
| let earliestTime = new Date(earliestTimestamp).getTime(); | ||
|
|
||
| for (const message of thread.messages) { | ||
| const messageTime = new Date(message.createdAt).getTime(); | ||
| if (messageTime < earliestTime) { | ||
| earliestTimestamp = message.createdAt; | ||
| earliestTime = messageTime; | ||
| } | ||
| } | ||
|
|
||
| return earliestTimestamp; |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0b0dae3ade
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| new Date(getThreadSidebarTimestamp(b)).getTime() - | ||
| new Date(getThreadSidebarTimestamp(a)).getTime(); |
There was a problem hiding this comment.
Precompute sidebar timestamps before sorting threads
The new comparator recomputes getThreadSidebarTimestamp for both operands on every comparison, and getThreadSidebarTimestamp scans the full thread.messages array each time. In projectThreads sorting this turns one render into roughly O(threadCount * log(threadCount) * messagesPerThread), which is a significant regression for projects with long histories and can make sidebar interactions noticeably sluggish under load; deriving each thread timestamp once before sorting avoids this repeated full scan.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🟢 Low
Issue on line in apps/web/src/components/Sidebar.tsx:107:
getThreadSidebarTimestamp returns the earliest message timestamp, but the sidebar sorting logic expects the latest timestamp so that more recent activity appears first. This causes threads to sort incorrectly — for example, a thread with messages at [10:01, 10:05] returns 10:01 and appears older than a thread with a single message at 10:03. Change the comparison to find the maximum timestamp instead.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file apps/web/src/components/Sidebar.tsx around line 107:
`getThreadSidebarTimestamp` returns the **earliest** message timestamp, but the sidebar sorting logic expects the **latest** timestamp so that more recent activity appears first. This causes threads to sort incorrectly — for example, a thread with messages at [10:01, 10:05] returns 10:01 and appears older than a thread with a single message at 10:03. Change the comparison to find the maximum timestamp instead.
Evidence trail:
apps/web/src/components/Sidebar.tsx lines 107-122: `getThreadSidebarTimestamp` function uses `messageTime < earliestTime` comparison to find minimum timestamp. apps/web/src/components/Sidebar.tsx lines 405-413: sorting uses `getThreadSidebarTimestamp(b) - getThreadSidebarTimestamp(a)` (descending order) and variable is named `latestThread`. apps/web/src/components/Sidebar.tsx lines 1317-1325: same sorting pattern. apps/web/src/components/Sidebar.tsx line 1576: timestamp displayed as relative time ('Xm ago') implying most recent activity.
What Changed
Updated sidebar thread recency to use the first message timestamp instead of the thread creation timestamp, with a fallback to
thread.createdAtfor empty threads. Applied the same derived timestamp to sidebar sorting and “most recent thread” selection so the displayed time and ordering stay consistent.Why
thread.createdAtreflects when the thread container was created, not when the conversation actually began. In this app that can happen before any real message is sent, especially with draft or pre-created threads, which makes the sidebar timestamp misleading. Using the first messagecreatedAtbetter matches user expectations of thread recency, while falling back to thread creation keeps empty threads stable and predictable.Checklist
Note
Fix sidebar thread recency to use first message time instead of thread creation time
Adds a
getThreadSidebarTimestamphelper in Sidebar.tsx that returns the earliest messagecreatedAtfor a thread, falling back tothread.createdAtwhen no messages exist. Both thread sort order and the displayed relative timestamp now use this value instead ofthread.createdAtdirectly.Behavioral Change: threads will reorder in the sidebar based on their first message time, which may differ from thread creation time and will change the visible ordering for existing threads.
📊 Macroscope summarized 0b0dae3. 1 file reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted
🗂️ Filtered Issues