@@ -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
@@ -734,8 +735,9 @@ class DeleteMessageEvent extends Event {
734
735
Map <String , dynamic > toJson () => _$DeleteMessageEventToJson (this );
735
736
}
736
737
737
- /// As in [DeleteMessageEvent.messageType]
738
- /// or [UpdateMessageFlagsMessageDetail.type] .
738
+ /// As in [DeleteMessageEvent.messageType] ,
739
+ /// [UpdateMessageFlagsMessageDetail.type]
740
+ /// or [TypingEvent.messageType]
739
741
@JsonEnum (alwaysCreate: true )
740
742
enum MessageType {
741
743
stream,
@@ -867,6 +869,69 @@ class UpdateMessageFlagsMessageDetail {
867
869
Map <String , dynamic > toJson () => _$UpdateMessageFlagsMessageDetailToJson (this );
868
870
}
869
871
872
+ /// A Zulip event of type `typing` :
873
+ /// https://zulip.com/api/get-events#typing-start
874
+ /// https://zulip.com/api/get-events#typing-stop
875
+ @JsonSerializable (fieldRename: FieldRename .snake)
876
+ class TypingEvent extends Event {
877
+ @override
878
+ @JsonKey (includeToJson: true )
879
+ String get type => 'typing' ;
880
+
881
+ final TypingOp op;
882
+ @MessageTypeConverter ()
883
+ final MessageType messageType;
884
+ @JsonKey (readValue: _readSenderId)
885
+ final int senderId;
886
+ @JsonKey (name: 'recipients' , fromJson: _recipientIdsFromJson)
887
+ final List <int >? recipientIds;
888
+ final int ? streamId;
889
+ final String ? topic;
890
+
891
+ TypingEvent ({
892
+ required super .id,
893
+ required this .op,
894
+ required this .messageType,
895
+ required this .senderId,
896
+ required this .recipientIds,
897
+ required this .streamId,
898
+ required this .topic,
899
+ });
900
+
901
+ static Object ? _readSenderId (Map <Object ?, Object ?> json, String key) {
902
+ return (json['sender' ] as Map <String , dynamic >)['user_id' ];
903
+ }
904
+
905
+ static List <int >? _recipientIdsFromJson (Object ? json) {
906
+ if (json == null ) return null ;
907
+ return (json as List <Object ?>).map (
908
+ (item) => (item as Map <String , Object ?>)['user_id' ] as int ).toList ();
909
+ }
910
+
911
+ factory TypingEvent .fromJson (Map <String , dynamic > json) {
912
+ final result = _$TypingEventFromJson (json);
913
+ // Crunchy-shell validation
914
+ switch (result.messageType) {
915
+ case MessageType .stream:
916
+ result.streamId as int ;
917
+ result.topic as String ;
918
+ case MessageType .direct:
919
+ result.recipientIds as List <int >;
920
+ }
921
+ return result;
922
+ }
923
+
924
+ @override
925
+ Map <String , dynamic > toJson () => _$TypingEventToJson (this );
926
+ }
927
+
928
+ /// As in [TypingEvent.op] .
929
+ @JsonEnum (fieldRename: FieldRename .snake)
930
+ enum TypingOp {
931
+ start,
932
+ stop
933
+ }
934
+
870
935
/// A Zulip event of type `reaction` , with op `add` or `remove` .
871
936
///
872
937
/// See:
0 commit comments