Skip to content

Commit 575f1c6

Browse files
PIG208gnprice
authored andcommitted
msglist [nfc]: Migrate most MessageListItem subclasses to use MessageBase
except MessageListMessageItem. This keeps changes minimal, leaving most of the helpers in lib/model/message_list.dart untouched, to avoid unnecessary generalization. This hoists streamId in StreamMessageRecipientHeader.build, where we used to access streamId via message instead from the onLongPress callback. Because Message.streamId only changes on message moves, we expect the build method to be called again, so this should be fine.
1 parent f136d8e commit 575f1c6

File tree

4 files changed

+39
-30
lines changed

4 files changed

+39
-30
lines changed

lib/model/message_list.dart

+4-3
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ sealed class MessageListItem {
2424
}
2525

2626
class MessageListRecipientHeaderItem extends MessageListItem {
27-
final Message message;
27+
final MessageBase message;
2828

2929
MessageListRecipientHeaderItem(this.message);
3030
}
3131

3232
class MessageListDateSeparatorItem extends MessageListItem {
33-
final Message message;
33+
final MessageBase message;
3434

3535
MessageListDateSeparatorItem(this.message);
3636
}
@@ -155,7 +155,8 @@ mixin _MessageSequence {
155155
}
156156
case MessageListRecipientHeaderItem(:var message):
157157
case MessageListDateSeparatorItem(:var message):
158-
return (message.id <= messageId) ? -1 : 1;
158+
if (message.id == null) return 1; // TODO(#1441): test
159+
return message.id! <= messageId ? -1 : 1;
159160
case MessageListMessageItem(:var message): return message.id.compareTo(messageId);
160161
}
161162
}

lib/model/narrow.dart

