1
1
import 'package:json_annotation/json_annotation.dart' ;
2
2
3
+ import '../../model/algorithms.dart' ;
3
4
import 'events.dart' ;
4
5
import 'initial_snapshot.dart' ;
5
6
import 'reaction.dart' ;
@@ -531,6 +532,52 @@ String? tryParseEmojiCodeToUnicode(String emojiCode) {
531
532
}
532
533
}
533
534
535
+ /// As in [StreamMessage.conversation] and [DmMessage.conversation] .
536
+ ///
537
+ /// Different from [MessageDestination] , this information comes from
538
+ /// [getMessages] or [getEvents] , identifying the conversation that contains a
539
+ /// message.
540
+ sealed class Conversation {}
541
+
542
+ /// The conversation a stream message is in.
543
+ @JsonSerializable (fieldRename: FieldRename .snake, createToJson: false )
544
+ class StreamConversation extends Conversation {
545
+ int streamId;
546
+
547
+ @JsonKey (name: 'subject' )
548
+ TopicName topic;
549
+
550
+ /// The name of the channel with ID [streamId] when the message was sent.
551
+ ///
552
+ /// The primary reference for the name of the channel is
553
+ /// the client's data structures about channels, at [streamId] .
554
+ /// This value may be used as a fallback when the channel is unknown.
555
+ ///
556
+ /// This is non-null when found in a [StreamMessage] object in the API,
557
+ /// but may become null in the client's data structures,
558
+ /// e.g. if the message gets moved between channels.
559
+ @JsonKey (required : true , disallowNullValue: true )
560
+ String ? displayRecipient;
561
+
562
+ StreamConversation (this .streamId, this .topic, {required this .displayRecipient});
563
+
564
+ factory StreamConversation .fromJson (Map <String , dynamic > json) =>
565
+ _$StreamConversationFromJson (json);
566
+ }
567
+
568
+ /// The conversation a DM message is in.
569
+ class DmConversation extends Conversation {
570
+ /// The user IDs of all users in the conversation, sorted numerically.
571
+ ///
572
+ /// This lists the sender as well as all (other) recipients, and it
573
+ /// lists each user just once. In particular the self-user is always
574
+ /// included.
575
+ final List <int > allRecipientIds;
576
+
577
+ DmConversation ({required this .allRecipientIds})
578
+ : assert (isSortedWithoutDuplicates (allRecipientIds.toList ()));
579
+ }
580
+
534
581
/// As in the get-messages response.
535
582
///
536
583
/// https://zulip.com/api/get-messages#response
@@ -720,20 +767,25 @@ class StreamMessage extends Message {
720
767
@JsonKey (includeToJson: true )
721
768
String get type => 'stream' ;
722
769
723
- // This is not nullable API-wise, but if the message moves across channels,
724
- // [displayRecipient] still refers to the original channel and it has to be
725
- // invalidated.
726
- @JsonKey (required : true , disallowNullValue: true )
727
- String ? displayRecipient;
728
-
729
- int streamId;
770
+ @JsonKey (includeToJson: true )
771
+ int get streamId => conversation.streamId;
730
772
731
773
// The topic/subject is documented to be present on DMs too, just empty.
732
774
// We ignore it on DMs; if a future server introduces distinct topics in DMs,
733
775
// that will need new UI that we'll design then as part of that feature,
734
776
// and ignoring the topics seems as good a fallback behavior as any.
735
- @JsonKey (name: 'subject' )
736
- TopicName topic;
777
+ @JsonKey (name: 'subject' , includeToJson: true )
778
+ TopicName get topic => conversation.topic;
779
+
780
+ @JsonKey (includeToJson: true )
781
+ String ? get displayRecipient => conversation.displayRecipient;
782
+
783
+ @JsonKey (readValue: _readConversation, includeToJson: false )
784
+ StreamConversation conversation;
785
+
786
+ static Map <String , dynamic > _readConversation (Map <dynamic , dynamic > json, String key) {
787
+ return json as Map <String , dynamic >;
788
+ }
737
789
738
790
StreamMessage ({
739
791
required super .client,
@@ -753,9 +805,7 @@ class StreamMessage extends Message {
753
805
required super .flags,
754
806
required super .matchContent,
755
807
required super .matchTopic,
756
- required this .displayRecipient,
757
- required this .streamId,
758
- required this .topic,
808
+ required this .conversation,
759
809
});
760
810
761
811
factory StreamMessage .fromJson (Map <String , dynamic > json) =>
@@ -781,20 +831,23 @@ class DmMessage extends Message {
781
831
/// included.
782
832
// TODO(server): Document that it's all users. That statement is based on
783
833
// reverse-engineering notes in zulip-mobile:src/api/modelTypes.js at PmMessage.
784
- @JsonKey (name: 'display_recipient' , fromJson : _allRecipientIdsFromJson, toJson : _allRecipientIdsToJson )
785
- final List <int > allRecipientIds;
834
+ @JsonKey (name: 'display_recipient' , toJson : _allRecipientIdsToJson, includeToJson : true )
835
+ List <int > get allRecipientIds => conversation. allRecipientIds;
786
836
787
- static List <int > _allRecipientIdsFromJson (Object ? json) {
788
- return (json as List <dynamic >).map (
789
- (element) => ((element as Map <String , dynamic >)['id' ] as num ).toInt ()
790
- ).toList (growable: false )
791
- ..sort ();
792
- }
837
+ @JsonKey (name: 'display_recipient' , fromJson: _conversationFromJson, includeToJson: false )
838
+ final DmConversation conversation;
793
839
794
840
static List <Map <String , dynamic >> _allRecipientIdsToJson (List <int > allRecipientIds) {
795
841
return allRecipientIds.map ((element) => {'id' : element}).toList ();
796
842
}
797
843
844
+ static DmConversation _conversationFromJson (List <dynamic > json) {
845
+ return DmConversation (allRecipientIds: json.map (
846
+ (element) => ((element as Map <String , dynamic >)['id' ] as num ).toInt ()
847
+ ).toList (growable: false )
848
+ ..sort ());
849
+ }
850
+
798
851
DmMessage ({
799
852
required super .client,
800
853
required super .content,
@@ -813,7 +866,7 @@ class DmMessage extends Message {
813
866
required super .flags,
814
867
required super .matchContent,
815
868
required super .matchTopic,
816
- required this .allRecipientIds ,
869
+ required this .conversation ,
817
870
});
818
871
819
872
factory DmMessage .fromJson (Map <String , dynamic > json) =>
0 commit comments