@@ -163,6 +163,55 @@ class ActionSheetCancelButton extends StatelessWidget {
163163 }
164164}
165165
166+ /// Show a sheet of actions you can take on a channel.
167+ void showChannelActionSheet (BuildContext context, {
168+ required int channelId,
169+ }) {
170+ final pageContext = PageRoot .contextOf (context);
171+ final store = PerAccountStoreWidget .of (pageContext);
172+
173+ final optionButtons = < ActionSheetMenuItemButton > [];
174+ final unreadCount = store.unreads.countInChannelNarrow (channelId);
175+ if (unreadCount > 0 ) {
176+ optionButtons.add (
177+ MarkChannelAsReadButton (pageContext: pageContext,streamId: channelId));
178+ }
179+ if (optionButtons.isEmpty) {
180+ // TODO(a11y): This case makes a no-op gesture handler; as a consequence,
181+ // we're presenting some UI (to people who use screen-reader software) as
182+ // though it offers a gesture interaction that it doesn't meaningfully
183+ // offer, which is confusing. The solution here is probably to remove this
184+ // is-empty case by having at least one button that's always present,
185+ // such as "copy link to channel".
186+ return ;
187+ }
188+ _showActionSheet (pageContext, optionButtons: optionButtons);
189+ }
190+
191+ class MarkChannelAsReadButton extends ActionSheetMenuItemButton {
192+ const MarkChannelAsReadButton ({
193+ super .key,
194+ required this .streamId,
195+ required super .pageContext
196+ });
197+
198+ final int streamId;
199+
200+ @override
201+ IconData get icon => ZulipIcons .message_checked;
202+
203+ @override
204+ String label (ZulipLocalizations zulipLocalizations) {
205+ return zulipLocalizations.actionSheetOptionMarkChannelAsRead;
206+ }
207+
208+ @override
209+ void onPressed () async {
210+ final narrow = ChannelNarrow (streamId);
211+ await ZulipAction .markNarrowAsRead (pageContext, narrow);
212+ }
213+ }
214+
166215/// Show a sheet of actions you can take on a topic.
167216///
168217/// Needs a [PageRoot] ancestor.
0 commit comments