Skip to content

Commit a6a8e22

Browse files
author
chimnayajith
committed
actions [nfc]: Move markNarrowAsRead function into ZulipAction abstract class
Move the high level operation markNarrowAsRead into the new ZulipAction abstract class, per discussion in: https://chat.zulip.org/#narrow/channel/516-mobile-dev-help/topic/.23F1317.20showErrorDialog/near/2080576 This makes it clearer at call sites that the methods combine API operations with UI feedback.
1 parent c66a905 commit a6a8e22

File tree

3 files changed

+61
-56
lines changed

3 files changed

+61
-56
lines changed

lib/widgets/actions.dart

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,57 @@ import '../notifications/receive.dart';
2020
import 'dialog.dart';
2121
import 'store.dart';
2222

23+
/// High-level operations that combine API calls with UI feedback.
24+
///
25+
/// Methods in this class provide UI feedback while performing API operations.
26+
abstract final class ZulipAction {
27+
static Future<void> markNarrowAsRead(BuildContext context, Narrow narrow) async {
28+
final store = PerAccountStoreWidget.of(context);
29+
final connection = store.connection;
30+
final zulipLocalizations = ZulipLocalizations.of(context);
31+
final useLegacy = connection.zulipFeatureLevel! < 155; // TODO(server-6)
32+
if (useLegacy) {
33+
try {
34+
await _legacyMarkNarrowAsRead(context, narrow);
35+
return;
36+
} catch (e) {
37+
if (!context.mounted) return;
38+
showErrorDialog(context: context,
39+
title: zulipLocalizations.errorMarkAsReadFailedTitle,
40+
message: e.toString()); // TODO(#741): extract user-facing message better
41+
return;
42+
}
43+
}
44+
45+
final didPass = await updateMessageFlagsStartingFromAnchor(
46+
context: context,
47+
// Include `is:unread` in the narrow. That has a database index, so
48+
// this can be an important optimization in narrows with a lot of history.
49+
// The server applies the same optimization within the (deprecated)
50+
// specialized endpoints for marking messages as read; see
51+
// `do_mark_stream_messages_as_read` in `zulip:zerver/actions/message_flags.py`.
52+
apiNarrow: narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread)),
53+
// Use [AnchorCode.oldest], because [AnchorCode.firstUnread]
54+
// will be the oldest non-muted unread message, which would
55+
// result in muted unreads older than the first unread not
56+
// being processed.
57+
anchor: AnchorCode.oldest,
58+
// [AnchorCode.oldest] is an anchor ID lower than any valid
59+
// message ID.
60+
includeAnchor: false,
61+
op: UpdateMessageFlagsOp.add,
62+
flag: MessageFlag.read,
63+
onCompletedMessage: zulipLocalizations.markAsReadComplete,
64+
progressMessage: zulipLocalizations.markAsReadInProgress,
65+
onFailedTitle: zulipLocalizations.errorMarkAsReadFailedTitle);
66+
67+
if (!didPass || !context.mounted) return;
68+
if (narrow is CombinedFeedNarrow) {
69+
PerAccountStoreWidget.of(context).unreads.handleAllMessagesReadSuccess();
70+
}
71+
}
72+
}
73+
2374
Future<void> logOutAccount(BuildContext context, int accountId) async {
2475
final globalStore = GlobalStoreWidget.of(context);
2576

@@ -32,7 +83,7 @@ Future<void> logOutAccount(BuildContext context, int accountId) async {
3283
await globalStore.removeAccount(accountId);
3384
}
3485

35-
Future<void> unregisterToken(GlobalStore globalStore, int accountId) async {
86+
Future<void> unregisterToken(GlobalStore globalStore, int accountId) async {
3687
final account = globalStore.getAccount(accountId);
3788
if (account == null) return; // TODO(log)
3889

@@ -53,52 +104,6 @@ Future<void> unregisterToken(GlobalStore globalStore, int accountId) async {
53104
}
54105
}
55106

56-
Future<void> markNarrowAsRead(BuildContext context, Narrow narrow) async {
57-
final store = PerAccountStoreWidget.of(context);
58-
final connection = store.connection;
59-
final zulipLocalizations = ZulipLocalizations.of(context);
60-
final useLegacy = connection.zulipFeatureLevel! < 155; // TODO(server-6)
61-
if (useLegacy) {
62-
try {
63-
await _legacyMarkNarrowAsRead(context, narrow);
64-
return;
65-
} catch (e) {
66-
if (!context.mounted) return;
67-
showErrorDialog(context: context,
68-
title: zulipLocalizations.errorMarkAsReadFailedTitle,
69-
message: e.toString()); // TODO(#741): extract user-facing message better
70-
return;
71-
}
72-
}
73-
74-
final didPass = await updateMessageFlagsStartingFromAnchor(
75-
context: context,
76-
// Include `is:unread` in the narrow. That has a database index, so
77-
// this can be an important optimization in narrows with a lot of history.
78-
// The server applies the same optimization within the (deprecated)
79-
// specialized endpoints for marking messages as read; see
80-
// `do_mark_stream_messages_as_read` in `zulip:zerver/actions/message_flags.py`.
81-
apiNarrow: narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread)),
82-
// Use [AnchorCode.oldest], because [AnchorCode.firstUnread]
83-
// will be the oldest non-muted unread message, which would
84-
// result in muted unreads older than the first unread not
85-
// being processed.
86-
anchor: AnchorCode.oldest,
87-
// [AnchorCode.oldest] is an anchor ID lower than any valid
88-
// message ID.
89-
includeAnchor: false,
90-
op: UpdateMessageFlagsOp.add,
91-
flag: MessageFlag.read,
92-
onCompletedMessage: zulipLocalizations.markAsReadComplete,
93-
progressMessage: zulipLocalizations.markAsReadInProgress,
94-
onFailedTitle: zulipLocalizations.errorMarkAsReadFailedTitle);
95-
96-
if (!didPass || !context.mounted) return;
97-
if (narrow is CombinedFeedNarrow) {
98-
PerAccountStoreWidget.of(context).unreads.handleAllMessagesReadSuccess();
99-
}
100-
}
101-
102107
Future<void> markNarrowAsUnreadFromMessage(
103108
BuildContext context,
104109
Message message,

lib/widgets/message_list.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ class _MarkAsReadWidgetState extends State<MarkAsReadWidget> {
788788
void _handlePress(BuildContext context) async {
789789
if (!context.mounted) return;
790790
setState(() => _loading = true);
791-
await markNarrowAsRead(context, widget.narrow);
791+
await ZulipAction.markNarrowAsRead(context, widget.narrow);
792792
setState(() => _loading = false);
793793
}
794794

test/widgets/actions_test.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ void main() {
289289
processedCount: 11, updatedCount: 3,
290290
firstProcessedId: null, lastProcessedId: null,
291291
foundOldest: true, foundNewest: true).toJson());
292-
final future = markNarrowAsRead(context, narrow);
292+
final future = ZulipAction.markNarrowAsRead(context, narrow);
293293
await tester.pump(Duration.zero);
294294
await future;
295295
final apiNarrow = narrow.apiEncode()..add(ApiNarrowIs(IsOperand.unread));
@@ -314,7 +314,7 @@ void main() {
314314
processedCount: 11, updatedCount: 3,
315315
firstProcessedId: null, lastProcessedId: null,
316316
foundOldest: true, foundNewest: true).toJson());
317-
final future = markNarrowAsRead(context, narrow);
317+
final future = ZulipAction.markNarrowAsRead(context, narrow);
318318
await tester.pump(Duration.zero);
319319
await future;
320320
check(connection.lastRequest).isA<http.Request>()
@@ -340,7 +340,7 @@ void main() {
340340
processedCount: 11, updatedCount: 3,
341341
firstProcessedId: null, lastProcessedId: null,
342342
foundOldest: true, foundNewest: true).toJson());
343-
final future = markNarrowAsRead(context, narrow);
343+
final future = ZulipAction.markNarrowAsRead(context, narrow);
344344
await tester.pump(Duration.zero);
345345
await future;
346346
check(store.unreads.oldUnreadsMissing).isFalse();
@@ -354,7 +354,7 @@ void main() {
354354

355355
connection.zulipFeatureLevel = 154;
356356
connection.prepare(json: {});
357-
final future = markNarrowAsRead(context, narrow);
357+
final future = ZulipAction.markNarrowAsRead(context, narrow);
358358
await tester.pump(Duration.zero);
359359
await future;
360360
check(connection.lastRequest).isA<http.Request>()
@@ -373,7 +373,7 @@ void main() {
373373
await prepare(tester);
374374
connection.zulipFeatureLevel = 154;
375375
connection.prepare(json: {});
376-
final future = markNarrowAsRead(context, narrow);
376+
final future = ZulipAction.markNarrowAsRead(context, narrow);
377377
await tester.pump(Duration.zero);
378378
await future;
379379
check(connection.lastRequest).isA<http.Request>()
@@ -389,7 +389,7 @@ void main() {
389389
await prepare(tester);
390390
connection.zulipFeatureLevel = 154;
391391
connection.prepare(json: {});
392-
final future = markNarrowAsRead(context, narrow);
392+
final future = ZulipAction.markNarrowAsRead(context, narrow);
393393
await tester.pump(Duration.zero);
394394
await future;
395395
check(connection.lastRequest).isA<http.Request>()
@@ -412,7 +412,7 @@ void main() {
412412
connection.zulipFeatureLevel = 154;
413413
connection.prepare(json:
414414
UpdateMessageFlagsResult(messages: [message.id]).toJson());
415-
final future = markNarrowAsRead(context, narrow);
415+
final future = ZulipAction.markNarrowAsRead(context, narrow);
416416
await tester.pump(Duration.zero);
417417
await future;
418418
check(connection.lastRequest).isA<http.Request>()
@@ -433,7 +433,7 @@ void main() {
433433
connection.zulipFeatureLevel = 154;
434434
connection.prepare(json:
435435
UpdateMessageFlagsResult(messages: [message.id]).toJson());
436-
final future = markNarrowAsRead(context, narrow);
436+
final future = ZulipAction.markNarrowAsRead(context, narrow);
437437
await tester.pump(Duration.zero);
438438
await future;
439439
check(connection.lastRequest).isA<http.Request>()

0 commit comments

Comments
 (0)