diff --git a/keyserver/src/creators/message-creator.js b/keyserver/src/creators/message-creator.js --- a/keyserver/src/creators/message-creator.js +++ b/keyserver/src/creators/message-creator.js @@ -620,6 +620,10 @@ const lastMessageExpression = SQL` last_message = GREATEST(last_message, CASE `; + const lastMessageForUnreadCheckExpression = SQL` + , last_message_for_unread_check = + GREATEST(last_message_for_unread_check, CASE + `; const lastReadMessageExpression = SQL` , last_read_message = GREATEST(last_read_message, CASE `; @@ -633,6 +637,9 @@ lastMessageExpression.append(SQL` WHEN user = ${userID} AND thread = ${threadID} THEN ${latestMessage} `); + lastMessageForUnreadCheckExpression.append(SQL` + WHEN user = ${userID} AND thread = ${threadID} THEN ${latestMessage} + `); if (latestReadMessage) { shouldUpdateLastReadMessage = true; lastReadMessageExpression.append(SQL` @@ -644,6 +651,10 @@ ELSE last_message END) `); + lastMessageForUnreadCheckExpression.append(SQL` + ELSE last_message_for_unread_check + END) + `); lastReadMessageExpression.append(SQL` ELSE last_read_message END) @@ -654,6 +665,7 @@ ); query.append(lastMessageExpression); + query.append(lastMessageForUnreadCheckExpression); if (shouldUpdateLastReadMessage) { query.append(lastReadMessageExpression); } diff --git a/keyserver/src/updaters/activity-updaters.js b/keyserver/src/updaters/activity-updaters.js --- a/keyserver/src/updaters/activity-updaters.js +++ b/keyserver/src/updaters/activity-updaters.js @@ -495,7 +495,7 @@ threadIDs: $ReadOnlyArray<string>, ) { const query = SQL` - SELECT thread, last_message, last_read_message + SELECT thread, last_message_for_unread_check, last_read_message FROM memberships WHERE user = ${viewer.userID} AND thread IN (${threadIDs}) `; @@ -504,7 +504,7 @@ const lastMessages = new Map<string, LastMessageInfo>(); for (const row of result) { const threadID = row.thread.toString(); - const lastMessage = row.last_message; + const lastMessage = row.last_message_for_unread_check; const lastReadMessage = row.last_read_message; lastMessages.set(threadID, { lastMessage, lastReadMessage }); } diff --git a/keyserver/src/updaters/thread-permission-updaters.js b/keyserver/src/updaters/thread-permission-updaters.js --- a/keyserver/src/updaters/thread-permission-updaters.js +++ b/keyserver/src/updaters/thread-permission-updaters.js @@ -958,7 +958,6 @@ ? JSON.stringify(rowToSave.permissionsForChildren) : null, rowToSave.unread ? 1 : 0, - 0, ]); } @@ -974,7 +973,7 @@ const batch = insertRows.splice(0, membershipInsertBatchSize); const query = SQL` INSERT INTO memberships (user, thread, role, creation_time, subscription, - permissions, permissions_for_children, last_message, last_read_message) + permissions, permissions_for_children, last_message_for_unread_check) VALUES ${batch} ON DUPLICATE KEY UPDATE subscription = IF( @@ -1007,34 +1006,12 @@ thread, ]); - const unreadUserThreadPairs = joinRows - .filter(([, , unread]) => !!unread) - .map(([user, thread]) => [user, thread]); - - let lastReadMessageExpression; - if (unreadUserThreadPairs.length === 0) { - lastReadMessageExpression = SQL` - GREATEST(COALESCE(all_users_query.message, 0), - COALESCE(last_subthread_message_for_user_query.message, 0)) - `; - } else { - lastReadMessageExpression = SQL` - (CASE - WHEN ((mm.user, mm.thread) in (${unreadUserThreadPairs})) THEN 0 - ELSE GREATEST(COALESCE(all_users_query.message, 0), - COALESCE(last_subthread_message_for_user_query.message, 0)) - END) - `; - } - // We join two subqueries with the memberships table: // - the first subquery calculates the oldest non-CREATE_SUB_THREAD // message, which is the same for all users // - the second subquery calculates the oldest CREATE_SUB_THREAD messages, // which can be different for each user because of visibility permissions // Then we set the `last_message` column to the greater value of the two. - // For `last_read_message` we do the same but only if the user should have - // the "unread" status set for this thread. const query = SQL` UPDATE memberships mm LEFT JOIN ( @@ -1053,13 +1030,12 @@ ) last_subthread_message_for_user_query ON mm.thread = last_subthread_message_for_user_query.thread AND mm.user = last_subthread_message_for_user_query.user - SET - mm.last_message = GREATEST(COALESCE(all_users_query.message, 0), - COALESCE(last_subthread_message_for_user_query.message, 0)), - mm.last_read_message = + SET mm.last_message = GREATEST( + COALESCE(all_users_query.message, 0), + COALESCE(last_subthread_message_for_user_query.message, 0) + ) + WHERE (mm.user, mm.thread) IN (${joinedUserThreadPairs}) `; - query.append(lastReadMessageExpression); - query.append(SQL`WHERE (mm.user, mm.thread) IN (${joinedUserThreadPairs});`); await dbQuery(query); } @@ -1082,13 +1058,15 @@ null, 0, 0, + 0, ]); while (insertRows.length > 0) { const batch = insertRows.splice(0, membershipInsertBatchSize); const query = SQL` INSERT INTO memberships (user, thread, role, creation_time, subscription, - permissions, permissions_for_children, last_message, last_read_message) + permissions, permissions_for_children, last_message, last_read_message, + last_message_for_unread_check) VALUES ${batch} ON DUPLICATE KEY UPDATE role = -1, @@ -1096,7 +1074,8 @@ permissions_for_children = NULL, subscription = ${defaultSubscriptionString}, last_message = 0, - last_read_message = 0 + last_read_message = 0, + last_message_for_unread_check = 0 `; await dbQuery(query); }