Skip to content

fix(sidebar): use first message time for thread recency timestamp#1030

Open
jeheskielSunloy77 wants to merge 1 commit intopingdotgg:mainfrom
jeheskielSunloy77:fix/sidebar-thread-timestamp
Open

fix(sidebar): use first message time for thread recency timestamp#1030
jeheskielSunloy77 wants to merge 1 commit intopingdotgg:mainfrom
jeheskielSunloy77:fix/sidebar-thread-timestamp

Conversation

@jeheskielSunloy77
Copy link

@jeheskielSunloy77 jeheskielSunloy77 commented Mar 13, 2026

What Changed

Updated sidebar thread recency to use the first message timestamp instead of the thread creation timestamp, with a fallback to thread.createdAt for 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.createdAt reflects 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 message createdAt better matches user expectations of thread recency, while falling back to thread creation keeps empty threads stable and predictable.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Fix sidebar thread recency to use first message time instead of thread creation time

Adds a getThreadSidebarTimestamp helper in Sidebar.tsx that returns the earliest message createdAt for a thread, falling back to thread.createdAt when no messages exist. Both thread sort order and the displayed relative timestamp now use this value instead of thread.createdAt directly.

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

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.
Copilot AI review requested due to automatic review settings March 13, 2026 15:41
@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 05fb2ca7-216e-4e7f-90d3-387751b5ba90

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use OpenGrep to find security vulnerabilities and bugs across 17+ programming languages.

OpenGrep is compatible with Semgrep configurations. Add an opengrep.yml or semgrep.yml configuration file to your project to enable OpenGrep analysis.

@github-actions github-actions bot added size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Mar 13, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 getThreadSidebarTimestamp helper that finds the earliest message timestamp (falling back to thread.createdAt for 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.

Comment on lines +107 to +124
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;
}
Comment on lines +108 to +123
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;
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +1321 to +1322
new Date(getThreadSidebarTimestamp(b)).getTime() -
new Date(getThreadSidebarTimestamp(a)).getTime();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants