Skip to content

Commit 3ccccf3

Browse files
committed
topicList: Add topic list page for each channel
fixes: zulip#1158
1 parent e524e6b commit 3ccccf3

21 files changed

+851
-42
lines changed

assets/icons/ZulipIcons.ttf

268 Bytes
Binary file not shown.

assets/icons/chevron_down.svg

+3
Loading

assets/icons/list.svg

+1
Loading

assets/l10n/app_en.arb

+16
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@
108108
"@actionSheetOptionUnresolveTopic": {
109109
"description": "Label for the 'Mark as unresolved' button on the topic action sheet."
110110
},
111+
"actionSheetOptionTopicList": "Topic list",
112+
"@actionSheetOptionTopicList": {
113+
"description": "Label for a button in the channel action sheet that opens the list of topics in the channel"
114+
},
111115
"errorResolveTopicFailedTitle": "Failed to mark topic as resolved",
112116
"@errorResolveTopicFailedTitle": {
113117
"description": "Error title when marking a topic as resolved failed."
@@ -697,6 +701,10 @@
697701
"@channelFeedButtonTooltip": {
698702
"description": "Tooltip for button to navigate to a given channel's feed"
699703
},
704+
"topicListButtonTooltip": "Topic list",
705+
"@topicListButtonTooltip": {
706+
"description": "Tooltip for button to navigate to topic list page."
707+
},
700708
"notifGroupDmConversationLabel": "{senderFullName} to you and {numOthers, plural, =1{1 other} other{{numOthers} others}}",
701709
"@notifGroupDmConversationLabel": {
702710
"description": "Label for a group DM conversation notification.",
@@ -855,6 +863,14 @@
855863
"@emojiPickerSearchEmoji": {
856864
"description": "Hint text for the emoji picker search text field."
857865
},
866+
"errorFetchingTopics": "Error fetching topics",
867+
"@errorFetchingTopics": {
868+
"description": "Error title when fetching the topics failed."
869+
},
870+
"noTopicsInChannel": "No topics in the channel",
871+
"@noTopicsInChannel": {
872+
"description": "Text to show when a channel has no topics."
873+
},
858874
"noEarlierMessages": "No earlier messages",
859875
"@noEarlierMessages": {
860876
"description": "Text to show at the start of a message list if there are no earlier messages."

lib/generated/l10n/zulip_localizations.dart

+24
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ abstract class ZulipLocalizations {
267267
/// **'Mark as unresolved'**
268268
String get actionSheetOptionUnresolveTopic;
269269

270+
/// Label for a button in the channel action sheet that opens the list of topics in the channel
271+
///
272+
/// In en, this message translates to:
273+
/// **'Topic list'**
274+
String get actionSheetOptionTopicList;
275+
270276
/// Error title when marking a topic as resolved failed.
271277
///
272278
/// In en, this message translates to:
@@ -1035,6 +1041,12 @@ abstract class ZulipLocalizations {
10351041
/// **'Channel feed'**
10361042
String get channelFeedButtonTooltip;
10371043

1044+
/// Tooltip for button to navigate to topic list page.
1045+
///
1046+
/// In en, this message translates to:
1047+
/// **'Topic list'**
1048+
String get topicListButtonTooltip;
1049+
10381050
/// Label for a group DM conversation notification.
10391051
///
10401052
/// In en, this message translates to:
@@ -1251,6 +1263,18 @@ abstract class ZulipLocalizations {
12511263
/// **'Search emoji'**
12521264
String get emojiPickerSearchEmoji;
12531265

1266+
/// Error title when fetching the topics failed.
1267+
///
1268+
/// In en, this message translates to:
1269+
/// **'Error fetching topics'**
1270+
String get errorFetchingTopics;
1271+
1272+
/// Text to show when a channel has no topics.
1273+
///
1274+
/// In en, this message translates to:
1275+
/// **'No topics in the channel'**
1276+
String get noTopicsInChannel;
1277+
12541278
/// Text to show at the start of a message list if there are no earlier messages.
12551279
///
12561280
/// In en, this message translates to:

lib/generated/l10n/zulip_localizations_ar.dart

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
9191
@override
9292
String get actionSheetOptionUnresolveTopic => 'Mark as unresolved';
9393

94+
@override
95+
String get actionSheetOptionTopicList => 'Topic list';
96+
9497
@override
9598
String get errorResolveTopicFailedTitle => 'Failed to mark topic as resolved';
9699

@@ -545,6 +548,9 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
545548
@override
546549
String get channelFeedButtonTooltip => 'Channel feed';
547550

551+
@override
552+
String get topicListButtonTooltip => 'Topic list';
553+
548554
@override
549555
String notifGroupDmConversationLabel(String senderFullName, int numOthers) {
550556
String _temp0 = intl.Intl.pluralLogic(
@@ -667,6 +673,12 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
667673
@override
668674
String get emojiPickerSearchEmoji => 'Search emoji';
669675

676+
@override
677+
String get errorFetchingTopics => 'Error fetching topics';
678+
679+
@override
680+
String get noTopicsInChannel => 'No topics in the channel';
681+
670682
@override
671683
String get noEarlierMessages => 'No earlier messages';
672684

lib/generated/l10n/zulip_localizations_en.dart

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
9191
@override
9292
String get actionSheetOptionUnresolveTopic => 'Mark as unresolved';
9393

94+
@override
95+
String get actionSheetOptionTopicList => 'Topic list';
96+
9497
@override
9598
String get errorResolveTopicFailedTitle => 'Failed to mark topic as resolved';
9699

@@ -545,6 +548,9 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
545548
@override
546549
String get channelFeedButtonTooltip => 'Channel feed';
547550

551+
@override
552+
String get topicListButtonTooltip => 'Topic list';
553+
548554
@override
549555
String notifGroupDmConversationLabel(String senderFullName, int numOthers) {
550556
String _temp0 = intl.Intl.pluralLogic(
@@ -667,6 +673,12 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
667673
@override
668674
String get emojiPickerSearchEmoji => 'Search emoji';
669675

676+
@override
677+
String get errorFetchingTopics => 'Error fetching topics';
678+
679+
@override
680+
String get noTopicsInChannel => 'No topics in the channel';
681+
670682
@override
671683
String get noEarlierMessages => 'No earlier messages';
672684

lib/generated/l10n/zulip_localizations_ja.dart

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
9191
@override
9292
String get actionSheetOptionUnresolveTopic => 'Mark as unresolved';
9393

94+
@override
95+
String get actionSheetOptionTopicList => 'Topic list';
96+
9497
@override
9598
String get errorResolveTopicFailedTitle => 'Failed to mark topic as resolved';
9699

@@ -545,6 +548,9 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
545548
@override
546549
String get channelFeedButtonTooltip => 'Channel feed';
547550

551+
@override
552+
String get topicListButtonTooltip => 'Topic list';
553+
548554
@override
549555
String notifGroupDmConversationLabel(String senderFullName, int numOthers) {
550556
String _temp0 = intl.Intl.pluralLogic(
@@ -667,6 +673,12 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
667673
@override
668674
String get emojiPickerSearchEmoji => 'Search emoji';
669675

676+
@override
677+
String get errorFetchingTopics => 'Error fetching topics';
678+
679+
@override
680+
String get noTopicsInChannel => 'No topics in the channel';
681+
670682
@override
671683
String get noEarlierMessages => 'No earlier messages';
672684

lib/generated/l10n/zulip_localizations_nb.dart

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
9191
@override
9292
String get actionSheetOptionUnresolveTopic => 'Mark as unresolved';
9393

94+
@override
95+
String get actionSheetOptionTopicList => 'Topic list';
96+
9497
@override
9598
String get errorResolveTopicFailedTitle => 'Failed to mark topic as resolved';
9699

@@ -545,6 +548,9 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
545548
@override
546549
String get channelFeedButtonTooltip => 'Channel feed';
547550

551+
@override
552+
String get topicListButtonTooltip => 'Topic list';
553+
548554
@override
549555
String notifGroupDmConversationLabel(String senderFullName, int numOthers) {
550556
String _temp0 = intl.Intl.pluralLogic(
@@ -667,6 +673,12 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
667673
@override
668674
String get emojiPickerSearchEmoji => 'Search emoji';
669675

676+
@override
677+
String get errorFetchingTopics => 'Error fetching topics';
678+
679+
@override
680+
String get noTopicsInChannel => 'No topics in the channel';
681+
670682
@override
671683
String get noEarlierMessages => 'No earlier messages';
672684

lib/generated/l10n/zulip_localizations_pl.dart

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
9191
@override
9292
String get actionSheetOptionUnresolveTopic => 'Oznacz brak rozwiązania';
9393

94+
@override
95+
String get actionSheetOptionTopicList => 'Topic list';
96+
9497
@override
9598
String get errorResolveTopicFailedTitle => 'Nie udało się oznaczyć jako rozwiązany';
9699

@@ -545,6 +548,9 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
545548
@override
546549
String get channelFeedButtonTooltip => 'Strumień kanału';
547550

551+
@override
552+
String get topicListButtonTooltip => 'Topic list';
553+
548554
@override
549555
String notifGroupDmConversationLabel(String senderFullName, int numOthers) {
550556
String _temp0 = intl.Intl.pluralLogic(
@@ -667,6 +673,12 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
667673
@override
668674
String get emojiPickerSearchEmoji => 'Szukaj emoji';
669675

676+
@override
677+
String get errorFetchingTopics => 'Error fetching topics';
678+
679+
@override
680+
String get noTopicsInChannel => 'No topics in the channel';
681+
670682
@override
671683
String get noEarlierMessages => 'Brak historii';
672684

lib/generated/l10n/zulip_localizations_ru.dart

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
9191
@override
9292
String get actionSheetOptionUnresolveTopic => 'Mark as unresolved';
9393

94+
@override
95+
String get actionSheetOptionTopicList => 'Topic list';
96+
9497
@override
9598
String get errorResolveTopicFailedTitle => 'Failed to mark topic as resolved';
9699

@@ -545,6 +548,9 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
545548
@override
546549
String get channelFeedButtonTooltip => 'Лента канала';
547550

551+
@override
552+
String get topicListButtonTooltip => 'Topic list';
553+
548554
@override
549555
String notifGroupDmConversationLabel(String senderFullName, int numOthers) {
550556
String _temp0 = intl.Intl.pluralLogic(
@@ -667,6 +673,12 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
667673
@override
668674
String get emojiPickerSearchEmoji => 'Поиск эмодзи';
669675

676+
@override
677+
String get errorFetchingTopics => 'Error fetching topics';
678+
679+
@override
680+
String get noTopicsInChannel => 'No topics in the channel';
681+
670682
@override
671683
String get noEarlierMessages => 'No earlier messages';
672684

lib/generated/l10n/zulip_localizations_sk.dart

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
9191
@override
9292
String get actionSheetOptionUnresolveTopic => 'Mark as unresolved';
9393

94+
@override
95+
String get actionSheetOptionTopicList => 'Topic list';
96+
9497
@override
9598
String get errorResolveTopicFailedTitle => 'Failed to mark topic as resolved';
9699

@@ -545,6 +548,9 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
545548
@override
546549
String get channelFeedButtonTooltip => 'Channel feed';
547550

551+
@override
552+
String get topicListButtonTooltip => 'Topic list';
553+
548554
@override
549555
String notifGroupDmConversationLabel(String senderFullName, int numOthers) {
550556
String _temp0 = intl.Intl.pluralLogic(
@@ -667,6 +673,12 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
667673
@override
668674
String get emojiPickerSearchEmoji => 'Hľadať emotikon';
669675

676+
@override
677+
String get errorFetchingTopics => 'Error fetching topics';
678+
679+
@override
680+
String get noTopicsInChannel => 'No topics in the channel';
681+
670682
@override
671683
String get noEarlierMessages => 'No earlier messages';
672684

lib/model/topic_list.dart

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'package:flutter/foundation.dart';
2+
import '../api/route/channels.dart';
3+
import '../model/store.dart';
4+
5+
class TopicListView extends ChangeNotifier {
6+
TopicListView({required this.store, required this.streamId});
7+
8+
final PerAccountStore store;
9+
final int streamId;
10+
11+
bool _isLoading = true;
12+
bool _hasError = false;
13+
String _errorMessage = '';
14+
List<GetStreamTopicsEntry>? _topics;
15+
16+
bool get isLoading => _isLoading;
17+
bool get hasError => _hasError;
18+
String get errorMessage => _errorMessage;
19+
List<GetStreamTopicsEntry>? get topics => _topics;
20+
21+
Future<void> fetchTopics() async {
22+
_isLoading = true;
23+
_hasError = false;
24+
_errorMessage = '';
25+
notifyListeners();
26+
27+
try {
28+
final response = await getStreamTopics(store.connection, streamId: streamId);
29+
_topics = response.topics;
30+
_isLoading = false;
31+
} catch (e) {
32+
_isLoading = false;
33+
_hasError = true;
34+
_errorMessage = e.toString();
35+
}
36+
notifyListeners();
37+
}
38+
}

0 commit comments

Comments
 (0)