@@ -20,6 +20,57 @@ import '../notifications/receive.dart';
2020import 'dialog.dart' ;
2121import '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+
2374Future <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-
102107Future <void > markNarrowAsUnreadFromMessage (
103108 BuildContext context,
104109 Message message,
0 commit comments