Skip to content

Commit aa83014

Browse files
lakshya1goelPIG208
andcommitted
topics: Add TopicListButton to channel action sheet
The icon was taken from CZO discussion: https://chat.zulip.org/#narrow/channel/530-mobile-design/topic/Topic.20list.20in.20channel/near/2140324 Fixes: zulip#1158 Co-authored-by: Zixuan James Li <[email protected]>
1 parent 7600fdf commit aa83014

16 files changed

+90
-13
lines changed

assets/icons/ZulipIcons.ttf

276 Bytes
Binary file not shown.

assets/icons/topics.svg

Lines changed: 3 additions & 0 deletions
Loading

assets/l10n/app_en.arb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@
8484
"@actionSheetOptionMarkChannelAsRead": {
8585
"description": "Label for marking a channel as read."
8686
},
87+
"actionSheetOptionListOfTopics": "List of topics",
88+
"@actionSheetOptionListOfTopics": {
89+
"description": "Label for navigating to a channel's topic-list page."
90+
},
8791
"actionSheetOptionMuteTopic": "Mute topic",
8892
"@actionSheetOptionMuteTopic": {
8993
"description": "Label for muting a topic on action sheet."

lib/generated/l10n/zulip_localizations.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ abstract class ZulipLocalizations {
239239
/// **'Mark channel as read'**
240240
String get actionSheetOptionMarkChannelAsRead;
241241

242+
/// Label for navigating to a channel's topic-list page.
243+
///
244+
/// In en, this message translates to:
245+
/// **'List of topics'**
246+
String get actionSheetOptionListOfTopics;
247+
242248
/// Label for muting a topic on action sheet.
243249
///
244250
/// In en, this message translates to:

lib/generated/l10n/zulip_localizations_ar.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
7676
@override
7777
String get actionSheetOptionMarkChannelAsRead => 'Mark channel as read';
7878

79+
@override
80+
String get actionSheetOptionListOfTopics => 'List of topics';
81+
7982
@override
8083
String get actionSheetOptionMuteTopic => 'Mute topic';
8184

lib/generated/l10n/zulip_localizations_de.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class ZulipLocalizationsDe extends ZulipLocalizations {
7676
@override
7777
String get actionSheetOptionMarkChannelAsRead => 'Mark channel as read';
7878

79+
@override
80+
String get actionSheetOptionListOfTopics => 'List of topics';
81+
7982
@override
8083
String get actionSheetOptionMuteTopic => 'Mute topic';
8184

lib/generated/l10n/zulip_localizations_en.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
7676
@override
7777
String get actionSheetOptionMarkChannelAsRead => 'Mark channel as read';
7878

79+
@override
80+
String get actionSheetOptionListOfTopics => 'List of topics';
81+
7982
@override
8083
String get actionSheetOptionMuteTopic => 'Mute topic';
8184

lib/generated/l10n/zulip_localizations_ja.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
7676
@override
7777
String get actionSheetOptionMarkChannelAsRead => 'Mark channel as read';
7878

79+
@override
80+
String get actionSheetOptionListOfTopics => 'List of topics';
81+
7982
@override
8083
String get actionSheetOptionMuteTopic => 'Mute topic';
8184

lib/generated/l10n/zulip_localizations_nb.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
7676
@override
7777
String get actionSheetOptionMarkChannelAsRead => 'Mark channel as read';
7878

79+
@override
80+
String get actionSheetOptionListOfTopics => 'List of topics';
81+
7982
@override
8083
String get actionSheetOptionMuteTopic => 'Mute topic';
8184

lib/generated/l10n/zulip_localizations_pl.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
7878
String get actionSheetOptionMarkChannelAsRead =>
7979
'Oznacz kanał jako przeczytany';
8080

81+
@override
82+
String get actionSheetOptionListOfTopics => 'List of topics';
83+
8184
@override
8285
String get actionSheetOptionMuteTopic => 'Wycisz wątek';
8386

lib/generated/l10n/zulip_localizations_ru.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
7878
String get actionSheetOptionMarkChannelAsRead =>
7979
'Отметить канал как прочитанный';
8080

81+
@override
82+
String get actionSheetOptionListOfTopics => 'List of topics';
83+
8184
@override
8285
String get actionSheetOptionMuteTopic => 'Отключить тему';
8386

lib/generated/l10n/zulip_localizations_sk.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
7676
@override
7777
String get actionSheetOptionMarkChannelAsRead => 'Mark channel as read';
7878

79+
@override
80+
String get actionSheetOptionListOfTopics => 'List of topics';
81+
7982
@override
8083
String get actionSheetOptionMuteTopic => 'Stlmiť tému';
8184

lib/generated/l10n/zulip_localizations_uk.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class ZulipLocalizationsUk extends ZulipLocalizations {
7979
String get actionSheetOptionMarkChannelAsRead =>
8080
'Позначити канал як прочитаний';
8181

82+
@override
83+
String get actionSheetOptionListOfTopics => 'List of topics';
84+
8285
@override
8386
String get actionSheetOptionMuteTopic => 'Заглушити тему';
8487

lib/widgets/action_sheet.dart

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import 'page.dart';
2929
import 'store.dart';
3030
import 'text.dart';
3131
import 'theme.dart';
32+
import 'topic_list.dart';
3233

3334
void _showActionSheet(
3435
BuildContext context, {
@@ -175,24 +176,43 @@ void showChannelActionSheet(BuildContext context, {
175176
final pageContext = PageRoot.contextOf(context);
176177
final store = PerAccountStoreWidget.of(pageContext);
177178

178-
final optionButtons = <ActionSheetMenuItemButton>[];
179+
final optionButtons = <ActionSheetMenuItemButton>[
180+
TopicListButton(pageContext: pageContext, channelId: channelId),
181+
];
182+
179183
final unreadCount = store.unreads.countInChannelNarrow(channelId);
180184
if (unreadCount > 0) {
181185
optionButtons.add(
182186
MarkChannelAsReadButton(pageContext: pageContext, channelId: channelId));
183187
}
184-
if (optionButtons.isEmpty) {
185-
// TODO(a11y): This case makes a no-op gesture handler; as a consequence,
186-
// we're presenting some UI (to people who use screen-reader software) as
187-
// though it offers a gesture interaction that it doesn't meaningfully
188-
// offer, which is confusing. The solution here is probably to remove this
189-
// is-empty case by having at least one button that's always present,
190-
// such as "copy link to channel".
191-
return;
192-
}
188+
193189
_showActionSheet(pageContext, optionButtons: optionButtons);
194190
}
195191

192+
class TopicListButton extends ActionSheetMenuItemButton {
193+
const TopicListButton({
194+
super.key,
195+
required this.channelId,
196+
required super.pageContext,
197+
});
198+
199+
final int channelId;
200+
201+
@override
202+
IconData get icon => ZulipIcons.topics;
203+
204+
@override
205+
String label(ZulipLocalizations zulipLocalizations) {
206+
return zulipLocalizations.actionSheetOptionListOfTopics;
207+
}
208+
209+
@override
210+
void onPressed() {
211+
Navigator.push(pageContext,
212+
TopicListPage.buildRoute(context: pageContext, streamId: channelId));
213+
}
214+
}
215+
196216
class MarkChannelAsReadButton extends ActionSheetMenuItemButton {
197217
const MarkChannelAsReadButton({
198218
super.key,

lib/widgets/icons.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,14 @@ abstract final class ZulipIcons {
144144
/// The Zulip custom icon "topic".
145145
static const IconData topic = IconData(0xf128, fontFamily: "Zulip Icons");
146146

147+
/// The Zulip custom icon "topics".
148+
static const IconData topics = IconData(0xf129, fontFamily: "Zulip Icons");
149+
147150
/// The Zulip custom icon "unmute".
148-
static const IconData unmute = IconData(0xf129, fontFamily: "Zulip Icons");
151+
static const IconData unmute = IconData(0xf12a, fontFamily: "Zulip Icons");
149152

150153
/// The Zulip custom icon "user".
151-
static const IconData user = IconData(0xf12a, fontFamily: "Zulip Icons");
154+
static const IconData user = IconData(0xf12b, fontFamily: "Zulip Icons");
152155

153156
// END GENERATED ICON DATA
154157
}

test/widgets/action_sheet_test.dart

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ void main() {
227227
void checkButtons() {
228228
check(actionSheetFinder).findsOne();
229229
checkButton('Mark channel as read');
230+
checkButton('List of topics');
230231
}
231232

232233
testWidgets('show from inbox', (tester) async {
@@ -244,7 +245,7 @@ void main() {
244245
testWidgets('show with no unread messages', (tester) async {
245246
await prepare(hasUnreadMessages: false);
246247
await showFromSubscriptionList(tester);
247-
check(actionSheetFinder).findsNothing();
248+
check(findButtonForLabel('Mark channel as read')).findsNothing();
248249
});
249250

250251
testWidgets('show from app bar in channel narrow', (tester) async {
@@ -268,6 +269,19 @@ void main() {
268269
});
269270
});
270271

272+
testWidgets('TopicListButton', (tester) async {
273+
await prepare();
274+
await showFromAppBar(tester,
275+
narrow: ChannelNarrow(someChannel.streamId));
276+
277+
connection.prepare(json: GetStreamTopicsResult(topics: [
278+
eg.getStreamTopicsEntry(name: 'some topic foo'),
279+
]).toJson());
280+
await tester.tap(findButtonForLabel('List of topics'));
281+
await tester.pumpAndSettle();
282+
check(find.text('some topic foo')).findsOne();
283+
});
284+
271285
group('MarkChannelAsReadButton', () {
272286
void checkRequest(int channelId) {
273287
check(connection.takeRequests()).single.isA<http.Request>()

0 commit comments

Comments
 (0)