hardened API decoding against server fields the models did not expect
The Talk room list crashed for a new account because the server omits
lastMessage for rooms without a visible message and the model required it.
Beyond that single field, a review of the Talk models against the OpenAPI
spec of the installed version (23.0.8) found the same crash class in several
places: closed enums over open server values (inCall bitmask, rich-object
types, actor and message types), a deleted parent sent as {id, deleted},
and the autocomplete status arriving as an object.
- json_serializable `checked: true`: decode errors now name class and field
- lists (rooms, messages, participants, autocomplete) decode per entry;
a malformed entry is skipped and reported via ClientErrorReporter
- unknownEnumValue fallbacks for all response enums of Talk and breakers
- lastMessage nullable; inCall as bitmask; deleted parent placeholder;
autocomplete status object/string; fixed shareWithDisplayNameUnique key
- GetRoomParams no longer sends null query parameters
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrepDTL4qDe35TuS29sLW3
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../api_response.dart';
|
||||
import '../../../json_lenient.dart';
|
||||
import '../chat/get_chat_response.dart';
|
||||
|
||||
part 'get_room_response.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomResponse extends ApiResponse {
|
||||
@JsonKey(fromJson: _roomsFromJson)
|
||||
Set<GetRoomResponseObject> data;
|
||||
|
||||
GetRoomResponse(this.data);
|
||||
@@ -33,10 +35,14 @@ class GetRoomResponse extends ApiResponse {
|
||||
}
|
||||
}
|
||||
|
||||
Set<GetRoomResponseObject> _roomsFromJson(Object? raw) =>
|
||||
decodeSetLenient(raw, GetRoomResponseObject.fromJson, what: 'room');
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomResponseObject {
|
||||
int id;
|
||||
String token;
|
||||
@JsonKey(unknownEnumValue: GetRoomResponseObjectConversationType.unknown)
|
||||
GetRoomResponseObjectConversationType type;
|
||||
String name;
|
||||
String displayName;
|
||||
@@ -55,13 +61,20 @@ class GetRoomResponseObject {
|
||||
bool canLeaveConversation;
|
||||
int lastActivity;
|
||||
bool isFavorite;
|
||||
@JsonKey(
|
||||
unknownEnumValue:
|
||||
GetRoomResponseObjectParticipantNotificationLevel.defaultLevel,
|
||||
)
|
||||
GetRoomResponseObjectParticipantNotificationLevel notificationLevel;
|
||||
int unreadMessages;
|
||||
bool unreadMention;
|
||||
bool unreadMentionDirect;
|
||||
int lastReadMessage;
|
||||
int lastCommonReadMessage;
|
||||
GetChatResponseObject lastMessage;
|
||||
|
||||
/// Omitted by the server for rooms without a visible message (empty room,
|
||||
/// last message expired or hidden from this user, federated conversation).
|
||||
GetChatResponseObject? lastMessage;
|
||||
String? status;
|
||||
String? statusIcon;
|
||||
String? statusMessage;
|
||||
@@ -117,6 +130,9 @@ enum GetRoomResponseObjectConversationType {
|
||||
deleted,
|
||||
@JsonValue(6)
|
||||
noteToSelf,
|
||||
|
||||
/// Fallback for types this app does not know yet; treated like a group.
|
||||
unknown,
|
||||
}
|
||||
|
||||
enum GetRoomResponseObjectParticipantNotificationLevel {
|
||||
@@ -147,6 +163,17 @@ enum GetRoomResponseObjectMessageActorType {
|
||||
bot,
|
||||
@JsonValue('bridged')
|
||||
bridge,
|
||||
@JsonValue('groups')
|
||||
group,
|
||||
@JsonValue('emails')
|
||||
email,
|
||||
@JsonValue('circles')
|
||||
circle,
|
||||
@JsonValue('federated_users')
|
||||
federatedUser,
|
||||
@JsonValue('phones')
|
||||
phone,
|
||||
unknown,
|
||||
}
|
||||
|
||||
enum GetRoomResponseObjectMessageType {
|
||||
@@ -160,4 +187,8 @@ enum GetRoomResponseObjectMessageType {
|
||||
system,
|
||||
@JsonValue('command')
|
||||
command,
|
||||
|
||||
/// Fallback for types this app does not know yet (e.g. call recordings);
|
||||
/// rendered like a plain comment.
|
||||
unknown,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user