+6-4
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ class ChannelNarrow extends Narrow {
9494
class TopicNarrow extends Narrow implements SendableNarrow {
9595
const TopicNarrow(this.streamId, this.topic, {this.with_});
9696

97-
factory TopicNarrow.ofMessage(StreamMessage message) {
98-
return TopicNarrow(message.streamId, message.topic);
97+
factory TopicNarrow.ofMessage(MessageBase<StreamConversation> message) {
98+
return TopicNarrow(message.conversation.streamId, message.conversation.topic);
9999
}
100100

101101
final int streamId;
@@ -194,9 +194,11 @@ class DmNarrow extends Narrow implements SendableNarrow {
194194
);
195195
}
196196

197-
factory DmNarrow.ofMessage(DmMessage message, {required int selfUserId}) {
197+
factory DmNarrow.ofMessage(MessageBase<DmConversation> message, {
198+
required int selfUserId,
199+
}) {
198200
return DmNarrow(
199-
allRecipientIds: List.unmodifiable(message.allRecipientIds),
201+
allRecipientIds: List.unmodifiable(message.conversation.allRecipientIds),
200202
selfUserId: selfUserId,
201203
);
202204
}

lib/widgets/message_list.dart

+27-21
Original file line numberDiff line numberDiff line change
@@ -901,23 +901,27 @@ class _MarkAsReadAnimationState extends State<MarkAsReadAnimation> {
901901
class RecipientHeader extends StatelessWidget {
902902
const RecipientHeader({super.key, required this.message, required this.narrow});
903903

904-
final Message message;
904+
final MessageBase message;
905905
final Narrow narrow;
906906

907907
@override
908908
Widget build(BuildContext context) {
909909
final message = this.message;
910910
return switch (message) {
911-
StreamMessage() => StreamMessageRecipientHeader(message: message, narrow: narrow),
912-
DmMessage() => DmRecipientHeader(message: message, narrow: narrow),
911+
MessageBase<StreamConversation>() =>
912+
StreamMessageRecipientHeader(message: message, narrow: narrow),
913+
MessageBase<DmConversation>() =>
914+
DmRecipientHeader(message: message, narrow: narrow),
915+
MessageBase<Conversation>() =>
916+
throw StateError('Bad concrete subclass of MessageBase'),
913917
};
914918
}
915919
}
916920

917921
class DateSeparator extends StatelessWidget {
918922
const DateSeparator({super.key, required this.message});
919923

920-
final Message message;
924+
final MessageBase message;
921925

922926
@override
923927
Widget build(BuildContext context) {
@@ -1027,7 +1031,7 @@ class StreamMessageRecipientHeader extends StatelessWidget {
10271031
required this.narrow,
10281032
});
10291033

1030-
final StreamMessage message;
1034+
final MessageBase<StreamConversation> message;
10311035
final Narrow narrow;
10321036

10331037
static bool _containsDifferentChannels(Narrow narrow) {
@@ -1053,11 +1057,12 @@ class StreamMessageRecipientHeader extends StatelessWidget {
10531057
final designVariables = DesignVariables.of(context);
10541058
final zulipLocalizations = ZulipLocalizations.of(context);
10551059

1056-
final topic = message.topic;
1060+
final streamId = message.conversation.streamId;
1061+
final topic = message.conversation.topic;
10571062

10581063
final messageListTheme = MessageListTheme.of(context);
10591064

1060-
final subscription = store.subscriptions[message.streamId];
1065+
final subscription = store.subscriptions[streamId];
10611066
final Color backgroundColor;
10621067
final Color iconColor;
10631068
if (subscription != null) {
@@ -1073,16 +1078,16 @@ class StreamMessageRecipientHeader extends StatelessWidget {
10731078
if (!_containsDifferentChannels(narrow)) {
10741079
streamWidget = const SizedBox(width: 16);
10751080
} else {
1076-
final stream = store.streams[message.streamId];
1081+
final stream = store.streams[streamId];
10771082
final streamName = stream?.name
1078-
?? message.displayRecipient
1083+
?? message.conversation.displayRecipient
10791084
?? zulipLocalizations.unknownChannelName; // TODO(log)
10801085

10811086
streamWidget = GestureDetector(
10821087
onTap: () => Navigator.push(context,
10831088
MessageListPage.buildRoute(context: context,
1084-
narrow: ChannelNarrow(message.streamId))),
1085-
onLongPress: () => showChannelActionSheet(context, channelId: message.streamId),
1089+
narrow: ChannelNarrow(streamId))),
1090+
onLongPress: () => showChannelActionSheet(context, channelId: streamId),
10861091
child: Row(
10871092
crossAxisAlignment: CrossAxisAlignment.center,
10881093
children: [
@@ -1130,7 +1135,7 @@ class StreamMessageRecipientHeader extends StatelessWidget {
11301135
Icon(size: 14, color: designVariables.title.withFadedAlpha(0.5),
11311136
// A null [Icon.icon] makes a blank space.
11321137
iconDataForTopicVisibilityPolicy(
1133-
store.topicVisibilityPolicy(message.streamId, topic))),
1138+
store.topicVisibilityPolicy(streamId, topic))),
11341139
]));
11351140

11361141
return GestureDetector(
@@ -1143,7 +1148,7 @@ class StreamMessageRecipientHeader extends StatelessWidget {
11431148
MessageListPage.buildRoute(context: context,
11441149
narrow: TopicNarrow.ofMessage(message))),
11451150
onLongPress: () => showTopicActionSheet(context,
1146-
channelId: message.streamId,
1151+
channelId: streamId,
11471152
topic: topic,
11481153
someMessageIdInTopic: message.id),
11491154
child: ColoredBox(
@@ -1168,20 +1173,21 @@ class DmRecipientHeader extends StatelessWidget {
11681173
required this.narrow,
11691174
});
11701175

1171-
final DmMessage message;
1176+
final MessageBase<DmConversation> message;
11721177
final Narrow narrow;
11731178

11741179
@override
11751180
Widget build(BuildContext context) {
11761181
final zulipLocalizations = ZulipLocalizations.of(context);
11771182
final store = PerAccountStoreWidget.of(context);
11781183
final String title;
1179-
if (message.allRecipientIds.length > 1) {
1180-
title = zulipLocalizations.messageListGroupYouAndOthers(message.allRecipientIds
1181-
.where((id) => id != store.selfUserId)
1182-
.map(store.userDisplayName)
1183-
.sorted()
1184-
.join(", "));
1184+
if (message.conversation.allRecipientIds.length > 1) {
1185+
title = zulipLocalizations.messageListGroupYouAndOthers(
1186+
message.conversation.allRecipientIds
1187+
.where((id) => id != store.selfUserId)
1188+
.map(store.userDisplayName)
1189+
.sorted()
1190+
.join(", "));
11851191
} else {
11861192
title = zulipLocalizations.messageListGroupYouWithYourself;
11871193
}
@@ -1233,7 +1239,7 @@ TextStyle recipientHeaderTextStyle(BuildContext context, {FontStyle? fontStyle})
12331239
class RecipientHeaderDate extends StatelessWidget {
12341240
const RecipientHeaderDate({super.key, required this.message});
12351241

1236-
final Message message;
1242+
final MessageBase message;
12371243

12381244
@override
12391245
Widget build(BuildContext context) {

test/model/message_list_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -1994,11 +1994,11 @@ void checkInvariants(MessageListView model) {
19941994
}
19951995

19961996
extension MessageListRecipientHeaderItemChecks on Subject<MessageListRecipientHeaderItem> {
1997-
Subject<Message> get message => has((x) => x.message, 'message');
1997+
Subject<MessageBase> get message => has((x) => x.message, 'message');
19981998
}
19991999

20002000
extension MessageListDateSeparatorItemChecks on Subject<MessageListDateSeparatorItem> {
2001-
Subject<Message> get message => has((x) => x.message, 'message');
2001+
Subject<MessageBase> get message => has((x) => x.message, 'message');
20022002
}
20032003

20042004
extension MessageListMessageItemChecks on Subject<MessageListMessageItem> {

0 commit comments

Comments
 (0)