diff --git a/lib/api/model/events.dart b/lib/api/model/events.dart index f30047c335..d49d2418a3 100644 --- a/lib/api/model/events.dart +++ b/lib/api/model/events.dart @@ -31,6 +31,8 @@ sealed class Event { default: return UnexpectedEvent.fromJson(json); } case 'message': return MessageEvent.fromJson(json); + case 'update_message': return UpdateMessageEvent.fromJson(json); + case 'delete_message': return DeleteMessageEvent.fromJson(json); case 'heartbeat': return HeartbeatEvent.fromJson(json); // TODO add many more event types default: return UnexpectedEvent.fromJson(json); @@ -265,6 +267,102 @@ class MessageEvent extends Event { } } +/// A Zulip event of type `update_message`. +@JsonSerializable(fieldRename: FieldRename.snake) +class UpdateMessageEvent extends Event { + @override + String get type => 'update_message'; + + final int? userId; // TODO(server-5) + final bool? renderingOnly; // TODO(server-5) + final int messageId; + final List messageIds; + final List flags; // TODO enum + final int? editTimestamp; // TODO(server-5) + final String? streamName; + final int? streamId; + final int? newStreamId; + final PropagateMode? propagateMode; + final String? origSubject; + final String? subject; + // final List topicLinks; // TODO handle + final String? origContent; + final String? origRenderedContent; + // final int? prevRenderedContentVersion; // deprecated + final String? content; + final String? renderedContent; + final bool? isMeMessage; + + UpdateMessageEvent({ + required super.id, + this.userId, + this.renderingOnly, + required this.messageId, + required this.messageIds, + required this.flags, + this.editTimestamp, + this.streamName, + this.streamId, + this.newStreamId, + this.propagateMode, + this.origSubject, + this.subject, + this.origContent, + this.origRenderedContent, + this.content, + this.renderedContent, + this.isMeMessage, + }); + + factory UpdateMessageEvent.fromJson(Map json) => + _$UpdateMessageEventFromJson(json); + + @override + Map toJson() => _$UpdateMessageEventToJson(this); +} + +/// As in [UpdateMessageEvent.propagateMode]. +@JsonEnum(fieldRename: FieldRename.snake) +enum PropagateMode { + changeOne, + changeLater, + changeAll; +} + +/// A Zulip event of type `delete_message`. +@JsonSerializable(fieldRename: FieldRename.snake) +class DeleteMessageEvent extends Event { + @override + String get type => 'delete_message'; + + final List messageIds; + // final int messageId; // Not present; we support the bulk_message_deletion capability + final MessageType messageType; + final int? streamId; + final String? topic; + + DeleteMessageEvent({ + required super.id, + required this.messageIds, + required this.messageType, + this.streamId, + this.topic, + }); + + factory DeleteMessageEvent.fromJson(Map json) => + _$DeleteMessageEventFromJson(json); + + @override + Map toJson() => _$DeleteMessageEventToJson(this); +} + +/// As in [DeleteMessageEvent.messageType]. +@JsonEnum(fieldRename: FieldRename.snake) +enum MessageType { + stream, + private; +} + @JsonSerializable(fieldRename: FieldRename.snake) class HeartbeatEvent extends Event { @override diff --git a/lib/api/model/events.g.dart b/lib/api/model/events.g.dart index 20d3d6d1eb..68aa0c4c7a 100644 --- a/lib/api/model/events.g.dart +++ b/lib/api/model/events.g.dart @@ -133,6 +133,82 @@ Map _$StreamDeleteEventToJson(StreamDeleteEvent instance) => 'streams': instance.streams, }; +UpdateMessageEvent _$UpdateMessageEventFromJson(Map json) => + UpdateMessageEvent( + id: json['id'] as int, + userId: json['user_id'] as int?, + renderingOnly: json['rendering_only'] as bool?, + messageId: json['message_id'] as int, + messageIds: + (json['message_ids'] as List).map((e) => e as int).toList(), + flags: (json['flags'] as List).map((e) => e as String).toList(), + editTimestamp: json['edit_timestamp'] as int?, + streamName: json['stream_name'] as String?, + streamId: json['stream_id'] as int?, + newStreamId: json['new_stream_id'] as int?, + propagateMode: + $enumDecodeNullable(_$PropagateModeEnumMap, json['propagate_mode']), + origSubject: json['orig_subject'] as String?, + subject: json['subject'] as String?, + origContent: json['orig_content'] as String?, + origRenderedContent: json['orig_rendered_content'] as String?, + content: json['content'] as String?, + renderedContent: json['rendered_content'] as String?, + isMeMessage: json['is_me_message'] as bool?, + ); + +Map _$UpdateMessageEventToJson(UpdateMessageEvent instance) => + { + 'id': instance.id, + 'user_id': instance.userId, + 'rendering_only': instance.renderingOnly, + 'message_id': instance.messageId, + 'message_ids': instance.messageIds, + 'flags': instance.flags, + 'edit_timestamp': instance.editTimestamp, + 'stream_name': instance.streamName, + 'stream_id': instance.streamId, + 'new_stream_id': instance.newStreamId, + 'propagate_mode': _$PropagateModeEnumMap[instance.propagateMode], + 'orig_subject': instance.origSubject, + 'subject': instance.subject, + 'orig_content': instance.origContent, + 'orig_rendered_content': instance.origRenderedContent, + 'content': instance.content, + 'rendered_content': instance.renderedContent, + 'is_me_message': instance.isMeMessage, + }; + +const _$PropagateModeEnumMap = { + PropagateMode.changeOne: 'change_one', + PropagateMode.changeLater: 'change_later', + PropagateMode.changeAll: 'change_all', +}; + +DeleteMessageEvent _$DeleteMessageEventFromJson(Map json) => + DeleteMessageEvent( + id: json['id'] as int, + messageIds: + (json['message_ids'] as List).map((e) => e as int).toList(), + messageType: $enumDecode(_$MessageTypeEnumMap, json['message_type']), + streamId: json['stream_id'] as int?, + topic: json['topic'] as String?, + ); + +Map _$DeleteMessageEventToJson(DeleteMessageEvent instance) => + { + 'id': instance.id, + 'message_ids': instance.messageIds, + 'message_type': _$MessageTypeEnumMap[instance.messageType]!, + 'stream_id': instance.streamId, + 'topic': instance.topic, + }; + +const _$MessageTypeEnumMap = { + MessageType.stream: 'stream', + MessageType.private: 'private', +}; + HeartbeatEvent _$HeartbeatEventFromJson(Map json) => HeartbeatEvent( id: json['id'] as int, diff --git a/lib/model/store.dart b/lib/model/store.dart index d6d335f80b..d9de720020 100644 --- a/lib/model/store.dart +++ b/lib/model/store.dart @@ -270,6 +270,12 @@ class PerAccountStore extends ChangeNotifier { for (final view in _messageListViews) { view.maybeAddMessage(event.message); } + } else if (event is UpdateMessageEvent) { + assert(debugLog("server event: update_message ${event.messageId}")); + // TODO handle + } else if (event is DeleteMessageEvent) { + assert(debugLog("server event: delete_message ${event.messageIds}")); + // TODO handle } else if (event is UnexpectedEvent) { assert(debugLog("server event: ${jsonEncode(event.toJson())}")); // TODO log better } else {