@@ -8,6 +8,7 @@ import 'package:share_plus/share_plus.dart';
88
99import  '../api/exception.dart' ;
1010import  '../api/model/model.dart' ;
11+ import  '../api/model/narrow.dart' ;
1112import  '../api/route/channels.dart' ;
1213import  '../api/route/messages.dart' ;
1314import  '../generated/l10n/zulip_localizations.dart' ;
@@ -240,6 +241,14 @@ void showTopicActionSheet(BuildContext context, {
240241      pageContext:  context);
241242  }));
242243
244+   final  unreadCount =  store.unreads.countInTopicNarrow (channelId, topic);
245+   if  (unreadCount >  0 ) {
246+     optionButtons.add (MarkTopicAsReadButton (
247+       channelId:  channelId,
248+       topic:  topic,
249+       pageContext:  context));
250+   }
251+ 
243252  if  (optionButtons.isEmpty) {
244253    // TODO(a11y): This case makes a no-op gesture handler; as a consequence, 
245254    //   we're presenting some UI (to people who use screen-reader software) as 
@@ -372,6 +381,61 @@ class UserTopicUpdateButton extends ActionSheetMenuItemButton {
372381  }
373382}
374383
384+ class  MarkTopicAsReadButton  extends  ActionSheetMenuItemButton  {
385+   const  MarkTopicAsReadButton ({
386+     super .key,
387+     required  this .channelId,
388+     required  this .topic,
389+     required  super .pageContext,
390+   });
391+ 
392+   final  int  channelId;
393+   final  TopicName  topic;
394+ 
395+   @override  IconData  get  icon =>  Icons .mark_chat_read_outlined;
396+ 
397+   @override 
398+   String  label (ZulipLocalizations  zulipLocalizations) {
399+     return  zulipLocalizations.actionSheetOptionMarkTopicAsRead;
400+   }
401+ 
402+   @override  void  onPressed () async  {
403+     final  store =  PerAccountStoreWidget .of (pageContext);
404+     final  connection =  store.connection;
405+     final  zulipLocalizations =  ZulipLocalizations .of (pageContext);
406+ 
407+     try  {
408+       if  (connection.zulipFeatureLevel!  >=  155 ) {
409+         await  updateMessageFlagsForNarrow (connection,
410+           anchor:  AnchorCode .oldest,
411+           numBefore:  0 ,
412+           numAfter:  1000 ,
413+           narrow:  TopicNarrow (channelId, topic).apiEncode ()
414+             ..add (ApiNarrowIs (IsOperand .unread)),
415+           op:  UpdateMessageFlagsOp .add,
416+           flag:  MessageFlag .read);
417+       } else  {
418+         await  markTopicAsRead (connection,
419+           streamId:  channelId,
420+           topicName:  topic);
421+       }
422+     } catch  (e) {
423+       if  (! pageContext.mounted) return ;
424+ 
425+       String ?  errorMessage;
426+       switch  (e) {
427+         case  ZulipApiException (): 
428+           errorMessage =  e.message;
429+         default : 
430+       }
431+ 
432+       showErrorDialog (context:  pageContext,
433+         title:  zulipLocalizations.errorMarkTopicAsReadFailed,
434+         message:  errorMessage);
435+     }
436+   }
437+ }
438+ 
375439/// Show a sheet of actions you can take on a message in the message list. 
376440/// 
377441/// Must have a [MessageListPage]  ancestor. 
0 commit comments