Break message grouping on a long gap, not just sender change (#73)

Consecutive messages from the same sender only repeated the
avatar/name/timestamp header on the first one in the run, so a
message sent minutes later with nobody else posting in between still
hid under a stale timestamp. Adds a 5-minute gap threshold (Slack's
own cutoff) that starts a new group even for the same sender.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-03 20:02:01 -06:00
co-authored by Claude Sonnet 5
parent b4a104f8c6
commit 6e889b8ea4
+14 -2
View File
@@ -69,6 +69,13 @@ function FileAttachmentCard({ file, roomId, onPreview }: FileAttachmentCardProps
// trigger a download the moment the browser tries to fetch it). // trigger a download the moment the browser tries to fetch it).
const PLAYABLE_VIDEO_CONTENT_TYPES = new Set(['video/mp4', 'video/webm', 'video/ogg']) const PLAYABLE_VIDEO_CONTENT_TYPES = new Set(['video/mp4', 'video/webm', 'video/ogg'])
// #73: Slack's own threshold for the same "still grouped, but it's been a
// while" call -- past this gap a same-sender message starts a new group
// (its own avatar/name/timestamp) even with nobody else posting in
// between, so a message sent minutes later doesn't hide under a stale
// timestamp from the start of the run.
const GROUP_BREAK_MS = 5 * 60 * 1000
interface VideoAttachmentProps { interface VideoAttachmentProps {
file: MessageFileInfo file: MessageFileInfo
roomId: string roomId: string
@@ -210,8 +217,13 @@ export function MessageList({
// Mattermost-style grouping: every message shows who sent it, but // Mattermost-style grouping: every message shows who sent it, but
// consecutive messages from the same sender only repeat the // consecutive messages from the same sender only repeat the
// avatar/name/timestamp header on the first one in the run -- // avatar/name/timestamp header on the first one in the run --
// applies uniformly, including to your own messages. // applies uniformly, including to your own messages. Also breaks on
const isGroupStart = !prev || prev.user_id !== msg.user_id // a long gap (see GROUP_BREAK_MS) so a message sent well after the
// rest of the run still gets its own visible timestamp.
const isGroupStart =
!prev ||
prev.user_id !== msg.user_id ||
new Date(msg.created_at).getTime() - new Date(prev.created_at).getTime() > GROUP_BREAK_MS
const editing = editingId === msg.id const editing = editingId === msg.id
const deleted = !!msg.deleted_at const deleted = !!msg.deleted_at