From 882aa64ecb74c8d8391f10db8d358cd0860dfe62 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 4 Jul 2023 11:53:45 -0700 Subject: [PATCH 1/2] api: Add update_message events --- lib/api/model/events.dart | 63 +++++++++++++++++++++++++++++++++++++ lib/api/model/events.g.dart | 52 ++++++++++++++++++++++++++++++ lib/model/store.dart | 3 ++ 3 files changed, 118 insertions(+) diff --git a/lib/api/model/events.dart b/lib/api/model/events.dart index f30047c335..bbec5c3c2c 100644 --- a/lib/api/model/events.dart +++ b/lib/api/model/events.dart @@ -31,6 +31,7 @@ sealed class Event { default: return UnexpectedEvent.fromJson(json); } case 'message': return MessageEvent.fromJson(json); + case 'update_message': return UpdateMessageEvent.fromJson(json); case 'heartbeat': return HeartbeatEvent.fromJson(json); // TODO add many more event types default: return UnexpectedEvent.fromJson(json); @@ -265,6 +266,68 @@ 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; +} + @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..2f7434bcd0 100644 --- a/lib/api/model/events.g.dart +++ b/lib/api/model/events.g.dart @@ -133,6 +133,58 @@ 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', +}; + HeartbeatEvent _$HeartbeatEventFromJson(Map json) => HeartbeatEvent( id: json['id'] as int, diff --git a/lib/model/store.dart b/lib/model/store.dart index d6d335f80b..de57db37d5 100644 --- a/lib/model/store.dart +++ b/lib/model/store.dart @@ -270,6 +270,9 @@ 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 UnexpectedEvent) { assert(debugLog("server event: ${jsonEncode(event.toJson())}")); // TODO log better } else { From 9b92676c7faad26e51e53796e652934c7b54b6c3 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 5 Jul 2023 11:33:45 -0700 Subject: [PATCH 2/2] api: Add delete_message events --- lib/api/model/events.dart | 35 +++++++++++++++++++++++++++++++++++ lib/api/model/events.g.dart | 24 ++++++++++++++++++++++++ lib/model/store.dart | 3 +++ 3 files changed, 62 insertions(+) diff --git a/lib/api/model/events.dart b/lib/api/model/events.dart index bbec5c3c2c..d49d2418a3 100644 --- a/lib/api/model/events.dart +++ b/lib/api/model/events.dart @@ -32,6 +32,7 @@ sealed class Event { } 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); @@ -328,6 +329,40 @@ enum PropagateMode { 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 2f7434bcd0..68aa0c4c7a 100644 --- a/lib/api/model/events.g.dart +++ b/lib/api/model/events.g.dart @@ -185,6 +185,30 @@ const _$PropagateModeEnumMap = { 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 de57db37d5..d9de720020 100644 --- a/lib/model/store.dart +++ b/lib/model/store.dart @@ -273,6 +273,9 @@ class PerAccountStore extends ChangeNotifier { } 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 {