@@ -62,6 +62,7 @@ sealed class Event {
62
62
case 'remove' : return UpdateMessageFlagsRemoveEvent .fromJson (json);
63
63
default : return UnexpectedEvent .fromJson (json);
64
64
}
65
+ case 'typing' : return TypingEvent .fromJson (json);
65
66
case 'reaction' : return ReactionEvent .fromJson (json);
66
67
case 'heartbeat' : return HeartbeatEvent .fromJson (json);
67
68
// TODO add many more event types
@@ -733,8 +734,9 @@ class DeleteMessageEvent extends Event {
733
734
Map <String , dynamic > toJson () => _$DeleteMessageEventToJson (this );
734
735
}
735
736
736
- /// As in [DeleteMessageEvent.messageType]
737
- /// or [UpdateMessageFlagsMessageDetail.type] .
737
+ /// As in [DeleteMessageEvent.messageType] ,
738
+ /// [UpdateMessageFlagsMessageDetail.type]
739
+ /// or [TypingEvent.messageType]
738
740
@JsonEnum (fieldRename: FieldRename .snake)
739
741
enum MessageType {
740
742
stream,
@@ -850,6 +852,68 @@ class UpdateMessageFlagsMessageDetail {
850
852
Map <String , dynamic > toJson () => _$UpdateMessageFlagsMessageDetailToJson (this );
851
853
}
852
854
855
+
856
+ /// A Zulip event of type `typing` :
857
+ /// https://zulip.com/api/get-events#typing-start
858
+ /// https://zulip.com/api/get-events#typing-stop
859
+ @JsonSerializable (fieldRename: FieldRename .snake)
860
+ class TypingEvent extends Event {
861
+ @override
862
+ @JsonKey (includeToJson: true )
863
+ String get type => 'typing' ;
864
+
865
+ final TypingOp op;
866
+ final MessageType messageType;
867
+ @JsonKey (name: 'sender' , readValue: _readSenderId)
868
+ final int senderId;
869
+ @JsonKey (name: 'recipients' , fromJson: _recipientIdsFromJson)
870
+ final List <int >? recipientIds;
871
+ final int ? streamId;
872
+ final String ? topic;
873
+
874
+ TypingEvent ({
875
+ required super .id,
876
+ required this .op,
877
+ required this .messageType,
878
+ required this .senderId,
879
+ required this .recipientIds,
880
+ required this .streamId,
881
+ required this .topic,
882
+ });
883
+
884
+ static dynamic _readSenderId (Map <dynamic , dynamic > json, String key) {
885
+ return json[key]['user_id' ];
886
+ }
887
+
888
+ static List <int >? _recipientIdsFromJson (dynamic json) {
889
+ if (json == null ) return null ;
890
+ return (json as List <dynamic >).map ((item) => item['user_id' ] as int ).toList ();
891
+ }
892
+
893
+ factory TypingEvent .fromJson (Map <String , dynamic > json) {
894
+ final result = _$TypingEventFromJson (json);
895
+ // Crunchy-shell validation
896
+ switch (result.messageType) {
897
+ case MessageType .stream:
898
+ result.streamId as int ;
899
+ result.topic as String ;
900
+ case MessageType .private:
901
+ result.recipientIds as List <int >;
902
+ }
903
+ return result;
904
+ }
905
+
906
+ @override
907
+ Map <String , dynamic > toJson () => _$TypingEventToJson (this );
908
+ }
909
+
910
+ /// As in [TypingEvent.op] .
911
+ @JsonEnum (fieldRename: FieldRename .snake)
912
+ enum TypingOp {
913
+ start,
914
+ stop
915
+ }
916
+
853
917
/// A Zulip event of type `reaction` , with op `add` or `remove` .
854
918
///
855
919
/// See:
0 commit comments