Skip to content

Commit 854bdc9

Browse files
committed
event: Handle submessage event for polls.
We could potentially avoid notifying listeners in some cases when handling submessage event, but it wouldn't be critically necessary. Signed-off-by: Zixuan James Li <[email protected]>
1 parent 2eba1fb commit 854bdc9

11 files changed

+280
-10
lines changed

lib/api/model/events.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:json_annotation/json_annotation.dart';
22

33
import 'json.dart';
44
import 'model.dart';
5+
import 'submessage.dart';
56

67
part 'events.g.dart';
78

@@ -62,6 +63,7 @@ sealed class Event {
6263
case 'remove': return UpdateMessageFlagsRemoveEvent.fromJson(json);
6364
default: return UnexpectedEvent.fromJson(json);
6465
}
66+
case 'submessage': return SubmessageEvent.fromJson(json);
6567
case 'typing': return TypingEvent.fromJson(json);
6668
case 'reaction': return ReactionEvent.fromJson(json);
6769
case 'heartbeat': return HeartbeatEvent.fromJson(json);
@@ -873,6 +875,38 @@ class UpdateMessageFlagsMessageDetail {
873875
Map<String, dynamic> toJson() => _$UpdateMessageFlagsMessageDetailToJson(this);
874876
}
875877

878+
/// A Zulip event of type `submessage`: https://zulip.com/api/get-events#submessage
879+
@JsonSerializable(fieldRename: FieldRename.snake)
880+
class SubmessageEvent extends Event {
881+
@override
882+
@JsonKey(includeToJson: true)
883+
String get type => 'submessage';
884+
885+
@JsonKey(unknownEnumValue: SubmessageType.unknown)
886+
final SubmessageType msgType;
887+
/// [SubmessageData] encoded in JSON.
888+
@JsonKey(readValue: Submessage.readContent, toJson: Submessage.contentToJson)
889+
final Object? content;
890+
final int messageId;
891+
final int senderId;
892+
final int submessageId;
893+
894+
SubmessageEvent({
895+
required super.id,
896+
required this.msgType,
897+
required this.content,
898+
required this.messageId,
899+
required this.senderId,
900+
required this.submessageId,
901+
});
902+
903+
factory SubmessageEvent.fromJson(Map<String, dynamic> json) =>
904+
_$SubmessageEventFromJson(json);
905+
906+
@override
907+
Map<String, dynamic> toJson() => _$SubmessageEventToJson(this);
908+
}
909+
876910
/// A Zulip event of type `typing`:
877911
/// https://zulip.com/api/get-events#typing-start
878912
/// https://zulip.com/api/get-events#typing-stop

lib/api/model/events.g.dart

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/api/model/model.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ sealed class Message {
554554
}
555555

556556
static Object? _pollToJson(Poll? poll) {
557-
return null;
557+
return poll?.submessages ?? [];
558558
}
559559

560560
Message({

lib/api/model/model.g.dart

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/api/model/submessage.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ class Submessage {
2222
@JsonKey(unknownEnumValue: SubmessageType.unknown)
2323
final SubmessageType msgType;
2424
/// [SubmessageData] encoded in JSON.
25-
@JsonKey(readValue: _readContent, toJson: _contentToJson)
25+
@JsonKey(readValue: readContent, toJson: contentToJson)
2626
final Object? content;
2727
final int messageId;
2828
final int senderId;
2929
final int id;
3030

31-
static Object? _readContent(Map<Object?, Object?> json, String key) {
31+
static Object? readContent(Map<Object?, Object?> json, String key) {
3232
try {
3333
return (const JsonDecoder().convert(json[key] as String)) as Object?;
3434
} catch (e) {
@@ -39,7 +39,7 @@ class Submessage {
3939
}
4040
}
4141

42-
static Object? _contentToJson(Object? content) =>
42+
static Object? contentToJson(Object? content) =>
4343
const JsonEncoder().convert(content);
4444

4545
factory Submessage.fromJson(Map<String, Object?> json) =>

lib/api/model/submessage.g.dart

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/api/model/widget.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'submessage.dart';
66
/// - https://zulip.com/help/create-a-poll
77
class Poll {
88
Poll({
9+
required this.submessages,
910
required this.senderId,
1011
required this.question,
1112
required final List<String> options,
@@ -23,6 +24,7 @@ class Poll {
2324
final widgetEventSubmessages = submessages.sublist(1);
2425

2526
final poll = Poll(
27+
submessages: submessages,
2628
senderId: senderId,
2729
question: widgetData.extraData.question,
2830
options: widgetData.extraData.options,
@@ -35,6 +37,8 @@ class Poll {
3537
return poll;
3638
}
3739

40+
/// See [Message._pollToJson].
41+
final List<Submessage> submessages;
3842
final int senderId;
3943
String question;
4044

lib/model/message.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import '../api/model/events.dart';
22
import '../api/model/model.dart';
3+
import '../api/model/submessage.dart';
34
import '../log.dart';
45
import 'message_list.dart';
56

@@ -267,4 +268,17 @@ class MessageStoreImpl with MessageStore {
267268
view.notifyListenersIfMessagePresent(event.messageId);
268269
}
269270
}
271+
272+
void handleSubmessageEvent(SubmessageEvent event) {
273+
final poll = messages[event.messageId]?.poll;
274+
if (poll == null) return;
275+
poll.applyEvent(
276+
event.senderId,
277+
PollEvent.fromJson(event.content as Map<String, Object?>)
278+
);
279+
280+
for (final view in _messageListViews) {
281+
view.notifyListenersIfMessagePresent(event.messageId);
282+
}
283+
}
270284
}

lib/model/store.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,10 @@ class PerAccountStore extends ChangeNotifier with ChannelStore, MessageStore {
521521
_messages.handleUpdateMessageFlagsEvent(event);
522522
unreads.handleUpdateMessageFlagsEvent(event);
523523

524+
case SubmessageEvent():
525+
assert(debugLog("server event: submessage ${event.content}"));
526+
_messages.handleSubmessageEvent(event);
527+
524528
case TypingEvent():
525529
assert(debugLog("server event: typing/${event.op} ${event.messageType}"));
526530
typingStatus.handleTypingEvent(event);

test/example_data.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,21 @@ ReactionEvent reactionEvent(Reaction reaction, ReactionOp op, int messageId) {
580580
);
581581
}
582582

583+
SubmessageEvent submessageEvent(
584+
int messageId,
585+
int senderId,
586+
{required Object? content}
587+
) {
588+
return SubmessageEvent(
589+
id: 1,
590+
msgType: SubmessageType.widget,
591+
content: deepToJson(content),
592+
messageId: messageId,
593+
senderId: senderId,
594+
submessageId: 1,
595+
);
596+
}
597+
583598
////////////////////////////////////////////////////////////////
584599
// The entire per-account or global state.
585600
//

0 commit comments

Comments
 (0)