@@ -8,6 +8,7 @@ let oldestMessageId = null; // Track the oldest message ID we've loaded
88let hasMoreMessages = true ; // Track if there are more messages to load
99let editingMessage = null ; // Track the message being edited
1010let replyingToMessage = null ; // Track the message being replied to
11+ var lastReferenceReadMessageId = null ; // Track the ID of either last outgoing message that has been read by others or last incoming message (as a reference point for read status)
1112
1213// Load messages for a chat
1314async function loadMessages ( chatId , initialLoad = false ) {
@@ -63,7 +64,7 @@ async function loadMessages(chatId, initialLoad = false) {
6364 }
6465
6566 // Display messages (will prepend if not initial load, clear and append if initial)
66- displayMessages ( messages , initialLoad , hasMoreMessages ) ;
67+ displayMessages ( messages , initialLoad ) ;
6768
6869 // Restore scroll position after DOM update (only if not initial load)
6970 if ( ! initialLoad ) {
@@ -228,7 +229,7 @@ function updateSingleMessageGrouping(messageElement, index, allMessageElements)
228229}
229230
230231// Display messages in the chat area
231- function displayMessages ( messages , isInitialLoad = false , hasMoreMessages = true ) {
232+ function displayMessages ( messages , isInitialLoad = false ) {
232233 const prepend = ! isInitialLoad ;
233234 console . log ( `Displaying ${ messages . length } messages... (prepend: ${ prepend } )` ) ;
234235
@@ -262,8 +263,6 @@ function displayMessages(messages, isInitialLoad = false, hasMoreMessages = true
262263 let previousMessageInBatch = null ;
263264 for ( let i = 0 ; i < messages . length ; i ++ ) {
264265 const message = messages [ i ] ;
265- // If there are no more messages, the very first (top) message should have a date header
266- const isTopMessage = ! hasMoreMessages && i === messages . length - 1 ;
267266 addMessageToChat ( message , true , prepend ) ;
268267 if ( prepend ) {
269268 previousMessageInBatch = message ;
@@ -275,7 +274,10 @@ function displayMessages(messages, isInitialLoad = false, hasMoreMessages = true
275274 messageElements . forEach ( ( messageElement , index ) => {
276275 updateSingleMessageGrouping ( messageElement , index , messageElements ) ;
277276 } ) ;
278-
277+
278+ // Mark messages as read
279+ showCurrentChatMessagesAsRead ( ) ;
280+
279281 // Handle scrolling (only for initial load)
280282 if ( isInitialLoad ) {
281283 // Scroll to bottom instantly when loading messages
@@ -498,6 +500,14 @@ function createMessageElement(message) {
498500 if ( hasAttachments && messageDiv . dataset . attachments ) {
499501 messageDiv . dataset . currentAttachmentIndex = '0' ;
500502 }
503+
504+ if ( isOwnMessage ( message ) && message . id <= lastReferenceReadMessageId ) {
505+ // remove hidden class to show read mark
506+ const readMark = messageDiv . querySelector ( '.message-status-read-mark' ) ;
507+ if ( readMark ) {
508+ readMark . classList . remove ( 'hidden' ) ;
509+ }
510+ }
501511
502512 // Add long press handler for context menu
503513 addLongPressHandler ( messageDiv , {
@@ -512,7 +522,28 @@ function createMessageElement(message) {
512522 return messageDiv ;
513523}
514524
515- // Navigate message attachments
525+ function showCurrentChatMessagesAsRead ( ) {
526+ const messagesContainer = document . getElementById ( 'messagesContainer' ) ;
527+ if ( ! messagesContainer || ! lastReferenceReadMessageId ) return ;
528+
529+ // Query only hidden read marks (more efficient - only elements that need updating)
530+ const hiddenReadMarks = messagesContainer . querySelectorAll ( '.message-status-read-mark.hidden' ) ;
531+
532+ hiddenReadMarks . forEach ( readMark => {
533+ // Find the parent message element
534+ const messageElement = readMark . closest ( '.message-row.own' ) ;
535+ if ( ! messageElement ) return ;
536+
537+ const messageId = messageElement . dataset . messageId ;
538+ if ( ! messageId ) return ;
539+
540+ // If this message ID is <= the reference message ID, show as read
541+ if ( messageId <= lastReferenceReadMessageId ) {
542+ readMark . classList . remove ( 'hidden' ) ;
543+ }
544+ } ) ;
545+ }
546+
516547function navigateMessageAttachment ( messageId , direction ) {
517548 const messageDiv = document . querySelector ( `[data-message-id="${ messageId } "]` ) ?. closest ( '.message-row' ) ;
518549 if ( ! messageDiv ) return ;
@@ -1031,6 +1062,13 @@ function initializeMessageInput() {
10311062
10321063 messageInput . addEventListener ( 'input' , adjustHeight ) ;
10331064
1065+ messageInput . addEventListener ( 'focus' , function ( ) {
1066+ // Mark chat as read when message input is focused
1067+ if ( currentChatId ) {
1068+ markChatAsRead ( currentChatId ) ;
1069+ }
1070+ } ) ;
1071+
10341072 messageInput . addEventListener ( 'keydown' , function ( e ) {
10351073 if ( e . key === 'Escape' ) {
10361074 e . preventDefault ( ) ;
@@ -1142,6 +1180,9 @@ async function sendMessage(textOverride = null) {
11421180 // Display message immediately with sending state
11431181 await addMessageToChat ( message ) ;
11441182
1183+ // Mark chat as read if not already (since user is sending a message, we can assume they've seen the chat)
1184+ markChatAsRead ( currentChatId ) ;
1185+
11451186 // Update chat list with new message
11461187 updateChatListWithMessage ( message ) ;
11471188
@@ -1241,6 +1282,18 @@ async function addMessageToChat(message, bulkAddition = false, prepend = false)
12411282 noMessages . remove ( ) ;
12421283 }
12431284
1285+ // Check if message has read marks from other users to update lastReferenceReadMessageId
1286+ const hasOtherUserReadMarks = message . readMarks ?. some ( mark =>
1287+ mark . user && mark . user . id !== currentUser . info . id
1288+ ) ;
1289+
1290+ if ( hasOtherUserReadMarks || ! isOwnMessage ( message ) ) {
1291+ // Only update if this ID is greater than current lastReferenceReadMessageId
1292+ if ( ! lastReferenceReadMessageId || message . id > lastReferenceReadMessageId ) {
1293+ lastReferenceReadMessageId = message . id ;
1294+ }
1295+ }
1296+
12441297 // Date header is now handled inside the message element by updateSingleMessageGrouping
12451298 // No need to check for date headers here
12461299
0 commit comments