Skip to content

Commit e3006ae

Browse files
committed
fix: do not return updated messages from markAllRead if not needed
1 parent ff37dee commit e3006ae

File tree

5 files changed

+60
-31
lines changed

5 files changed

+60
-31
lines changed

ts/data/data.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,9 +493,13 @@ async function getUnreadByConversation(conversationId: string): Promise<MessageC
493493
}
494494

495495
async function markAllAsReadByConversationNoExpiration(
496-
conversationId: string
496+
conversationId: string,
497+
returnMessagesUpdated: boolean // for performances reason we do not return them because usually they are not needed
497498
): Promise<Array<number>> {
498-
const messagesIds = await channels.markAllAsReadByConversationNoExpiration(conversationId);
499+
const messagesIds = await channels.markAllAsReadByConversationNoExpiration(
500+
conversationId,
501+
returnMessagesUpdated
502+
);
499503
return messagesIds;
500504
}
501505

ts/interactions/conversationInteractions.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,7 @@ export function showLeaveGroupByConvoId(conversationId: string) {
254254
export function showInviteContactByConvoId(conversationId: string) {
255255
window.inboxStore?.dispatch(updateInviteContactModal({ conversationId }));
256256
}
257-
export async function onMarkAllReadByConvoId(conversationId: string) {
258-
const conversation = getConversationController().get(conversationId);
259257

260-
await conversation.markReadBouncy(Date.now());
261-
}
262258

263259
export function showAddModeratorsByConvoId(conversationId: string) {
264260
window.inboxStore?.dispatch(updateAddModeratorsModal({ conversationId }));

ts/models/conversation.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
actions as conversationActions,
3333
conversationChanged,
3434
conversationsChanged,
35+
markConversationFullyRead,
3536
MessageModelPropsWithoutConvoProps,
3637
ReduxConversationType,
3738
} from '../state/ducks/conversations';
@@ -1231,27 +1232,38 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
12311232
* Send read receipt if needed.
12321233
*/
12331234
public async markAllAsRead() {
1234-
if (this.isOpenGroupV2()) {
1235+
/**
1236+
* when marking all as read, there is a bunch of things we need to do.
1237+
* - we need to update all the messages in the DB not read yet for that conversation
1238+
* - we need to send the read receipts if there is one needed for those messages
1239+
* - we need to trigger a change on the redux store, so those messages are read AND mark the whole convo as read.
1240+
* - we need to remove any notifications related to this conversation ID.
1241+
*
1242+
*
1243+
* (if there is an expireTimer, we do it the slow way, handling each message separately)
1244+
*/
1245+
const expireTimerSet = !!this.get('expireTimer');
1246+
if (this.isOpenGroupV2() || !expireTimerSet) {
12351247
// for opengroups, we batch everything as there is no expiration timer to take care (and potentially a lot of messages)
12361248

1237-
await Data.markAllAsReadByConversationNoExpiration(this.id);
1249+
const isOpenGroup = this.isOpenGroupV2();
1250+
// if this is an opengroup there is no need to send read receipt, and so no need to fetch messages updated.
1251+
const allReadMessages = await Data.markAllAsReadByConversationNoExpiration(
1252+
this.id,
1253+
!isOpenGroup
1254+
);
12381255
this.set({ mentionedUs: false, unreadCount: 0 });
12391256

12401257
await this.commit();
1241-
return;
1242-
}
1243-
1244-
// if the conversation has no expiration timer, we can also batch everything, but we also need to send read receipts potentially
1245-
// so we grab them from the db
1246-
if (!this.get('expireTimer')) {
1247-
const allReadMessages = await Data.markAllAsReadByConversationNoExpiration(this.id);
1248-
this.set({ mentionedUs: false, unreadCount: 0 });
1249-
await this.commit();
1250-
if (allReadMessages.length) {
1258+
if (!this.isOpenGroupV2() && allReadMessages.length) {
12511259
await this.sendReadReceiptsIfNeeded(uniq(allReadMessages));
12521260
}
1261+
Notifications.clearByConversationID(this.id);
1262+
window.inboxStore?.dispatch(markConversationFullyRead(this.id));
1263+
12531264
return;
12541265
}
1266+
// otherwise, do it the slow way
12551267
await this.markReadBouncy(Date.now());
12561268
}
12571269

ts/node/sql.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,18 +1117,23 @@ function getUnreadByConversation(conversationId: string) {
11171117
* Warning: This does not start expiration timer
11181118
*/
11191119
function markAllAsReadByConversationNoExpiration(
1120-
conversationId: string
1121-
): Array<{ id: string; timestamp: number }> {
1122-
const messagesUnreadBefore = assertGlobalInstance()
1123-
.prepare(
1124-
`SELECT json FROM ${MESSAGES_TABLE} WHERE
1125-
unread = $unread AND
1126-
conversationId = $conversationId;`
1127-
)
1128-
.all({
1129-
unread: 1,
1130-
conversationId,
1131-
});
1120+
conversationId: string,
1121+
returnMessagesUpdated: boolean
1122+
): Array<number> {
1123+
let toReturn: Array<number> = [];
1124+
if (returnMessagesUpdated) {
1125+
const messagesUnreadBefore = assertGlobalInstance()
1126+
.prepare(
1127+
`SELECT json FROM ${MESSAGES_TABLE} WHERE
1128+
unread = $unread AND
1129+
conversationId = $conversationId;`
1130+
)
1131+
.all({
1132+
unread: 1,
1133+
conversationId,
1134+
});
1135+
toReturn = compact(messagesUnreadBefore.map(row => jsonToObject(row.json).sent_at));
1136+
}
11321137

11331138
assertGlobalInstance()
11341139
.prepare(
@@ -1142,7 +1147,7 @@ function markAllAsReadByConversationNoExpiration(
11421147
conversationId,
11431148
});
11441149

1145-
return compact(messagesUnreadBefore.map(row => jsonToObject(row.json).sent_at));
1150+
return toReturn;
11461151
}
11471152

11481153
function getUnreadCountByConversation(conversationId: string) {

ts/state/ducks/conversations.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,11 +699,23 @@ const conversationsSlice = createSlice({
699699
return state;
700700
}
701701

702+
let updatedMessages = state.messages;
703+
704+
// if some are unread, mark them as read
705+
if (state.messages.some(m => m.propsForMessage.isUnread)) {
706+
updatedMessages = state.messages.map(m => ({
707+
...m,
708+
propsForMessage: { ...m.propsForMessage, isUnread: false },
709+
}));
710+
}
711+
702712
// keep the unread visible just like in other apps. It will be shown until the user changes convo
703713
return {
704714
...state,
705715
shouldHighlightMessage: false,
706716
firstUnreadMessageId: undefined,
717+
718+
messages: updatedMessages,
707719
};
708720
},
709721
/**

0 commit comments

Comments
 (0)