Skip to content

Commit 219972a

Browse files
gnpricechrisbobbe
authored andcommitted
model [nfc]: Use TopicName type across our model code
We do this all together in one commit, to avoid trying to disentangle the graph of how topics get passed around among the various parts of our model.
1 parent 1bf5178 commit 219972a

19 files changed

+54
-49
lines changed

lib/model/autocomplete.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
485485
required Narrow narrow,
486486
}) {
487487
int? streamId;
488-
String? topic;
488+
TopicName? topic;
489489
switch (narrow) {
490490
case ChannelNarrow():
491491
streamId = narrow.streamId;
@@ -506,7 +506,7 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
506506

507507
static int _compareByRelevance(User userA, User userB, {
508508
required int? streamId,
509-
required String? topic,
509+
required TopicName? topic,
510510
required PerAccountStore store,
511511
}) {
512512
// TODO(#234): give preference to "all", "everyone" or "stream"
@@ -543,7 +543,7 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
543543
@visibleForTesting
544544
static int compareByRecency(User userA, User userB, {
545545
required int streamId,
546-
required String? topic,
546+
required TopicName? topic,
547547
required PerAccountStore store,
548548
}) {
549549
final recentSenders = store.recentSenders;
@@ -815,7 +815,7 @@ class TopicAutocompleteView extends AutocompleteView<TopicAutocompleteQuery, Top
815815
/// The channel/stream the eventual message will be sent to.
816816
final int streamId;
817817

818-
Iterable<String> _topics = [];
818+
Iterable<TopicName> _topics = [];
819819
bool _isFetching = false;
820820

821821
/// Fetches topics of the current stream narrow, expected to fetch
@@ -843,7 +843,7 @@ class TopicAutocompleteView extends AutocompleteView<TopicAutocompleteQuery, Top
843843
return results;
844844
}
845845

846-
TopicAutocompleteResult? _testTopic(TopicAutocompleteQuery query, String topic) {
846+
TopicAutocompleteResult? _testTopic(TopicAutocompleteQuery query, TopicName topic) {
847847
if (query.testTopic(topic)) {
848848
return TopicAutocompleteResult(topic: topic);
849849
}
@@ -862,7 +862,7 @@ class TopicAutocompleteView extends AutocompleteView<TopicAutocompleteQuery, Top
862862
class TopicAutocompleteQuery extends AutocompleteQuery {
863863
TopicAutocompleteQuery(super.raw);
864864

865-
bool testTopic(String topic) {
865+
bool testTopic(TopicName topic) {
866866
// TODO(#881): Sort by match relevance, like web does.
867867
return topic != raw && topic.toLowerCase().contains(raw.toLowerCase());
868868
}
@@ -883,7 +883,7 @@ class TopicAutocompleteQuery extends AutocompleteQuery {
883883

884884
/// A topic chosen in an autocomplete interaction, via a [TopicAutocompleteView].
885885
class TopicAutocompleteResult extends AutocompleteResult {
886-
final String topic;
886+
final TopicName topic;
887887

888888
TopicAutocompleteResult({required this.topic});
889889
}

lib/model/channel.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ mixin ChannelStore {
4141
///
4242
/// For policies directly applicable in the UI, see
4343
/// [isTopicVisibleInStream] and [isTopicVisible].
44-
UserTopicVisibilityPolicy topicVisibilityPolicy(int streamId, String topic);
44+
UserTopicVisibilityPolicy topicVisibilityPolicy(int streamId, TopicName topic);
4545

4646
/// The raw data structure underlying [topicVisibilityPolicy].
4747
///
@@ -51,7 +51,7 @@ mixin ChannelStore {
5151
/// and on the other hand being a concrete, finite data structure that
5252
/// can be compared using `deepEquals`.
5353
@visibleForTesting
54-
Map<int, Map<String, UserTopicVisibilityPolicy>> get debugTopicVisibility;
54+
Map<int, Map<TopicName, UserTopicVisibilityPolicy>> get debugTopicVisibility;
5555

5656
/// Whether this topic should appear when already focusing on its stream.
5757
///
@@ -63,7 +63,7 @@ mixin ChannelStore {
6363
///
6464
/// For UI contexts that are not specific to a particular stream, see
6565
/// [isTopicVisible].
66-
bool isTopicVisibleInStream(int streamId, String topic) {
66+
bool isTopicVisibleInStream(int streamId, TopicName topic) {
6767
return _isTopicVisibleInStream(topicVisibilityPolicy(streamId, topic));
6868
}
6969

@@ -100,7 +100,7 @@ mixin ChannelStore {
100100
///
101101
/// For UI contexts that are specific to a particular stream, see
102102
/// [isTopicVisibleInStream].
103-
bool isTopicVisible(int streamId, String topic) {
103+
bool isTopicVisible(int streamId, TopicName topic) {
104104
return _isTopicVisible(streamId, topicVisibilityPolicy(streamId, topic));
105105
}
106106

@@ -171,7 +171,7 @@ class ChannelStoreImpl with ChannelStore {
171171
streams.putIfAbsent(stream.streamId, () => stream);
172172
}
173173

174-
final topicVisibility = <int, Map<String, UserTopicVisibilityPolicy>>{};
174+
final topicVisibility = <int, Map<TopicName, UserTopicVisibilityPolicy>>{};
175175
for (final item in initialSnapshot.userTopics ?? const <UserTopicItem>[]) {
176176
if (_warnInvalidVisibilityPolicy(item.visibilityPolicy)) {
177177
// Not a value we expect. Keep it out of our data structures. // TODO(log)
@@ -204,12 +204,12 @@ class ChannelStoreImpl with ChannelStore {
204204
final Map<int, Subscription> subscriptions;
205205

206206
@override
207-
Map<int, Map<String, UserTopicVisibilityPolicy>> get debugTopicVisibility => topicVisibility;
207+
Map<int, Map<TopicName, UserTopicVisibilityPolicy>> get debugTopicVisibility => topicVisibility;
208208

209-
final Map<int, Map<String, UserTopicVisibilityPolicy>> topicVisibility;
209+
final Map<int, Map<TopicName, UserTopicVisibilityPolicy>> topicVisibility;
210210

211211
@override
212-
UserTopicVisibilityPolicy topicVisibilityPolicy(int streamId, String topic) {
212+
UserTopicVisibilityPolicy topicVisibilityPolicy(int streamId, TopicName topic) {
213213
return topicVisibility[streamId]?[topic] ?? UserTopicVisibilityPolicy.none;
214214
}
215215

lib/model/internal_link.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/foundation.dart';
22
import 'package:json_annotation/json_annotation.dart';
33

4+
import '../api/model/model.dart';
45
import '../api/model/narrow.dart';
56
import 'narrow.dart';
67
import 'store.dart';
@@ -178,7 +179,7 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
178179
if (topicElement != null) return null;
179180
final String? topic = decodeHashComponent(operand);
180181
if (topic == null) return null;
181-
topicElement = ApiNarrowTopic(topic, negated: negated);
182+
topicElement = ApiNarrowTopic(TopicName(topic), negated: negated);
182183

183184
case _NarrowOperator.dm:
184185
case _NarrowOperator.pmWith:
@@ -223,7 +224,7 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
223224
} else if (streamElement != null) {
224225
final streamId = streamElement.operand;
225226
if (topicElement != null) {
226-
return TopicNarrow(streamId, topicElement.operand);
227+
return TopicNarrow(streamId, TopicName.fromJson(topicElement.operand));
227228
} else {
228229
return ChannelNarrow(streamId);
229230
}

lib/model/message_list.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,8 @@ class MessageListView with ChangeNotifier, _MessageSequence {
686686
void messagesMoved({
687687
required int origStreamId,
688688
required int newStreamId,
689-
required String origTopic,
690-
required String newTopic,
689+
required TopicName origTopic,
690+
required TopicName newTopic,
691691
required List<int> messageIds,
692692
required PropagateMode propagateMode,
693693
}) {

lib/model/narrow.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class TopicNarrow extends Narrow implements SendableNarrow {
9999
}
100100

101101
final int streamId;
102-
final String topic;
102+
final TopicName topic;
103103

104104
@override
105105
bool containsMessage(Message message) {

lib/model/recent_senders.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class RecentSenders {
1616

1717
// topicSenders[streamId][topic][senderId] = MessageIdTracker
1818
@visibleForTesting
19-
final Map<int, Map<String, Map<int, MessageIdTracker>>> topicSenders = {};
19+
final Map<int, Map<TopicName, Map<int, MessageIdTracker>>> topicSenders = {};
2020

2121
/// The latest message the given user sent to the given stream,
2222
/// or null if no such message is known.
@@ -29,7 +29,7 @@ class RecentSenders {
2929
/// or null if no such message is known.
3030
int? latestMessageIdOfSenderInTopic({
3131
required int streamId,
32-
required String topic,
32+
required TopicName topic,
3333
required int senderId,
3434
}) => topicSenders[streamId]?[topic]?[senderId]?.maxId;
3535

@@ -38,7 +38,7 @@ class RecentSenders {
3838
/// The messages must be sorted by [Message.id] ascending.
3939
void handleMessages(List<Message> messages) {
4040
final messagesByUserInStream = <(int, int), QueueList<int>>{};
41-
final messagesByUserInTopic = <(int, String, int), QueueList<int>>{};
41+
final messagesByUserInTopic = <(int, TopicName, int), QueueList<int>>{};
4242
for (final message in messages) {
4343
if (message is! StreamMessage) continue;
4444
final StreamMessage(:streamId, :topic, :senderId, id: int messageId) = message;

lib/model/store.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,10 +466,10 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess
466466
@override
467467
Map<int, Subscription> get subscriptions => _channels.subscriptions;
468468
@override
469-
UserTopicVisibilityPolicy topicVisibilityPolicy(int streamId, String topic) =>
469+
UserTopicVisibilityPolicy topicVisibilityPolicy(int streamId, TopicName topic) =>
470470
_channels.topicVisibilityPolicy(streamId, topic);
471471
@override
472-
Map<int, Map<String, UserTopicVisibilityPolicy>> get debugTopicVisibility =>
472+
Map<int, Map<TopicName, UserTopicVisibilityPolicy>> get debugTopicVisibility =>
473473
_channels.debugTopicVisibility;
474474

475475
final ChannelStoreImpl _channels;

lib/model/unreads.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Unreads extends ChangeNotifier {
4040
required int selfUserId,
4141
required ChannelStore channelStore,
4242
}) {
43-
final streams = <int, Map<String, QueueList<int>>>{};
43+
final streams = <int, Map<TopicName, QueueList<int>>>{};
4444
final dms = <DmNarrow, QueueList<int>>{};
4545
final mentions = Set.of(initial.mentions);
4646

@@ -86,7 +86,7 @@ class Unreads extends ChangeNotifier {
8686
// int count;
8787

8888
/// Unread stream messages, as: stream ID → topic → message IDs (sorted).
89-
final Map<int, Map<String, QueueList<int>>> streams;
89+
final Map<int, Map<TopicName, QueueList<int>>> streams;
9090

9191
/// Unread DM messages, as: DM narrow → message IDs (sorted).
9292
final Map<DmNarrow, QueueList<int>> dms;
@@ -185,7 +185,7 @@ class Unreads extends ChangeNotifier {
185185
return c;
186186
}
187187

188-
int countInTopicNarrow(int streamId, String topic) {
188+
int countInTopicNarrow(int streamId, TopicName topic) {
189189
final topics = streams[streamId];
190190
return topics?[topic]?.length ?? 0;
191191
}
@@ -365,7 +365,7 @@ class Unreads extends ChangeNotifier {
365365
_slowRemoveAllInDms(messageIdsSet);
366366
}
367367
case UpdateMessageFlagsRemoveEvent():
368-
final newlyUnreadInStreams = <int, Map<String, QueueList<int>>>{};
368+
final newlyUnreadInStreams = <int, Map<TopicName, QueueList<int>>>{};
369369
final newlyUnreadInDms = <DmNarrow, QueueList<int>>{};
370370
for (final messageId in event.messages) {
371371
final detail = event.messageDetails![messageId];
@@ -449,12 +449,12 @@ class Unreads extends ChangeNotifier {
449449
);
450450
}
451451

452-
void _addLastInStreamTopic(int messageId, int streamId, String topic) {
452+
void _addLastInStreamTopic(int messageId, int streamId, TopicName topic) {
453453
((streams[streamId] ??= {})[topic] ??= QueueList()).addLast(messageId);
454454
}
455455

456456
// [messageIds] must be sorted ascending and without duplicates.
457-
void _addAllInStreamTopic(QueueList<int> messageIds, int streamId, String topic) {
457+
void _addAllInStreamTopic(QueueList<int> messageIds, int streamId, TopicName topic) {
458458
final topics = streams[streamId] ??= {};
459459
topics.update(topic,
460460
ifAbsent: () => messageIds,
@@ -469,7 +469,7 @@ class Unreads extends ChangeNotifier {
469469
void _slowRemoveAllInStreams(Set<int> idsToRemove) {
470470
final newlyEmptyStreams = <int>[];
471471
for (final MapEntry(key: streamId, value: topics) in streams.entries) {
472-
final newlyEmptyTopics = <String>[];
472+
final newlyEmptyTopics = <TopicName>[];
473473
for (final MapEntry(key: topic, value: messageIds) in topics.entries) {
474474
messageIds.removeWhere((id) => idsToRemove.contains(id));
475475
if (messageIds.isEmpty) {
@@ -488,7 +488,7 @@ class Unreads extends ChangeNotifier {
488488
}
489489
}
490490

491-
void _removeAllInStreamTopic(Set<int> incomingMessageIds, int streamId, String topic) {
491+
void _removeAllInStreamTopic(Set<int> incomingMessageIds, int streamId, TopicName topic) {
492492
final topics = streams[streamId];
493493
if (topics == null) return;
494494
final messageIds = topics[topic];

lib/notifications/display.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:collection/collection.dart';
66
import 'package:flutter/foundation.dart';
77
import 'package:flutter/widgets.dart' hide Notification;
88

9+
import '../api/model/model.dart';
910
import '../api/notifications.dart';
1011
import '../generated/l10n/zulip_localizations.dart';
1112
import '../host/android_notifications.dart';
@@ -538,8 +539,8 @@ class NotificationOpenPayload {
538539
case 'topic':
539540
final channelIdStr = url.queryParameters['channel_id']!;
540541
final channelId = int.parse(channelIdStr, radix: 10);
541-
final topic = url.queryParameters['topic']!;
542-
narrow = TopicNarrow(channelId, topic);
542+
final topicStr = url.queryParameters['topic']!;
543+
narrow = TopicNarrow(channelId, TopicName(topicStr));
543544
case 'dm':
544545
final allRecipientIdsStr = url.queryParameters['all_recipient_ids']!;
545546
final allRecipientIds = allRecipientIdsStr.split(',')

lib/widgets/action_sheet.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class ActionSheetCancelButton extends StatelessWidget {
151151
/// Show a sheet of actions you can take on a topic.
152152
void showTopicActionSheet(BuildContext context, {
153153
required int channelId,
154-
required String topic,
154+
required TopicName topic,
155155
}) {
156156
final store = PerAccountStoreWidget.of(context);
157157
final subscription = store.subscriptions[channelId];

0 commit comments

Comments
 (0)