@@ -40,7 +40,7 @@ sealed class Event {
4040 switch (json['op' ] as String ) {
4141 case 'create' : return ChannelCreateEvent .fromJson (json);
4242 case 'delete' : return ChannelDeleteEvent .fromJson (json);
43- // TODO(#182): case 'update': …
43+ case 'update' : return ChannelUpdateEvent . fromJson (json);
4444 default : return UnexpectedEvent .fromJson (json);
4545 }
4646 case 'subscription' :
@@ -379,8 +379,73 @@ class ChannelDeleteEvent extends ChannelEvent {
379379 Map <String , dynamic > toJson () => _$ChannelDeleteEventToJson (this );
380380}
381381
382- // TODO(#182) ChannelUpdateEvent, for a [ChannelEvent] with op `update`:
383- // https://zulip.com/api/get-events#stream-update
382+ /// A [ChannelEvent] with op `update` : https://zulip.com/api/get-events#stream-update
383+ @JsonSerializable (fieldRename: FieldRename .snake)
384+ class ChannelUpdateEvent extends ChannelEvent {
385+ @override
386+ String get op => 'update' ;
387+
388+ final int streamId;
389+ final String name;
390+
391+ /// The name of the channel property, or null if we don't recognize it.
392+ @JsonKey (unknownEnumValue: JsonKey .nullForUndefinedEnumValue)
393+ final ChannelPropertyName ? property;
394+
395+ /// The new value, or null if we don't recognize the property.
396+ ///
397+ /// This will have the type appropriate for [property] ; for example,
398+ /// if the property is boolean, then `value is bool` will always be true.
399+ /// This invariant is enforced by [ChannelUpdateEvent.fromJson] .
400+ @JsonKey (readValue: _readValue)
401+ final Object ? value;
402+
403+ final String ? renderedDescription;
404+ final bool ? historyPublicToSubscribers;
405+ final bool ? isWebPublic;
406+
407+ ChannelUpdateEvent ({
408+ required super .id,
409+ required this .streamId,
410+ required this .name,
411+ required this .property,
412+ required this .value,
413+ this .renderedDescription,
414+ this .historyPublicToSubscribers,
415+ this .isWebPublic,
416+ });
417+
418+ /// [value] , with a check that its type corresponds to [property]
419+ /// (e.g., `value as bool` ).
420+ static Object ? _readValue (Map <dynamic , dynamic > json, String key) {
421+ final value = json['value' ];
422+ switch (ChannelPropertyName .fromRawString (json['property' ] as String )) {
423+ case ChannelPropertyName .name:
424+ case ChannelPropertyName .description:
425+ return value as String ;
426+ case ChannelPropertyName .firstMessageId:
427+ return value as int ? ;
428+ case ChannelPropertyName .inviteOnly:
429+ return value as bool ;
430+ case ChannelPropertyName .messageRetentionDays:
431+ return value as int ? ;
432+ case ChannelPropertyName .channelPostPolicy:
433+ return ChannelPostPolicy .fromApiValue (value as int );
434+ case ChannelPropertyName .canRemoveSubscribersGroup:
435+ case ChannelPropertyName .canRemoveSubscribersGroupId:
436+ case ChannelPropertyName .streamWeeklyTraffic:
437+ return value as int ? ;
438+ case null :
439+ return null ;
440+ }
441+ }
442+
443+ factory ChannelUpdateEvent .fromJson (Map <String , dynamic > json) =>
444+ _$ChannelUpdateEventFromJson (json);
445+
446+ @override
447+ Map <String , dynamic > toJson () => _$ChannelUpdateEventToJson (this );
448+ }
384449
385450/// A Zulip event of type `subscription` .
386451///
0 commit comments