block / block/buzz

Sort channel threads by most recent reply, not creation date

Open
#4,585 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

**Motivation**

Channel timelines order threads by when the root was posted. A two-week-old thread getting replies all morning stays buried under yesterday's dead ones, so finding the live conversation means scrolling and checking reply counts. Home / Inbox is the only pane that surfaces threads by activity, and it is personal/mention-scoped — it does not answer "what is live in this channel."

**Proposed solution**

An activity-ordering option for the channel timeline, shipped as a preview feature (`preview-features.json`) — off by default, same path Workflows, Projects, Pulse, and Forum Channels took.

The data already exists end to end. `thread_metadata.last_reply_at` is bumped on every reply (`crates/buzz-db/src/thread.rs:210`), selected in the channel window query (`thread.rs:588`), serialized to the client (`crates/buzz-relay/src/api/bridge.rs:544`), and already rendered as "last replied …" on thread summary rows (`desktop/src/features/messages/ui/MessageThreadSummaryRow.tsx:253`). Nothing sorts by it — `get_channel_window` (`thread.rs:565`) hardcodes `ORDER BY e.created_at DESC, e.id ASC` (`thread.rs:628`).

There are two implementations, with different scope and different correctness:

1. **Client-side re-sort.** Sort the loaded window by `lastReplyAt ?? createdAt` behind the flag. Desktop-only, no relay change, no migration. Reorders only what is loaded, so an old-but-active thread below the pagination boundary stays hidden until paged in. Reaches users in a desktop release.
2. **Server-side sort.** Correct at any depth. The current pagination is a composite keyset on `(created_at, id)`, so it needs a new cursor over `COALESCE(last_reply_at, created_at)`, a supporting index, and a `sort` param through bridge → Tauri → client. Reaches users only after a relay deploy.

(1) is a subset of (2) — the flag and the UI carry over, so starting there does not throw work away if (2) follows. Either is fine to build; which one depends on whether the partial ordering is acceptable to ship.

**Alternatives considered**

- **Home / Inbox.** Already orders by reply time (`crates/buzz-db/src/feed.rs:115`), but it is a personal view, not a channel one.
- **Always sort by activity, no toggle.** Changes the timeline's meaning for every existing user, and reorders the view underneath the reader as replies land.
- **Sort by reply count or unread.** Reply count does not identify recent activity; unread is per-user state and does not belong in the window query.

**Additional context**

Searched open issues and PRs — no duplicates found.

Per CONTRIBUTING.md § "PRs We're Unlikely to Merge", raising this before building. If the direction works, the PR will include before/after screenshots.

Contributor guide

Open the contributing guide

Research direction

Start with get_channel_window in crates/buzz-db/src/thread.rs, then trace the existing last_reply_at path through crates/buzz-relay/src/api/bridge.rs and desktop/src/features/messages/ui/MessageThreadSummaryRow.tsx. Read preview-features.json and compare the client-side and server-side options with the maintainer before implementing; done means the preview flag controls activity ordering and the relevant pagination or loaded-window behavior is covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, tauri, typescript
Domain
databases, full-stack
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.