@@ -25,6 +25,7 @@ import { SignalService } from '../protobuf';
25
25
import { MessageModel , sliceQuoteText } from './message' ;
26
26
import { MessageAttributesOptionals , MessageDirection } from './messageType' ;
27
27
import autoBind from 'auto-bind' ;
28
+
28
29
import { Data } from '../../ts/data/data' ;
29
30
import { toHex } from '../session/utils/String' ;
30
31
import {
@@ -1223,15 +1224,49 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
1223
1224
}
1224
1225
}
1225
1226
1227
+ /**
1228
+ * Mark everything as read efficiently if possible.
1229
+ *
1230
+ * For convos with a expiration timer enable, start the timer as of now.
1231
+ * Send read receipt if needed.
1232
+ */
1233
+ public async markAllAsRead ( ) {
1234
+ if ( this . isOpenGroupV2 ( ) ) {
1235
+ // for opengroups, we batch everything as there is no expiration timer to take care (and potentially a lot of messages)
1236
+
1237
+ await Data . markAllAsReadByConversationNoExpiration ( this . id ) ;
1238
+ this . set ( { mentionedUs : false , unreadCount : 0 } ) ;
1239
+
1240
+ 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 ) {
1251
+ await this . sendReadReceiptsIfNeeded ( uniq ( allReadMessages ) ) ;
1252
+ }
1253
+ return ;
1254
+ }
1255
+ await this . markReadBouncy ( Date . now ( ) ) ;
1256
+ }
1257
+
1226
1258
// tslint:disable-next-line: cyclomatic-complexity
1227
- public async markReadBouncy ( newestUnreadDate : number , providedOptions : any = { } ) {
1259
+ public async markReadBouncy (
1260
+ newestUnreadDate : number ,
1261
+ providedOptions : { sendReadReceipts ?: boolean ; readAt ?: number } = { }
1262
+ ) {
1228
1263
const lastReadTimestamp = this . lastReadTimestamp ;
1229
1264
if ( newestUnreadDate < lastReadTimestamp ) {
1230
1265
return ;
1231
1266
}
1232
1267
1233
- const options = providedOptions || { } ;
1234
- defaults ( options , { sendReadReceipts : true } ) ;
1268
+ const readAt = providedOptions ?. readAt || Date . now ( ) ;
1269
+ const sendReadReceipts = providedOptions ?. sendReadReceipts || true ;
1235
1270
1236
1271
const conversationId = this . id ;
1237
1272
Notifications . clearByConversationID ( conversationId ) ;
@@ -1245,7 +1280,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
1245
1280
1246
1281
// Build the list of updated message models so we can mark them all as read on a single sqlite call
1247
1282
for ( const nowRead of oldUnreadNowRead ) {
1248
- nowRead . markReadNoCommit ( options . readAt ) ;
1283
+ nowRead . markReadNoCommit ( readAt ) ;
1249
1284
1250
1285
const errors = nowRead . get ( 'errors' ) ;
1251
1286
read . push ( {
@@ -1307,7 +1342,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
1307
1342
// conversation is viewed, another error message shows up for the contact
1308
1343
read = read . filter ( item => ! item . hasErrors ) ;
1309
1344
1310
- if ( read . length && options . sendReadReceipts ) {
1345
+ if ( read . length && sendReadReceipts ) {
1311
1346
const timestamps = map ( read , 'timestamp' ) . filter ( t => ! ! t ) as Array < number > ;
1312
1347
await this . sendReadReceiptsIfNeeded ( timestamps ) ;
1313
1348
}
0 commit comments