From e27ae7e226a4c9b3c3d5c85054d0506ecd6309a8 Mon Sep 17 00:00:00 2001 From: Shu Chen Date: Wed, 29 Nov 2023 15:58:57 +0000 Subject: [PATCH] msglist: Unconditionally add ApiNarrowIsUnread to markNarrowAsRead Fixes: #377 --- lib/widgets/message_list.dart | 18 +++++++++++------- test/widgets/message_list_test.dart | 12 ++++++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/widgets/message_list.dart b/lib/widgets/message_list.dart index 4cfc642cce3..48a051a766f 100644 --- a/lib/widgets/message_list.dart +++ b/lib/widgets/message_list.dart @@ -734,13 +734,17 @@ Future markNarrowAsRead(BuildContext context, Narrow narrow) async { int responseCount = 0; int updatedCount = 0; - final apiNarrow = switch (narrow) { - // Since there's a database index on is:unread, it's a fast - // search query and thus worth using as an optimization - // when processing all messages. - AllMessagesNarrow() => [ApiNarrowIsUnread()], - _ => narrow.apiEncode(), - }; + // This process can take a long time in narrows with a lot + // of history given the server ends up processing a large + // number of already read messages. Unconditionally add + // [ApiNarrowIsUnread] here to take advantage of a database + // index on `is:unread`. + // This optimization is also used server side for the + // (deprecated) specialized endpoints for marking messages + // as read. See `do_mark_stream_messages_as_read` in + // `zulip:zerver/actions/message_flags.py`. + final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread()); + while (true) { final result = await updateMessageFlagsForNarrow(connection, anchor: anchor, diff --git a/test/widgets/message_list_test.dart b/test/widgets/message_list_test.dart index c8555e2b74a..e93c7de59e5 100644 --- a/test/widgets/message_list_test.dart +++ b/test/widgets/message_list_test.dart @@ -9,6 +9,7 @@ import 'package:http/http.dart' as http; import 'package:zulip/api/model/events.dart'; import 'package:zulip/api/model/initial_snapshot.dart'; import 'package:zulip/api/model/model.dart'; +import 'package:zulip/api/model/narrow.dart'; import 'package:zulip/api/route/messages.dart'; import 'package:zulip/model/localizations.dart'; import 'package:zulip/model/narrow.dart'; @@ -479,6 +480,7 @@ void main() { firstProcessedId: null, lastProcessedId: null, foundOldest: true, foundNewest: true).toJson()); await tester.tap(find.byType(MarkAsReadWidget)); + final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread()); check(connection.lastRequest).isA() ..method.equals('POST') ..url.path.equals('/api/v1/messages/flags/narrow') @@ -487,7 +489,7 @@ void main() { 'include_anchor': 'false', 'num_before': '0', 'num_after': '1000', - 'narrow': jsonEncode(narrow.apiEncode()), + 'narrow': jsonEncode(apiNarrow), 'op': 'add', 'flag': 'read', }); @@ -537,6 +539,7 @@ void main() { firstProcessedId: 1, lastProcessedId: 1989, foundOldest: true, foundNewest: false).toJson()); await tester.tap(find.byType(MarkAsReadWidget)); + final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread()); check(connection.lastRequest).isA() ..method.equals('POST') ..url.path.equals('/api/v1/messages/flags/narrow') @@ -545,7 +548,7 @@ void main() { 'include_anchor': 'false', 'num_before': '0', 'num_after': '1000', - 'narrow': jsonEncode(narrow.apiEncode()), + 'narrow': jsonEncode(apiNarrow), 'op': 'add', 'flag': 'read', }); @@ -564,7 +567,7 @@ void main() { 'include_anchor': 'false', 'num_before': '0', 'num_after': '1000', - 'narrow': jsonEncode(narrow.apiEncode()), + 'narrow': jsonEncode(apiNarrow), 'op': 'add', 'flag': 'read', }); @@ -583,6 +586,7 @@ void main() { firstProcessedId: null, lastProcessedId: null, foundOldest: true, foundNewest: false).toJson()); await tester.tap(find.byType(MarkAsReadWidget)); + final apiNarrow = narrow.apiEncode()..add(ApiNarrowIsUnread()); check(connection.lastRequest).isA() ..method.equals('POST') ..url.path.equals('/api/v1/messages/flags/narrow') @@ -591,7 +595,7 @@ void main() { 'include_anchor': 'false', 'num_before': '0', 'num_after': '1000', - 'narrow': jsonEncode(narrow.apiEncode()), + 'narrow': jsonEncode(apiNarrow), 'op': 'add', 'flag': 'read', });