Skip to content

Commit f2b7daf

Browse files
committed
Mark chat as read fix.
1 parent fb3cab7 commit f2b7daf

6 files changed

Lines changed: 44 additions & 41 deletions

File tree

Docs/APIREF-Chats.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ __Path__:
339339
```
340340
PUT /chats/<id>/messages/<id>/read
341341
```
342-
__Response__: `OK`
342+
__Response__: [`MessageInfo`](APIREF-JSON.md#messageinfo) object with updated read marks.
343343
_________________________________________________________________________________
344344

345345
### 24. Send notification

Public/app/js/chat.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ async function sendMessage(textOverride = null) {
11811181
await addMessageToChat(message);
11821182

11831183
// Update chat list with new message
1184-
updateChatListWithMessage(message);
1184+
await updateChatListWithMessage(message);
11851185

11861186
// Send to server using the shared function
11871187
const serverMessage = await sendMessageToServer(message);
@@ -1255,7 +1255,7 @@ async function updateMessage(message, newText, newAttachments) {
12551255
replaceMessageElement(currentMessage.localId, serverMessage, false);
12561256

12571257
// Update chat list with updated message
1258-
updateChatListWithMessage(serverMessage);
1258+
await updateChatListWithMessage(serverMessage);
12591259
}
12601260

12611261
// Add message to chat
@@ -1624,7 +1624,7 @@ async function deleteMessage(message) {
16241624
replaceMessageElement(message.localId || message.id, serverMessage, false);
16251625

16261626
// Update chat list
1627-
updateChatListWithMessage(serverMessage);
1627+
await updateChatListWithMessage(serverMessage);
16281628
} catch (error) {
16291629
console.error('Error deleting message:', error);
16301630
alert('Failed to delete message');

Public/app/js/main.js

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -170,40 +170,40 @@ async function markChatAsRead(chatId) {
170170
const chat = chats.find(c => c.id === chatId);
171171
if (!chat) return;
172172

173-
if (resolveUnreadCount(chat) > 0) {
174-
setStorageUnreadCount(chat.id, 0);
175-
176-
// Update the DOM to remove badge and bold style
177-
const chatItem = document.querySelector(`[data-chat-id="${chatId}"]`);
178-
if (chatItem) {
179-
const lastMessageElement = chatItem.querySelector('.chat-last-message');
180-
if (lastMessageElement) {
181-
lastMessageElement.classList.remove('unread');
182-
}
183-
184-
const badgeElement = chatItem.querySelector('.chat-badge');
185-
if (badgeElement) {
186-
badgeElement.remove();
187-
}
173+
const lastMessage = chat.lastMessage;
174+
if (!lastMessage || !lastMessage.id || isMessageReadByCurrentUser(lastMessage)) return;
175+
176+
setStorageUnreadCount(chat.id, 0);
177+
178+
// Update the DOM to remove badge and bold style
179+
const chatItem = document.querySelector(`[data-chat-id="${chatId}"]`);
180+
if (chatItem) {
181+
const lastMessageElement = chatItem.querySelector('.chat-last-message');
182+
if (lastMessageElement) {
183+
lastMessageElement.classList.remove('unread');
188184
}
189185

190-
// Update page title badge
191-
updatePageTitleBadge();
186+
const badgeElement = chatItem.querySelector('.chat-badge');
187+
if (badgeElement) {
188+
badgeElement.remove();
189+
}
192190
}
193191

194-
// Mark messages as read on server
195-
if (chat.lastMessage && chat.lastMessage.id && !isMessageReadByCurrentUser(chat.lastMessage)) {
196-
try {
197-
await apiMarkAsRead(chatId, chat.lastMessage.id);
198-
} catch (error) {
199-
console.error('Failed to mark messages as read:', error);
200-
}
192+
// Call API to mark messages as read
193+
try {
194+
const message = await apiMarkAsRead(chatId, lastMessage.id);
195+
lastMessage.readMarks = message.readMarks; // Update readMarks for the last message
196+
} catch (error) {
197+
console.error('Failed to mark messages as read:', error);
201198
}
199+
200+
// Update page title badge
201+
updatePageTitleBadge();
202202
}
203203

204204
function updatePageTitleBadge() {
205205
// Count chats with unread messages
206-
const unreadChatsCount = chats.filter(chat => resolveUnreadCount(chat) > 0).length;
206+
const unreadChatsCount = chats.filter(chat => (getStorageUnreadCount(chat.id) || 0) > 0).length;
207207

208208
if (unreadChatsCount > 0 && document.hidden) {
209209
document.title = `(${unreadChatsCount}) ${originalTitle}`;
@@ -228,7 +228,7 @@ function displayChats(restoreSelection = true) {
228228
// Show all chats except blocked and archived
229229
return !isBlocked && !isArchived;
230230
case 'unread':
231-
return resolveUnreadCount(chat) > 0 && !isBlocked && !isArchived;
231+
return (getStorageUnreadCount(chat.id) || 0) > 0 && !isBlocked && !isArchived;
232232
case 'archived':
233233
return isArchived;
234234
case 'blocked':
@@ -589,7 +589,7 @@ function updateCurrentUserButton() {
589589
}
590590

591591
// Update chat list when new message arrives
592-
function updateChatListWithMessage(message) {
592+
async function updateChatListWithMessage(message) {
593593
const chat = chats.find(c => c.id === message.chatId);
594594
if (!chat || !chat.id) {
595595
console.warn('Received message for unknown chat:', message.chatId);
@@ -617,8 +617,10 @@ function updateChatListWithMessage(message) {
617617

618618
var unreadCount = getStorageUnreadCount(chat.id) || 0;
619619

620-
// If chat is not currently open or the page is hidden, increment the unread count
621-
if (message.chatId !== currentChatId || document.hidden) {
620+
// If the chat is currently open and the document is visible, mark it as read immediately
621+
if (message.chatId === currentChatId && !document.hidden) {
622+
await markChatAsRead(chat.id);
623+
} else {
622624
setStorageUnreadCount(chat.id, ++unreadCount);
623625
}
624626

Public/app/js/ws.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function initializeWebSocket() {
8080
}
8181

8282
// Handle WebSocket messages
83-
function handleWebSocketMessage(notification) {
83+
async function handleWebSocketMessage(notification) {
8484
if ((notification.event === 'message' || notification.event === 'messageUpdate') && notification.payload) {
8585
const message = notification.payload;
8686

@@ -92,7 +92,7 @@ function handleWebSocketMessage(notification) {
9292
// Check if this is for the current chat
9393
if (message.chatId === currentChatId) {
9494
// Update chat list item with new message
95-
updateChatListWithMessage(message);
95+
await updateChatListWithMessage(message);
9696

9797
// Check if we already have this message (by localId)
9898
const existingElement = document.querySelector(`[data-local-id="${message.localId}"]`);
@@ -111,7 +111,7 @@ function handleWebSocketMessage(notification) {
111111
loadChats();
112112
} else {
113113
// Update chat list item with new message
114-
updateChatListWithMessage(message);
114+
await updateChatListWithMessage(message);
115115
// Message for a different existing chat, re-sort chat list
116116
displayChats();
117117
}

Sources/App/Controllers/ChatController.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,9 @@ struct ChatController: RouteCollection {
173173
by: currentUser.requireID())
174174
}
175175

176-
func readMessage(_ req: Request) async throws -> HTTPStatus {
176+
func readMessage(_ req: Request) async throws -> MessageInfo {
177177
let currentUser = try await req.requireCurrentUser()
178-
try await service.with(currentUser).readMessage(req.messageID(), by: currentUser.requireID())
179-
return .ok
178+
return try await service.with(currentUser).readMessage(req.messageID(), by: currentUser.requireID())
180179
}
181180

182181
func deleteMessage(_ req: Request) async throws -> MessageInfo {

Sources/App/Services/ChatService.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ protocol ChatServiceProtocol: LoggedIn {
6565
func deleteMessage(_ id: MessageID, by userId: UserID) async throws -> MessageInfo
6666

6767
/// Marks message with`id` as seen by the user with `userId`.
68-
func readMessage(_ id: MessageID, by userId: UserID) async throws
68+
func readMessage(_ id: MessageID, by userId: UserID) async throws -> MessageInfo
6969

7070
/// Adds chat's profile picture (not to confuse with user's profile picture in personal chat).
7171
func addChatImage(_ chatId: ChatID, with info: UpdateChatRequest, by userId: UserID) async throws -> ChatInfo
@@ -562,7 +562,7 @@ actor ChatService: ChatServiceProtocol {
562562
return info
563563
}
564564

565-
func readMessage(_ id: MessageID, by userId: UserID) async throws {
565+
func readMessage(_ id: MessageID, by userId: UserID) async throws -> MessageInfo {
566566
guard let message = try await repo.findMessage(id: id) else {
567567
throw ServiceError(.notFound)
568568
}
@@ -576,7 +576,9 @@ actor ChatService: ChatServiceProtocol {
576576
let readMarkinfo = readMark.info()
577577
messageInfo.readMarks = (messageInfo.readMarks ?? []) + [readMarkinfo]
578578
try await core.notificator.notify(chat: message.chat, in: repo, about: .messageRead, from: readerRelation.user, with: messageInfo.jsonObject())
579+
return messageInfo
579580
}
581+
return message.info()
580582
}
581583

582584
func addChatImage(_ chatId: ChatID, with info: UpdateChatRequest, by userId: UserID) async throws -> ChatInfo {

0 commit comments

Comments
 (0)