From aa39b6a5be93f16f227f0c20498beeab86390f13 Mon Sep 17 00:00:00 2001 From: hobokenchicken Date: Mon, 6 Jul 2026 19:41:19 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20read=20indicator=20=E2=80=94=20NEW=20di?= =?UTF-8?q?vider=20line=20between=20read=20and=20unread=20messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/ChatArea.tsx | 57 +++++++++++++++++++++------------ web/src/components/DMChat.tsx | 40 +++++++++++++++-------- 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/web/src/components/ChatArea.tsx b/web/src/components/ChatArea.tsx index e831f23..95608d4 100644 --- a/web/src/components/ChatArea.tsx +++ b/web/src/components/ChatArea.tsx @@ -326,6 +326,7 @@ export function ChatArea() { const members = activeServerId ? membersByServer[activeServerId] || [] : []; const memberUsernames = useMemo(() => new Set(members.map((m) => m.username)), [members]); const markRead = useReadStatesStore((s) => s.markRead); + const readStates = useReadStatesStore((s) => s.states); const [showPinned, setShowPinned] = useState(false); const [showFeatureRequests, setShowFeatureRequests] = useState(false); @@ -828,27 +829,41 @@ export function ChatArea() { {!isLoading && messages.length === 0 && (

[no messages in this channel]

)} - {messages.map((message) => ( - m.id === message.reply_to) : null} - onJumpToParent={handleJumpToMessage} - /> - ))} + {messages.map((message, i) => { + // ponytail: last-read divider — show after the message matching the user's read state + const lastReadId = activeChannelId ? readStates[activeChannelId] : undefined; + const showDivider = lastReadId && message.id === lastReadId && i < messages.length - 1; + return ( + <> + m.id === message.reply_to) : null} + onJumpToParent={handleJumpToMessage} + /> + {showDivider && ( +
+ + ── NEW ── + +
+ )} + + ); + })}
diff --git a/web/src/components/DMChat.tsx b/web/src/components/DMChat.tsx index f25fc13..f1d0c4b 100644 --- a/web/src/components/DMChat.tsx +++ b/web/src/components/DMChat.tsx @@ -168,6 +168,7 @@ export function DMChat() { const inputRef = useRef(null); const lastTypingRef = useRef(0); const markConvRead = useReadStatesStore((s) => s.markConvRead); + const convStates = useReadStatesStore((s) => s.convStates); const id = conversationId || activeId; const conversation = conversations.find((c) => c.id === id); @@ -321,19 +322,32 @@ export function DMChat() { {isLoadingOlder &&

[loading older messages...]

} {!id &&

[select a conversation]

} {id && messages.length === 0 &&

[no messages]

} - {messages.map((msg: ConversationMessage) => ( - - ))} + {messages.map((msg: ConversationMessage, i: number) => { + const lastReadId = id ? convStates[id] : undefined; + const showDivider = lastReadId && msg.id === lastReadId && i < messages.length - 1; + return ( + <> + + {showDivider && ( +
+ + ── NEW ── + +
+ )} + + ); + })}