diff --git a/build.yaml b/build.yaml index dcc8576..4205425 100644 --- a/build.yaml +++ b/build.yaml @@ -4,4 +4,5 @@ targets: json_serializable: options: explicit_to_json: false + checked: true generic_argument_factories: true \ No newline at end of file diff --git a/lib/api/api_response.dart b/lib/api/api_response.dart index cef5697..17470f8 100644 --- a/lib/api/api_response.dart +++ b/lib/api/api_response.dart @@ -7,4 +7,9 @@ abstract class ApiResponse { @JsonKey(includeIfNull: false) Map? headers; + + /// Entries the decoder skipped (see `decodeListLenient`), reported by the + /// API layer once the response is back on the main isolate. + @JsonKey(includeFromJson: false, includeToJson: false) + List parseWarnings = const []; } diff --git a/lib/api/json_lenient.dart b/lib/api/json_lenient.dart new file mode 100644 index 0000000..b291d2f --- /dev/null +++ b/lib/api/json_lenient.dart @@ -0,0 +1,46 @@ +import 'package:json_annotation/json_annotation.dart'; + +/// Decodes server lists element by element so one entry the model cannot map +/// (a field the server dropped, an enum value it added) is skipped and +/// recorded instead of failing the whole response and with it the screen. +/// +/// Skipped entries are collected per isolate; the API layer drains them with +/// [drainDecodeWarnings] and reports them, so a drift in the server's format +/// still reaches us without taking the feature down for the user. +final List _warnings = []; + +List decodeListLenient( + Object? raw, + T Function(Map) fromJson, { + required String what, +}) { + final items = []; + if (raw is! List) { + throw FormatException( + 'expected a list of ${what}s, got ${raw.runtimeType}', + ); + } + for (final entry in raw) { + try { + items.add(fromJson(entry as Map)); + } on CheckedFromJsonException catch (e) { + _warnings.add('$what: $e'); + } on TypeError catch (e) { + _warnings.add('$what: $e'); + } + } + return items; +} + +Set decodeSetLenient( + Object? raw, + T Function(Map) fromJson, { + required String what, +}) => decodeListLenient(raw, fromJson, what: what).toSet(); + +/// Returns and clears the entries skipped since the last call. +List drainDecodeWarnings() { + final out = List.of(_warnings); + _warnings.clear(); + return out; +} diff --git a/lib/api/marianumcloud/autocomplete/autocomplete_api.dart b/lib/api/marianumcloud/autocomplete/autocomplete_api.dart index 0394871..ae083ff 100644 --- a/lib/api/marianumcloud/autocomplete/autocomplete_api.dart +++ b/lib/api/marianumcloud/autocomplete/autocomplete_api.dart @@ -5,6 +5,8 @@ import 'package:http/http.dart' as http; import '../../../model/endpoint_data.dart'; import '../../errors/server_exception.dart'; import '../../http_errors.dart'; +import '../../json_lenient.dart'; +import '../../marianumconnect/queries/report_client_error/client_error_reporter.dart'; import '../nextcloud_ocs.dart'; import 'autocomplete_response.dart'; @@ -43,6 +45,13 @@ class AutocompleteApi { technicalDetails: 'core/autocomplete/get: ${response.body}', ); } - return AutocompleteResponse.fromJson(NextcloudOcs.decode(response.body)); + final result = AutocompleteResponse.fromJson( + NextcloudOcs.decode(response.body), + ); + ClientErrorReporter.reportDecodeWarnings( + 'Autocomplete', + drainDecodeWarnings(), + ); + return result; } } diff --git a/lib/api/marianumcloud/autocomplete/autocomplete_response.dart b/lib/api/marianumcloud/autocomplete/autocomplete_response.dart index 28dcbf1..eb463de 100644 --- a/lib/api/marianumcloud/autocomplete/autocomplete_response.dart +++ b/lib/api/marianumcloud/autocomplete/autocomplete_response.dart @@ -1,5 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; +import '../../json_lenient.dart'; import '../files_sharing/queries/share/share.dart'; part 'autocomplete_response.g.dart'; @@ -14,6 +15,7 @@ int shareTypeFromSource(String? source) { @JsonSerializable(explicitToJson: true) class AutocompleteResponse { + @JsonKey(fromJson: _entriesFromJson) List data; AutocompleteResponse(this.data); @@ -23,15 +25,31 @@ class AutocompleteResponse { Map toJson() => _$AutocompleteResponseToJson(this); } +List _entriesFromJson(Object? raw) => + decodeListLenient( + raw, + AutocompleteResponseObject.fromJson, + what: 'autocomplete entry', + ); + +/// The server sends a user-status object for users that have one and an empty +/// string otherwise; only the status string itself is kept. +String? _statusFromJson(Object? raw) => switch (raw) { + Map status => status['status']?.toString(), + String status when status.isNotEmpty => status, + _ => null, +}; + @JsonSerializable() class AutocompleteResponseObject { String id; String label; String? icon; String? source; + @JsonKey(fromJson: _statusFromJson) String? status; String? subline; - String? shareWithDisplayNameUniqe; + String? shareWithDisplayNameUnique; AutocompleteResponseObject( this.id, @@ -40,7 +58,7 @@ class AutocompleteResponseObject { this.source, this.status, this.subline, - this.shareWithDisplayNameUniqe, + this.shareWithDisplayNameUnique, ); factory AutocompleteResponseObject.fromJson(Map json) => diff --git a/lib/api/marianumcloud/autocomplete/autocomplete_response.g.dart b/lib/api/marianumcloud/autocomplete/autocomplete_response.g.dart index 65b9863..50f7394 100644 --- a/lib/api/marianumcloud/autocomplete/autocomplete_response.g.dart +++ b/lib/api/marianumcloud/autocomplete/autocomplete_response.g.dart @@ -8,13 +8,12 @@ part of 'autocomplete_response.dart'; AutocompleteResponse _$AutocompleteResponseFromJson( Map json, -) => AutocompleteResponse( - (json['data'] as List) - .map( - (e) => AutocompleteResponseObject.fromJson(e as Map), - ) - .toList(), -); +) => $checkedCreate('AutocompleteResponse', json, ($checkedConvert) { + final val = AutocompleteResponse( + $checkedConvert('data', (v) => _entriesFromJson(v)), + ); + return val; +}); Map _$AutocompleteResponseToJson( AutocompleteResponse instance, @@ -22,15 +21,18 @@ Map _$AutocompleteResponseToJson( AutocompleteResponseObject _$AutocompleteResponseObjectFromJson( Map json, -) => AutocompleteResponseObject( - json['id'] as String, - json['label'] as String, - json['icon'] as String?, - json['source'] as String?, - json['status'] as String?, - json['subline'] as String?, - json['shareWithDisplayNameUniqe'] as String?, -); +) => $checkedCreate('AutocompleteResponseObject', json, ($checkedConvert) { + final val = AutocompleteResponseObject( + $checkedConvert('id', (v) => v as String), + $checkedConvert('label', (v) => v as String), + $checkedConvert('icon', (v) => v as String?), + $checkedConvert('source', (v) => v as String?), + $checkedConvert('status', (v) => _statusFromJson(v)), + $checkedConvert('subline', (v) => v as String?), + $checkedConvert('shareWithDisplayNameUnique', (v) => v as String?), + ); + return val; +}); Map _$AutocompleteResponseObjectToJson( AutocompleteResponseObject instance, @@ -41,5 +43,5 @@ Map _$AutocompleteResponseObjectToJson( 'source': instance.source, 'status': instance.status, 'subline': instance.subline, - 'shareWithDisplayNameUniqe': instance.shareWithDisplayNameUniqe, + 'shareWithDisplayNameUnique': instance.shareWithDisplayNameUnique, }; diff --git a/lib/api/marianumcloud/files_sharing/file_sharing_api_params.g.dart b/lib/api/marianumcloud/files_sharing/file_sharing_api_params.g.dart index e1d482e..6da8b4d 100644 --- a/lib/api/marianumcloud/files_sharing/file_sharing_api_params.g.dart +++ b/lib/api/marianumcloud/files_sharing/file_sharing_api_params.g.dart @@ -8,16 +8,19 @@ part of 'file_sharing_api_params.dart'; FileSharingApiParams _$FileSharingApiParamsFromJson( Map json, -) => FileSharingApiParams( - shareType: (json['shareType'] as num).toInt(), - shareWith: json['shareWith'] as String, - path: json['path'] as String, - referenceId: json['referenceId'] as String?, - talkMetaData: json['talkMetaData'] as String?, - permissions: (json['permissions'] as num?)?.toInt(), - password: json['password'] as String?, - expireDate: json['expireDate'] as String?, -); +) => $checkedCreate('FileSharingApiParams', json, ($checkedConvert) { + final val = FileSharingApiParams( + shareType: $checkedConvert('shareType', (v) => (v as num).toInt()), + shareWith: $checkedConvert('shareWith', (v) => v as String), + path: $checkedConvert('path', (v) => v as String), + referenceId: $checkedConvert('referenceId', (v) => v as String?), + talkMetaData: $checkedConvert('talkMetaData', (v) => v as String?), + permissions: $checkedConvert('permissions', (v) => (v as num?)?.toInt()), + password: $checkedConvert('password', (v) => v as String?), + expireDate: $checkedConvert('expireDate', (v) => v as String?), + ); + return val; +}); Map _$FileSharingApiParamsToJson( FileSharingApiParams instance, diff --git a/lib/api/marianumcloud/search/search_files_response.g.dart b/lib/api/marianumcloud/search/search_files_response.g.dart index 64dbe45..d4558ee 100644 --- a/lib/api/marianumcloud/search/search_files_response.g.dart +++ b/lib/api/marianumcloud/search/search_files_response.g.dart @@ -7,14 +7,20 @@ part of 'search_files_response.dart'; // ************************************************************************** SearchFilesResponse _$SearchFilesResponseFromJson(Map json) => - SearchFilesResponse( - name: json['name'] as String, - isPaginated: json['isPaginated'] as bool, - cursor: (json['cursor'] as num?)?.toInt(), - entries: (json['entries'] as List) - .map((e) => SearchFilesEntry.fromJson(e as Map)) - .toList(), - ); + $checkedCreate('SearchFilesResponse', json, ($checkedConvert) { + final val = SearchFilesResponse( + name: $checkedConvert('name', (v) => v as String), + isPaginated: $checkedConvert('isPaginated', (v) => v as bool), + cursor: $checkedConvert('cursor', (v) => (v as num?)?.toInt()), + entries: $checkedConvert( + 'entries', + (v) => (v as List) + .map((e) => SearchFilesEntry.fromJson(e as Map)) + .toList(), + ), + ); + return val; + }); Map _$SearchFilesResponseToJson( SearchFilesResponse instance, @@ -26,13 +32,19 @@ Map _$SearchFilesResponseToJson( }; SearchFilesEntry _$SearchFilesEntryFromJson(Map json) => - SearchFilesEntry( - title: json['title'] as String, - subline: json['subline'] as String?, - icon: json['icon'] as String?, - resourceUrl: json['resourceUrl'] as String?, - attributes: json['attributes'] as Map?, - ); + $checkedCreate('SearchFilesEntry', json, ($checkedConvert) { + final val = SearchFilesEntry( + title: $checkedConvert('title', (v) => v as String), + subline: $checkedConvert('subline', (v) => v as String?), + icon: $checkedConvert('icon', (v) => v as String?), + resourceUrl: $checkedConvert('resourceUrl', (v) => v as String?), + attributes: $checkedConvert( + 'attributes', + (v) => v as Map?, + ), + ); + return val; + }); Map _$SearchFilesEntryToJson(SearchFilesEntry instance) => { diff --git a/lib/api/marianumcloud/talk/chat/get_chat_params.g.dart b/lib/api/marianumcloud/talk/chat/get_chat_params.g.dart index b318eb6..ede348d 100644 --- a/lib/api/marianumcloud/talk/chat/get_chat_params.g.dart +++ b/lib/api/marianumcloud/talk/chat/get_chat_params.g.dart @@ -7,24 +7,33 @@ part of 'get_chat_params.dart'; // ************************************************************************** GetChatParams _$GetChatParamsFromJson(Map json) => - GetChatParams( - lookIntoFuture: $enumDecode( - _$GetChatParamsSwitchEnumMap, - json['lookIntoFuture'], - ), - limit: (json['limit'] as num?)?.toInt(), - lastKnownMessageId: (json['lastKnownMessageId'] as num?)?.toInt(), - lastCommonReadId: (json['lastCommonReadId'] as num?)?.toInt(), - timeout: (json['timeout'] as num?)?.toInt(), - setReadMarker: $enumDecodeNullable( - _$GetChatParamsSwitchEnumMap, - json['setReadMarker'], - ), - includeLastKnown: $enumDecodeNullable( - _$GetChatParamsSwitchEnumMap, - json['includeLastKnown'], - ), - ); + $checkedCreate('GetChatParams', json, ($checkedConvert) { + final val = GetChatParams( + lookIntoFuture: $checkedConvert( + 'lookIntoFuture', + (v) => $enumDecode(_$GetChatParamsSwitchEnumMap, v), + ), + limit: $checkedConvert('limit', (v) => (v as num?)?.toInt()), + lastKnownMessageId: $checkedConvert( + 'lastKnownMessageId', + (v) => (v as num?)?.toInt(), + ), + lastCommonReadId: $checkedConvert( + 'lastCommonReadId', + (v) => (v as num?)?.toInt(), + ), + timeout: $checkedConvert('timeout', (v) => (v as num?)?.toInt()), + setReadMarker: $checkedConvert( + 'setReadMarker', + (v) => $enumDecodeNullable(_$GetChatParamsSwitchEnumMap, v), + ), + includeLastKnown: $checkedConvert( + 'includeLastKnown', + (v) => $enumDecodeNullable(_$GetChatParamsSwitchEnumMap, v), + ), + ); + return val; + }); Map _$GetChatParamsToJson( GetChatParams instance, diff --git a/lib/api/marianumcloud/talk/chat/get_chat_response.dart b/lib/api/marianumcloud/talk/chat/get_chat_response.dart index 7dc5acc..7cb5afd 100644 --- a/lib/api/marianumcloud/talk/chat/get_chat_response.dart +++ b/lib/api/marianumcloud/talk/chat/get_chat_response.dart @@ -2,12 +2,14 @@ import 'package:json_annotation/json_annotation.dart'; import '../../../../extensions/date_time.dart'; import '../../../api_response.dart'; +import '../../../json_lenient.dart'; import '../room/get_room_response.dart'; part 'get_chat_response.g.dart'; @JsonSerializable(explicitToJson: true) class GetChatResponse extends ApiResponse { + @JsonKey(fromJson: _messagesFromJson) Set data; GetChatResponse(this.data); @@ -23,15 +25,20 @@ class GetChatResponse extends ApiResponse { } } +Set _messagesFromJson(Object? raw) => + decodeSetLenient(raw, GetChatResponseObject.fromJson, what: 'message'); + @JsonSerializable(explicitToJson: true) class GetChatResponseObject { int id; String token; + @JsonKey(unknownEnumValue: GetRoomResponseObjectMessageActorType.unknown) GetRoomResponseObjectMessageActorType actorType; String actorId; String actorDisplayName; int timestamp; String systemMessage; + @JsonKey(unknownEnumValue: GetRoomResponseObjectMessageType.unknown) GetRoomResponseObjectMessageType messageType; bool isReplyable; String referenceId; @@ -40,6 +47,11 @@ class GetChatResponseObject { List? reactionsSelf; @JsonKey(fromJson: _fromJson) Map? messageParameters; + + /// The quoted message. When the original is no longer available (expired, + /// purged) the server only sends `{id, deleted: true}`; that becomes a + /// deleted-comment placeholder so the quote still renders. + @JsonKey(fromJson: _parentFromJson) GetChatResponseObject? parent; /// Whether the server flagged this message to be rendered as Markdown @@ -73,11 +85,29 @@ class GetChatResponseObject { /// [timestamp] is in seconds. DateTime get sentAt => DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); - static GetChatResponseObject getDateDummy(int timestamp) => - getTextDummy( - DateTime.fromMillisecondsSinceEpoch( - timestamp * 1000, - ).formatDateRelativeShort(), + static GetChatResponseObject getDateDummy(int timestamp) => getTextDummy( + DateTime.fromMillisecondsSinceEpoch( + timestamp * 1000, + ).formatDateRelativeShort(), + ); + + static GetChatResponseObject deletedPlaceholder(int id) => + GetChatResponseObject( + id, + '', + GetRoomResponseObjectMessageActorType.user, + '', + '', + 0, + '', + GetRoomResponseObjectMessageType.deletedComment, + false, + '', + 'Nachricht wurde gelöscht', + null, + null, + null, + null, ); static GetChatResponseObject getTextDummy(String text) => @@ -100,14 +130,24 @@ class GetChatResponseObject { ); } +GetChatResponseObject? _parentFromJson(Object? json) { + if (json is! Map) return null; + if (json['deleted'] == true) { + return GetChatResponseObject.deletedPlaceholder( + (json['id'] as num?)?.toInt() ?? 0, + ); + } + return GetChatResponseObject.fromJson(json); +} + Map? _fromJson(dynamic json) { if (json is Map) { final data = {}; - for (final element in json.keys) { - data.putIfAbsent( - element, - () => RichObjectString.fromJson(json[element] as Map), - ); + for (final entry in json.entries) { + final value = entry.value; + if (value is Map) { + data[entry.key] = RichObjectString.fromJson(value); + } } return data; } @@ -117,6 +157,7 @@ Map? _fromJson(dynamic json) { @JsonSerializable(explicitToJson: true) class RichObjectString { + @JsonKey(unknownEnumValue: RichObjectStringObjectType.unknown) RichObjectStringObjectType type; String id; String name; @@ -148,4 +189,14 @@ enum RichObjectStringObjectType { geoLocation, @JsonValue('call') call, + @JsonValue('user-group') + userGroup, + @JsonValue('circle') + circle, + @JsonValue('email') + email, + + /// Anything else (deck cards, contacts, calendar events, ...); the + /// placeholder still resolves to the object's name. + unknown, } diff --git a/lib/api/marianumcloud/talk/chat/get_chat_response.g.dart b/lib/api/marianumcloud/talk/chat/get_chat_response.g.dart index 9d48637..b3080ea 100644 --- a/lib/api/marianumcloud/talk/chat/get_chat_response.g.dart +++ b/lib/api/marianumcloud/talk/chat/get_chat_response.g.dart @@ -7,16 +7,18 @@ part of 'get_chat_response.dart'; // ************************************************************************** GetChatResponse _$GetChatResponseFromJson(Map json) => - GetChatResponse( - (json['data'] as List) - .map( - (e) => GetChatResponseObject.fromJson(e as Map), - ) - .toSet(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), + $checkedCreate('GetChatResponse', json, ($checkedConvert) { + final val = GetChatResponse( + $checkedConvert('data', (v) => _messagesFromJson(v)), ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; + }); Map _$GetChatResponseToJson(GetChatResponse instance) => { @@ -26,31 +28,49 @@ Map _$GetChatResponseToJson(GetChatResponse instance) => GetChatResponseObject _$GetChatResponseObjectFromJson( Map json, -) => GetChatResponseObject( - (json['id'] as num).toInt(), - json['token'] as String, - $enumDecode( - _$GetRoomResponseObjectMessageActorTypeEnumMap, - json['actorType'], - ), - json['actorId'] as String, - json['actorDisplayName'] as String, - (json['timestamp'] as num).toInt(), - json['systemMessage'] as String, - $enumDecode(_$GetRoomResponseObjectMessageTypeEnumMap, json['messageType']), - json['isReplyable'] as bool, - json['referenceId'] as String, - json['message'] as String, - _fromJson(json['messageParameters']), - (json['reactions'] as Map?)?.map( - (k, e) => MapEntry(k, (e as num).toInt()), - ), - (json['reactionsSelf'] as List?)?.map((e) => e as String).toList(), - json['parent'] == null - ? null - : GetChatResponseObject.fromJson(json['parent'] as Map), - json['markdown'] as bool? ?? false, -); +) => $checkedCreate('GetChatResponseObject', json, ($checkedConvert) { + final val = GetChatResponseObject( + $checkedConvert('id', (v) => (v as num).toInt()), + $checkedConvert('token', (v) => v as String), + $checkedConvert( + 'actorType', + (v) => $enumDecode( + _$GetRoomResponseObjectMessageActorTypeEnumMap, + v, + unknownValue: GetRoomResponseObjectMessageActorType.unknown, + ), + ), + $checkedConvert('actorId', (v) => v as String), + $checkedConvert('actorDisplayName', (v) => v as String), + $checkedConvert('timestamp', (v) => (v as num).toInt()), + $checkedConvert('systemMessage', (v) => v as String), + $checkedConvert( + 'messageType', + (v) => $enumDecode( + _$GetRoomResponseObjectMessageTypeEnumMap, + v, + unknownValue: GetRoomResponseObjectMessageType.unknown, + ), + ), + $checkedConvert('isReplyable', (v) => v as bool), + $checkedConvert('referenceId', (v) => v as String), + $checkedConvert('message', (v) => v as String), + $checkedConvert('messageParameters', (v) => _fromJson(v)), + $checkedConvert( + 'reactions', + (v) => (v as Map?)?.map( + (k, e) => MapEntry(k, (e as num).toInt()), + ), + ), + $checkedConvert( + 'reactionsSelf', + (v) => (v as List?)?.map((e) => e as String).toList(), + ), + $checkedConvert('parent', (v) => _parentFromJson(v)), + $checkedConvert('markdown', (v) => v as bool? ?? false), + ); + return val; +}); Map _$GetChatResponseObjectToJson( GetChatResponseObject instance, @@ -83,6 +103,12 @@ const _$GetRoomResponseObjectMessageActorTypeEnumMap = { GetRoomResponseObjectMessageActorType.guest: 'guests', GetRoomResponseObjectMessageActorType.bot: 'bots', GetRoomResponseObjectMessageActorType.bridge: 'bridged', + GetRoomResponseObjectMessageActorType.group: 'groups', + GetRoomResponseObjectMessageActorType.email: 'emails', + GetRoomResponseObjectMessageActorType.circle: 'circles', + GetRoomResponseObjectMessageActorType.federatedUser: 'federated_users', + GetRoomResponseObjectMessageActorType.phone: 'phones', + GetRoomResponseObjectMessageActorType.unknown: 'unknown', }; const _$GetRoomResponseObjectMessageTypeEnumMap = { @@ -91,16 +117,27 @@ const _$GetRoomResponseObjectMessageTypeEnumMap = { GetRoomResponseObjectMessageType.deletedComment: 'comment_deleted', GetRoomResponseObjectMessageType.system: 'system', GetRoomResponseObjectMessageType.command: 'command', + GetRoomResponseObjectMessageType.unknown: 'unknown', }; RichObjectString _$RichObjectStringFromJson(Map json) => - RichObjectString( - $enumDecode(_$RichObjectStringObjectTypeEnumMap, json['type']), - json['id'] as String, - json['name'] as String, - json['path'] as String?, - json['link'] as String?, - ); + $checkedCreate('RichObjectString', json, ($checkedConvert) { + final val = RichObjectString( + $checkedConvert( + 'type', + (v) => $enumDecode( + _$RichObjectStringObjectTypeEnumMap, + v, + unknownValue: RichObjectStringObjectType.unknown, + ), + ), + $checkedConvert('id', (v) => v as String), + $checkedConvert('name', (v) => v as String), + $checkedConvert('path', (v) => v as String?), + $checkedConvert('link', (v) => v as String?), + ); + return val; + }); Map _$RichObjectStringToJson(RichObjectString instance) => { @@ -120,4 +157,8 @@ const _$RichObjectStringObjectTypeEnumMap = { RichObjectStringObjectType.talkPoll: 'talk-poll', RichObjectStringObjectType.geoLocation: 'geo-location', RichObjectStringObjectType.call: 'call', + RichObjectStringObjectType.userGroup: 'user-group', + RichObjectStringObjectType.circle: 'circle', + RichObjectStringObjectType.email: 'email', + RichObjectStringObjectType.unknown: 'unknown', }; diff --git a/lib/api/marianumcloud/talk/create_poll/create_poll_params.g.dart b/lib/api/marianumcloud/talk/create_poll/create_poll_params.g.dart index 46dc517..7eacc8e 100644 --- a/lib/api/marianumcloud/talk/create_poll/create_poll_params.g.dart +++ b/lib/api/marianumcloud/talk/create_poll/create_poll_params.g.dart @@ -7,14 +7,18 @@ part of 'create_poll_params.dart'; // ************************************************************************** CreatePollParams _$CreatePollParamsFromJson(Map json) => - CreatePollParams( - question: json['question'] as String, - options: (json['options'] as List) - .map((e) => e as String) - .toList(), - resultMode: (json['resultMode'] as num).toInt(), - maxVotes: (json['maxVotes'] as num).toInt(), - ); + $checkedCreate('CreatePollParams', json, ($checkedConvert) { + final val = CreatePollParams( + question: $checkedConvert('question', (v) => v as String), + options: $checkedConvert( + 'options', + (v) => (v as List).map((e) => e as String).toList(), + ), + resultMode: $checkedConvert('resultMode', (v) => (v as num).toInt()), + maxVotes: $checkedConvert('maxVotes', (v) => (v as num).toInt()), + ); + return val; + }); Map _$CreatePollParamsToJson(CreatePollParams instance) => { diff --git a/lib/api/marianumcloud/talk/create_room/create_room_params.g.dart b/lib/api/marianumcloud/talk/create_room/create_room_params.g.dart index b873df4..0855d25 100644 --- a/lib/api/marianumcloud/talk/create_room/create_room_params.g.dart +++ b/lib/api/marianumcloud/talk/create_room/create_room_params.g.dart @@ -7,14 +7,17 @@ part of 'create_room_params.dart'; // ************************************************************************** CreateRoomParams _$CreateRoomParamsFromJson(Map json) => - CreateRoomParams( - roomType: (json['roomType'] as num).toInt(), - invite: json['invite'] as String, - source: json['source'] as String?, - roomName: json['roomName'] as String?, - objectType: json['objectType'] as String?, - objectId: json['objectId'] as String?, - ); + $checkedCreate('CreateRoomParams', json, ($checkedConvert) { + final val = CreateRoomParams( + roomType: $checkedConvert('roomType', (v) => (v as num).toInt()), + invite: $checkedConvert('invite', (v) => v as String), + source: $checkedConvert('source', (v) => v as String?), + roomName: $checkedConvert('roomName', (v) => v as String?), + objectType: $checkedConvert('objectType', (v) => v as String?), + objectId: $checkedConvert('objectId', (v) => v as String?), + ); + return val; + }); Map _$CreateRoomParamsToJson(CreateRoomParams instance) => { diff --git a/lib/api/marianumcloud/talk/create_room/create_room_response.g.dart b/lib/api/marianumcloud/talk/create_room/create_room_response.g.dart index f079e1c..4db5d69 100644 --- a/lib/api/marianumcloud/talk/create_room/create_room_response.g.dart +++ b/lib/api/marianumcloud/talk/create_room/create_room_response.g.dart @@ -7,12 +7,21 @@ part of 'create_room_response.dart'; // ************************************************************************** CreateRoomResponse _$CreateRoomResponseFromJson(Map json) => - CreateRoomResponse( - CreateRoomResponseData.fromJson(json['data'] as Map), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), + $checkedCreate('CreateRoomResponse', json, ($checkedConvert) { + final val = CreateRoomResponse( + $checkedConvert( + 'data', + (v) => CreateRoomResponseData.fromJson(v as Map), + ), ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; + }); Map _$CreateRoomResponseToJson(CreateRoomResponse instance) => { @@ -22,7 +31,12 @@ Map _$CreateRoomResponseToJson(CreateRoomResponse instance) => CreateRoomResponseData _$CreateRoomResponseDataFromJson( Map json, -) => CreateRoomResponseData(json['token'] as String); +) => $checkedCreate('CreateRoomResponseData', json, ($checkedConvert) { + final val = CreateRoomResponseData( + $checkedConvert('token', (v) => v as String), + ); + return val; +}); Map _$CreateRoomResponseDataToJson( CreateRoomResponseData instance, diff --git a/lib/api/marianumcloud/talk/delete_react_message/delete_react_message_params.g.dart b/lib/api/marianumcloud/talk/delete_react_message/delete_react_message_params.g.dart index 9f50520..01d66c9 100644 --- a/lib/api/marianumcloud/talk/delete_react_message/delete_react_message_params.g.dart +++ b/lib/api/marianumcloud/talk/delete_react_message/delete_react_message_params.g.dart @@ -8,7 +8,12 @@ part of 'delete_react_message_params.dart'; DeleteReactMessageParams _$DeleteReactMessageParamsFromJson( Map json, -) => DeleteReactMessageParams(json['reaction'] as String); +) => $checkedCreate('DeleteReactMessageParams', json, ($checkedConvert) { + final val = DeleteReactMessageParams( + $checkedConvert('reaction', (v) => v as String), + ); + return val; +}); Map _$DeleteReactMessageParamsToJson( DeleteReactMessageParams instance, diff --git a/lib/api/marianumcloud/talk/get_participants/get_participants_response.dart b/lib/api/marianumcloud/talk/get_participants/get_participants_response.dart index 12a362b..1fea2d7 100644 --- a/lib/api/marianumcloud/talk/get_participants/get_participants_response.dart +++ b/lib/api/marianumcloud/talk/get_participants/get_participants_response.dart @@ -1,11 +1,13 @@ import 'package:json_annotation/json_annotation.dart'; import '../../../api_response.dart'; +import '../../../json_lenient.dart'; part 'get_participants_response.g.dart'; @JsonSerializable(explicitToJson: true) class GetParticipantsResponse extends ApiResponse { + @JsonKey(fromJson: _participantsFromJson) Set data; GetParticipantsResponse(this.data); @@ -15,15 +17,25 @@ class GetParticipantsResponse extends ApiResponse { Map toJson() => _$GetParticipantsResponseToJson(this); } +Set _participantsFromJson(Object? raw) => + decodeSetLenient( + raw, + GetParticipantsResponseObject.fromJson, + what: 'participant', + ); + @JsonSerializable(explicitToJson: true) class GetParticipantsResponseObject { int attendeeId; String actorType; String actorId; String displayName; + @JsonKey(unknownEnumValue: GetParticipantsResponseObjectParticipantType.user) GetParticipantsResponseObjectParticipantType participantType; int lastPing; - GetParticipantsResponseObjectParticipantsInCallFlags inCall; + + /// Bitmask: 1 = in call, 2 = with audio, 4 = with video, 8 = via phone. + int inCall; int permissions; int attendeePermissions; String? sessionId; @@ -54,6 +66,11 @@ class GetParticipantsResponseObject { factory GetParticipantsResponseObject.fromJson(Map json) => _$GetParticipantsResponseObjectFromJson(json); Map toJson() => _$GetParticipantsResponseObjectToJson(this); + + bool get isInCall => inCall & 1 != 0; + bool get inCallWithAudio => inCall & 2 != 0; + bool get inCallWithVideo => inCall & 4 != 0; + bool get inCallViaPhone => inCall & 8 != 0; } enum GetParticipantsResponseObjectParticipantType { @@ -73,16 +90,3 @@ enum GetParticipantsResponseObjectParticipantType { const GetParticipantsResponseObjectParticipantType(this.prettyName); final String prettyName; } - -enum GetParticipantsResponseObjectParticipantsInCallFlags { - @JsonValue(0) - disconnected, - @JsonValue(1) - inCall, - @JsonValue(2) - providesAudio, - @JsonValue(3) - providesVideo, - @JsonValue(4) - usesSipDialIn, -} diff --git a/lib/api/marianumcloud/talk/get_participants/get_participants_response.g.dart b/lib/api/marianumcloud/talk/get_participants/get_participants_response.g.dart index f3fd7cb..d44746c 100644 --- a/lib/api/marianumcloud/talk/get_participants/get_participants_response.g.dart +++ b/lib/api/marianumcloud/talk/get_participants/get_participants_response.g.dart @@ -8,19 +8,18 @@ part of 'get_participants_response.dart'; GetParticipantsResponse _$GetParticipantsResponseFromJson( Map json, -) => - GetParticipantsResponse( - (json['data'] as List) - .map( - (e) => GetParticipantsResponseObject.fromJson( - e as Map, - ), - ) - .toSet(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('GetParticipantsResponse', json, ($checkedConvert) { + final val = GetParticipantsResponse( + $checkedConvert('data', (v) => _participantsFromJson(v)), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$GetParticipantsResponseToJson( GetParticipantsResponse instance, @@ -31,29 +30,36 @@ Map _$GetParticipantsResponseToJson( GetParticipantsResponseObject _$GetParticipantsResponseObjectFromJson( Map json, -) => GetParticipantsResponseObject( - (json['attendeeId'] as num).toInt(), - json['actorType'] as String, - json['actorId'] as String, - json['displayName'] as String, - $enumDecode( - _$GetParticipantsResponseObjectParticipantTypeEnumMap, - json['participantType'], - ), - (json['lastPing'] as num).toInt(), - $enumDecode( - _$GetParticipantsResponseObjectParticipantsInCallFlagsEnumMap, - json['inCall'], - ), - (json['permissions'] as num).toInt(), - (json['attendeePermissions'] as num).toInt(), - json['sessionId'] as String?, - (json['sessionIds'] as List).map((e) => e as String).toList(), - json['status'] as String?, - json['statusIcon'] as String?, - json['statusMessage'] as String?, - json['roomToken'] as String?, -); +) => $checkedCreate('GetParticipantsResponseObject', json, ($checkedConvert) { + final val = GetParticipantsResponseObject( + $checkedConvert('attendeeId', (v) => (v as num).toInt()), + $checkedConvert('actorType', (v) => v as String), + $checkedConvert('actorId', (v) => v as String), + $checkedConvert('displayName', (v) => v as String), + $checkedConvert( + 'participantType', + (v) => $enumDecode( + _$GetParticipantsResponseObjectParticipantTypeEnumMap, + v, + unknownValue: GetParticipantsResponseObjectParticipantType.user, + ), + ), + $checkedConvert('lastPing', (v) => (v as num).toInt()), + $checkedConvert('inCall', (v) => (v as num).toInt()), + $checkedConvert('permissions', (v) => (v as num).toInt()), + $checkedConvert('attendeePermissions', (v) => (v as num).toInt()), + $checkedConvert('sessionId', (v) => v as String?), + $checkedConvert( + 'sessionIds', + (v) => (v as List).map((e) => e as String).toList(), + ), + $checkedConvert('status', (v) => v as String?), + $checkedConvert('statusIcon', (v) => v as String?), + $checkedConvert('statusMessage', (v) => v as String?), + $checkedConvert('roomToken', (v) => v as String?), + ); + return val; +}); Map _$GetParticipantsResponseObjectToJson( GetParticipantsResponseObject instance, @@ -66,9 +72,7 @@ Map _$GetParticipantsResponseObjectToJson( _$GetParticipantsResponseObjectParticipantTypeEnumMap[instance .participantType]!, 'lastPing': instance.lastPing, - 'inCall': - _$GetParticipantsResponseObjectParticipantsInCallFlagsEnumMap[instance - .inCall]!, + 'inCall': instance.inCall, 'permissions': instance.permissions, 'attendeePermissions': instance.attendeePermissions, 'sessionId': instance.sessionId, @@ -87,11 +91,3 @@ const _$GetParticipantsResponseObjectParticipantTypeEnumMap = { GetParticipantsResponseObjectParticipantType.userFollowingPublicLink: 5, GetParticipantsResponseObjectParticipantType.guestWithModeratorPermissions: 6, }; - -const _$GetParticipantsResponseObjectParticipantsInCallFlagsEnumMap = { - GetParticipantsResponseObjectParticipantsInCallFlags.disconnected: 0, - GetParticipantsResponseObjectParticipantsInCallFlags.inCall: 1, - GetParticipantsResponseObjectParticipantsInCallFlags.providesAudio: 2, - GetParticipantsResponseObjectParticipantsInCallFlags.providesVideo: 3, - GetParticipantsResponseObjectParticipantsInCallFlags.usesSipDialIn: 4, -}; diff --git a/lib/api/marianumcloud/talk/get_poll/get_poll_state_response.g.dart b/lib/api/marianumcloud/talk/get_poll/get_poll_state_response.g.dart index c81d2f5..8c6f4f2 100644 --- a/lib/api/marianumcloud/talk/get_poll/get_poll_state_response.g.dart +++ b/lib/api/marianumcloud/talk/get_poll/get_poll_state_response.g.dart @@ -8,15 +8,21 @@ part of 'get_poll_state_response.dart'; GetPollStateResponse _$GetPollStateResponseFromJson( Map json, -) => - GetPollStateResponse( - GetPollStateResponseObject.fromJson( - json['data'] as Map, - ), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('GetPollStateResponse', json, ($checkedConvert) { + final val = GetPollStateResponse( + $checkedConvert( + 'data', + (v) => GetPollStateResponseObject.fromJson(v as Map), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$GetPollStateResponseToJson( GetPollStateResponse instance, @@ -27,21 +33,30 @@ Map _$GetPollStateResponseToJson( GetPollStateResponseObject _$GetPollStateResponseObjectFromJson( Map json, -) => GetPollStateResponseObject( - (json['id'] as num).toInt(), - json['question'] as String, - (json['options'] as List).map((e) => e as String).toList(), - json['votes'], - json['actorType'] as String, - json['actorId'] as String, - json['actorDisplayName'] as String, - (json['status'] as num).toInt(), - (json['resultMode'] as num).toInt(), - (json['maxVotes'] as num).toInt(), - (json['votedSelf'] as List).map((e) => (e as num).toInt()).toList(), - (json['numVoters'] as num?)?.toInt(), - json['details'] as List?, -); +) => $checkedCreate('GetPollStateResponseObject', json, ($checkedConvert) { + final val = GetPollStateResponseObject( + $checkedConvert('id', (v) => (v as num).toInt()), + $checkedConvert('question', (v) => v as String), + $checkedConvert( + 'options', + (v) => (v as List).map((e) => e as String).toList(), + ), + $checkedConvert('votes', (v) => v), + $checkedConvert('actorType', (v) => v as String), + $checkedConvert('actorId', (v) => v as String), + $checkedConvert('actorDisplayName', (v) => v as String), + $checkedConvert('status', (v) => (v as num).toInt()), + $checkedConvert('resultMode', (v) => (v as num).toInt()), + $checkedConvert('maxVotes', (v) => (v as num).toInt()), + $checkedConvert( + 'votedSelf', + (v) => (v as List).map((e) => (e as num).toInt()).toList(), + ), + $checkedConvert('numVoters', (v) => (v as num?)?.toInt()), + $checkedConvert('details', (v) => v as List?), + ); + return val; +}); Map _$GetPollStateResponseObjectToJson( GetPollStateResponseObject instance, diff --git a/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.dart b/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.dart index 1f58dfc..78c9727 100644 --- a/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.dart +++ b/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.dart @@ -17,6 +17,7 @@ class GetReactionsResponse extends ApiResponse { @JsonSerializable() class GetReactionsResponseObject { + @JsonKey(unknownEnumValue: GetReactionsResponseObjectActorType.unknown) GetReactionsResponseObjectActorType actorType; String actorId; String actorDisplayName; @@ -39,4 +40,11 @@ enum GetReactionsResponseObjectActorType { guests, @JsonValue('users') users, + @JsonValue('emails') + emails, + @JsonValue('bots') + bots, + @JsonValue('federated_users') + federatedUsers, + unknown, } diff --git a/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.g.dart b/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.g.dart index a050c59..77a8c3b 100644 --- a/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.g.dart +++ b/lib/api/marianumcloud/talk/get_reactions/get_reactions_response.g.dart @@ -8,24 +8,32 @@ part of 'get_reactions_response.dart'; GetReactionsResponse _$GetReactionsResponseFromJson( Map json, -) => - GetReactionsResponse( - (json['data'] as Map).map( - (k, e) => MapEntry( - k, - (e as List) - .map( - (e) => GetReactionsResponseObject.fromJson( - e as Map, - ), - ) - .toList(), - ), +) => $checkedCreate('GetReactionsResponse', json, ($checkedConvert) { + final val = GetReactionsResponse( + $checkedConvert( + 'data', + (v) => (v as Map).map( + (k, e) => MapEntry( + k, + (e as List) + .map( + (e) => GetReactionsResponseObject.fromJson( + e as Map, + ), + ) + .toList(), ), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); + ), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$GetReactionsResponseToJson( GetReactionsResponse instance, @@ -38,12 +46,22 @@ Map _$GetReactionsResponseToJson( GetReactionsResponseObject _$GetReactionsResponseObjectFromJson( Map json, -) => GetReactionsResponseObject( - $enumDecode(_$GetReactionsResponseObjectActorTypeEnumMap, json['actorType']), - json['actorId'] as String, - json['actorDisplayName'] as String, - (json['timestamp'] as num).toInt(), -); +) => $checkedCreate('GetReactionsResponseObject', json, ($checkedConvert) { + final val = GetReactionsResponseObject( + $checkedConvert( + 'actorType', + (v) => $enumDecode( + _$GetReactionsResponseObjectActorTypeEnumMap, + v, + unknownValue: GetReactionsResponseObjectActorType.unknown, + ), + ), + $checkedConvert('actorId', (v) => v as String), + $checkedConvert('actorDisplayName', (v) => v as String), + $checkedConvert('timestamp', (v) => (v as num).toInt()), + ); + return val; +}); Map _$GetReactionsResponseObjectToJson( GetReactionsResponseObject instance, @@ -58,4 +76,8 @@ Map _$GetReactionsResponseObjectToJson( const _$GetReactionsResponseObjectActorTypeEnumMap = { GetReactionsResponseObjectActorType.guests: 'guests', GetReactionsResponseObjectActorType.users: 'users', + GetReactionsResponseObjectActorType.emails: 'emails', + GetReactionsResponseObjectActorType.bots: 'bots', + GetReactionsResponseObjectActorType.federatedUsers: 'federated_users', + GetReactionsResponseObjectActorType.unknown: 'unknown', }; diff --git a/lib/api/marianumcloud/talk/react_message/react_message_params.g.dart b/lib/api/marianumcloud/talk/react_message/react_message_params.g.dart index 054b0c6..cff54bf 100644 --- a/lib/api/marianumcloud/talk/react_message/react_message_params.g.dart +++ b/lib/api/marianumcloud/talk/react_message/react_message_params.g.dart @@ -7,7 +7,12 @@ part of 'react_message_params.dart'; // ************************************************************************** ReactMessageParams _$ReactMessageParamsFromJson(Map json) => - ReactMessageParams(json['reaction'] as String); + $checkedCreate('ReactMessageParams', json, ($checkedConvert) { + final val = ReactMessageParams( + $checkedConvert('reaction', (v) => v as String), + ); + return val; + }); Map _$ReactMessageParamsToJson(ReactMessageParams instance) => {'reaction': instance.reaction}; diff --git a/lib/api/marianumcloud/talk/room/get_room.dart b/lib/api/marianumcloud/talk/room/get_room.dart index 7732ee8..352738d 100644 --- a/lib/api/marianumcloud/talk/room/get_room.dart +++ b/lib/api/marianumcloud/talk/room/get_room.dart @@ -1,5 +1,6 @@ import 'package:flutter/foundation.dart'; +import '../../../json_lenient.dart'; import '../../nextcloud_ocs.dart'; import '../talk_api.dart'; import 'get_room_params.dart'; @@ -19,4 +20,5 @@ class GetRoom extends TalkApi { } GetRoomResponse _parseRooms(String raw) => - GetRoomResponse.fromJson(NextcloudOcs.decode(raw)); + GetRoomResponse.fromJson(NextcloudOcs.decode(raw)) + ..parseWarnings = drainDecodeWarnings(); diff --git a/lib/api/marianumcloud/talk/room/get_room_params.dart b/lib/api/marianumcloud/talk/room/get_room_params.dart index 35dc4b8..f76e70b 100644 --- a/lib/api/marianumcloud/talk/room/get_room_params.dart +++ b/lib/api/marianumcloud/talk/room/get_room_params.dart @@ -4,7 +4,7 @@ import '../../../api_params.dart'; part 'get_room_params.g.dart'; -@JsonSerializable(explicitToJson: true) +@JsonSerializable(explicitToJson: true, includeIfNull: false) class GetRoomParams extends ApiParams { GetRoomParamsStatusUpdate? noStatusUpdate; @JsonKey(toJson: _format) diff --git a/lib/api/marianumcloud/talk/room/get_room_params.g.dart b/lib/api/marianumcloud/talk/room/get_room_params.g.dart index ceaa6b1..c28f4cb 100644 --- a/lib/api/marianumcloud/talk/room/get_room_params.g.dart +++ b/lib/api/marianumcloud/talk/room/get_room_params.g.dart @@ -7,22 +7,28 @@ part of 'get_room_params.dart'; // ************************************************************************** GetRoomParams _$GetRoomParamsFromJson(Map json) => - GetRoomParams( - noStatusUpdate: $enumDecodeNullable( - _$GetRoomParamsStatusUpdateEnumMap, - json['noStatusUpdate'], - ), - includeStatus: json['includeStatus'] as bool?, - modifiedSince: (json['modifiedSince'] as num?)?.toInt(), - ); + $checkedCreate('GetRoomParams', json, ($checkedConvert) { + final val = GetRoomParams( + noStatusUpdate: $checkedConvert( + 'noStatusUpdate', + (v) => $enumDecodeNullable(_$GetRoomParamsStatusUpdateEnumMap, v), + ), + includeStatus: $checkedConvert('includeStatus', (v) => v as bool?), + modifiedSince: $checkedConvert( + 'modifiedSince', + (v) => (v as num?)?.toInt(), + ), + ); + return val; + }); -Map _$GetRoomParamsToJson( - GetRoomParams instance, -) => { - 'noStatusUpdate': _$GetRoomParamsStatusUpdateEnumMap[instance.noStatusUpdate], - 'includeStatus': GetRoomParams._format(instance.includeStatus), - 'modifiedSince': instance.modifiedSince, -}; +Map _$GetRoomParamsToJson(GetRoomParams instance) => + { + 'noStatusUpdate': + ?_$GetRoomParamsStatusUpdateEnumMap[instance.noStatusUpdate], + 'includeStatus': GetRoomParams._format(instance.includeStatus), + 'modifiedSince': ?instance.modifiedSince, + }; const _$GetRoomParamsStatusUpdateEnumMap = { GetRoomParamsStatusUpdate.defaults: 0, diff --git a/lib/api/marianumcloud/talk/room/get_room_response.dart b/lib/api/marianumcloud/talk/room/get_room_response.dart index 5610efa..c59ded3 100644 --- a/lib/api/marianumcloud/talk/room/get_room_response.dart +++ b/lib/api/marianumcloud/talk/room/get_room_response.dart @@ -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 data; GetRoomResponse(this.data); @@ -33,10 +35,14 @@ class GetRoomResponse extends ApiResponse { } } +Set _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, } diff --git a/lib/api/marianumcloud/talk/room/get_room_response.g.dart b/lib/api/marianumcloud/talk/room/get_room_response.g.dart index edda039..073a3cc 100644 --- a/lib/api/marianumcloud/talk/room/get_room_response.g.dart +++ b/lib/api/marianumcloud/talk/room/get_room_response.g.dart @@ -7,16 +7,18 @@ part of 'get_room_response.dart'; // ************************************************************************** GetRoomResponse _$GetRoomResponseFromJson(Map json) => - GetRoomResponse( - (json['data'] as List) - .map( - (e) => GetRoomResponseObject.fromJson(e as Map), - ) - .toSet(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), + $checkedCreate('GetRoomResponse', json, ($checkedConvert) { + final val = GetRoomResponse( + $checkedConvert('data', (v) => _roomsFromJson(v)), ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; + }); Map _$GetRoomResponseToJson(GetRoomResponse instance) => { @@ -26,41 +28,61 @@ Map _$GetRoomResponseToJson(GetRoomResponse instance) => GetRoomResponseObject _$GetRoomResponseObjectFromJson( Map json, -) => GetRoomResponseObject( - (json['id'] as num).toInt(), - json['token'] as String, - $enumDecode(_$GetRoomResponseObjectConversationTypeEnumMap, json['type']), - json['name'] as String, - json['displayName'] as String, - json['description'] as String, - (json['participantType'] as num).toInt(), - (json['participantFlags'] as num).toInt(), - (json['readOnly'] as num).toInt(), - (json['listable'] as num).toInt(), - (json['lastPing'] as num).toInt(), - json['sessionId'] as String, - json['hasPassword'] as bool, - json['hasCall'] as bool, - (json['callFlag'] as num).toInt(), - json['canStartCall'] as bool, - json['canDeleteConversation'] as bool, - json['canLeaveConversation'] as bool, - (json['lastActivity'] as num).toInt(), - json['isFavorite'] as bool, - $enumDecode( - _$GetRoomResponseObjectParticipantNotificationLevelEnumMap, - json['notificationLevel'], - ), - (json['unreadMessages'] as num).toInt(), - json['unreadMention'] as bool, - json['unreadMentionDirect'] as bool, - (json['lastReadMessage'] as num).toInt(), - (json['lastCommonReadMessage'] as num).toInt(), - GetChatResponseObject.fromJson(json['lastMessage'] as Map), - json['status'] as String?, - json['statusIcon'] as String?, - json['statusMessage'] as String?, -); +) => $checkedCreate('GetRoomResponseObject', json, ($checkedConvert) { + final val = GetRoomResponseObject( + $checkedConvert('id', (v) => (v as num).toInt()), + $checkedConvert('token', (v) => v as String), + $checkedConvert( + 'type', + (v) => $enumDecode( + _$GetRoomResponseObjectConversationTypeEnumMap, + v, + unknownValue: GetRoomResponseObjectConversationType.unknown, + ), + ), + $checkedConvert('name', (v) => v as String), + $checkedConvert('displayName', (v) => v as String), + $checkedConvert('description', (v) => v as String), + $checkedConvert('participantType', (v) => (v as num).toInt()), + $checkedConvert('participantFlags', (v) => (v as num).toInt()), + $checkedConvert('readOnly', (v) => (v as num).toInt()), + $checkedConvert('listable', (v) => (v as num).toInt()), + $checkedConvert('lastPing', (v) => (v as num).toInt()), + $checkedConvert('sessionId', (v) => v as String), + $checkedConvert('hasPassword', (v) => v as bool), + $checkedConvert('hasCall', (v) => v as bool), + $checkedConvert('callFlag', (v) => (v as num).toInt()), + $checkedConvert('canStartCall', (v) => v as bool), + $checkedConvert('canDeleteConversation', (v) => v as bool), + $checkedConvert('canLeaveConversation', (v) => v as bool), + $checkedConvert('lastActivity', (v) => (v as num).toInt()), + $checkedConvert('isFavorite', (v) => v as bool), + $checkedConvert( + 'notificationLevel', + (v) => $enumDecode( + _$GetRoomResponseObjectParticipantNotificationLevelEnumMap, + v, + unknownValue: + GetRoomResponseObjectParticipantNotificationLevel.defaultLevel, + ), + ), + $checkedConvert('unreadMessages', (v) => (v as num).toInt()), + $checkedConvert('unreadMention', (v) => v as bool), + $checkedConvert('unreadMentionDirect', (v) => v as bool), + $checkedConvert('lastReadMessage', (v) => (v as num).toInt()), + $checkedConvert('lastCommonReadMessage', (v) => (v as num).toInt()), + $checkedConvert( + 'lastMessage', + (v) => v == null + ? null + : GetChatResponseObject.fromJson(v as Map), + ), + $checkedConvert('status', (v) => v as String?), + $checkedConvert('statusIcon', (v) => v as String?), + $checkedConvert('statusMessage', (v) => v as String?), + ); + return val; +}); Map _$GetRoomResponseObjectToJson( GetRoomResponseObject instance, @@ -93,7 +115,7 @@ Map _$GetRoomResponseObjectToJson( 'unreadMentionDirect': instance.unreadMentionDirect, 'lastReadMessage': instance.lastReadMessage, 'lastCommonReadMessage': instance.lastCommonReadMessage, - 'lastMessage': instance.lastMessage.toJson(), + 'lastMessage': instance.lastMessage?.toJson(), 'status': instance.status, 'statusIcon': instance.statusIcon, 'statusMessage': instance.statusMessage, @@ -106,6 +128,7 @@ const _$GetRoomResponseObjectConversationTypeEnumMap = { GetRoomResponseObjectConversationType.changelog: 4, GetRoomResponseObjectConversationType.deleted: 5, GetRoomResponseObjectConversationType.noteToSelf: 6, + GetRoomResponseObjectConversationType.unknown: 'unknown', }; const _$GetRoomResponseObjectParticipantNotificationLevelEnumMap = { diff --git a/lib/api/marianumcloud/talk/send_message/send_message_params.g.dart b/lib/api/marianumcloud/talk/send_message/send_message_params.g.dart index 34e1d0c..b4f60a9 100644 --- a/lib/api/marianumcloud/talk/send_message/send_message_params.g.dart +++ b/lib/api/marianumcloud/talk/send_message/send_message_params.g.dart @@ -7,10 +7,13 @@ part of 'send_message_params.dart'; // ************************************************************************** SendMessageParams _$SendMessageParamsFromJson(Map json) => - SendMessageParams( - json['message'] as String, - replyTo: json['replyTo'] as String?, - ); + $checkedCreate('SendMessageParams', json, ($checkedConvert) { + final val = SendMessageParams( + $checkedConvert('message', (v) => v as String), + replyTo: $checkedConvert('replyTo', (v) => v as String?), + ); + return val; + }); Map _$SendMessageParamsToJson(SendMessageParams instance) => { diff --git a/lib/api/marianumcloud/talk/set_read_marker/set_read_marker_params.g.dart b/lib/api/marianumcloud/talk/set_read_marker/set_read_marker_params.g.dart index e6067b1..0dfe958 100644 --- a/lib/api/marianumcloud/talk/set_read_marker/set_read_marker_params.g.dart +++ b/lib/api/marianumcloud/talk/set_read_marker/set_read_marker_params.g.dart @@ -7,9 +7,15 @@ part of 'set_read_marker_params.dart'; // ************************************************************************** SetReadMarkerParams _$SetReadMarkerParamsFromJson(Map json) => - SetReadMarkerParams( - lastReadMessage: (json['lastReadMessage'] as num?)?.toInt(), - ); + $checkedCreate('SetReadMarkerParams', json, ($checkedConvert) { + final val = SetReadMarkerParams( + lastReadMessage: $checkedConvert( + 'lastReadMessage', + (v) => (v as num?)?.toInt(), + ), + ); + return val; + }); Map _$SetReadMarkerParamsToJson( SetReadMarkerParams instance, diff --git a/lib/api/marianumcloud/talk/talk_api.dart b/lib/api/marianumcloud/talk/talk_api.dart index 2d743e1..8206596 100644 --- a/lib/api/marianumcloud/talk/talk_api.dart +++ b/lib/api/marianumcloud/talk/talk_api.dart @@ -8,6 +8,8 @@ import '../../errors/network_exception.dart'; import '../../errors/parse_exception.dart'; import '../../errors/talk_exception.dart'; import '../../http_errors.dart'; +import '../../json_lenient.dart'; +import '../../marianumconnect/queries/report_client_error/client_error_reporter.dart'; import '../nextcloud_ocs.dart'; import 'talk_error.dart'; @@ -73,12 +75,17 @@ abstract class TalkApi { throwForStatus(status, detail); } + final T assembled; try { - final assembled = await assembleAsync(data.body); - assembled?.headers = data.headers; - return assembled; + assembled = await assembleAsync(data.body); } catch (e) { throw ParseException(technicalDetails: 'Talk $endpoint assemble: $e'); } + assembled?.headers = data.headers; + ClientErrorReporter.reportDecodeWarnings('Talk $path', [ + ...?assembled?.parseWarnings, + ...drainDecodeWarnings(), + ]); + return assembled; } } diff --git a/lib/api/marianumcloud/talk/vote_poll/vote_poll_params.g.dart b/lib/api/marianumcloud/talk/vote_poll/vote_poll_params.g.dart index e97aa57..8905af1 100644 --- a/lib/api/marianumcloud/talk/vote_poll/vote_poll_params.g.dart +++ b/lib/api/marianumcloud/talk/vote_poll/vote_poll_params.g.dart @@ -7,11 +7,15 @@ part of 'vote_poll_params.dart'; // ************************************************************************** VotePollParams _$VotePollParamsFromJson(Map json) => - VotePollParams( - optionIds: (json['optionIds'] as List) - .map((e) => (e as num).toInt()) - .toList(), - ); + $checkedCreate('VotePollParams', json, ($checkedConvert) { + final val = VotePollParams( + optionIds: $checkedConvert( + 'optionIds', + (v) => (v as List).map((e) => (e as num).toInt()).toList(), + ), + ); + return val; + }); Map _$VotePollParamsToJson(VotePollParams instance) => {'optionIds': instance.optionIds}; diff --git a/lib/api/marianumcloud/webdav/queries/list_files/cacheable_file.g.dart b/lib/api/marianumcloud/webdav/queries/list_files/cacheable_file.g.dart index c123d6c..03837d9 100644 --- a/lib/api/marianumcloud/webdav/queries/list_files/cacheable_file.g.dart +++ b/lib/api/marianumcloud/webdav/queries/list_files/cacheable_file.g.dart @@ -7,23 +7,28 @@ part of 'cacheable_file.dart'; // ************************************************************************** CacheableFile _$CacheableFileFromJson(Map json) => - CacheableFile( - path: json['path'] as String, - isDirectory: json['isDirectory'] as bool, - name: json['name'] as String, - mimeType: json['mimeType'] as String?, - size: (json['size'] as num?)?.toInt(), - eTag: json['eTag'] as String?, - createdAt: json['createdAt'] == null - ? null - : DateTime.parse(json['createdAt'] as String), - modifiedAt: json['modifiedAt'] == null - ? null - : DateTime.parse(json['modifiedAt'] as String), - fileId: (json['fileId'] as num?)?.toInt(), - hasPreview: json['hasPreview'] as bool?, - isSharedWithMe: json['isSharedWithMe'] as bool?, - ); + $checkedCreate('CacheableFile', json, ($checkedConvert) { + final val = CacheableFile( + path: $checkedConvert('path', (v) => v as String), + isDirectory: $checkedConvert('isDirectory', (v) => v as bool), + name: $checkedConvert('name', (v) => v as String), + mimeType: $checkedConvert('mimeType', (v) => v as String?), + size: $checkedConvert('size', (v) => (v as num?)?.toInt()), + eTag: $checkedConvert('eTag', (v) => v as String?), + createdAt: $checkedConvert( + 'createdAt', + (v) => v == null ? null : DateTime.parse(v as String), + ), + modifiedAt: $checkedConvert( + 'modifiedAt', + (v) => v == null ? null : DateTime.parse(v as String), + ), + fileId: $checkedConvert('fileId', (v) => (v as num?)?.toInt()), + hasPreview: $checkedConvert('hasPreview', (v) => v as bool?), + isSharedWithMe: $checkedConvert('isSharedWithMe', (v) => v as bool?), + ); + return val; + }); Map _$CacheableFileToJson(CacheableFile instance) => { diff --git a/lib/api/marianumcloud/webdav/queries/list_files/list_files_params.g.dart b/lib/api/marianumcloud/webdav/queries/list_files/list_files_params.g.dart index 29f551f..2e9828b 100644 --- a/lib/api/marianumcloud/webdav/queries/list_files/list_files_params.g.dart +++ b/lib/api/marianumcloud/webdav/queries/list_files/list_files_params.g.dart @@ -7,7 +7,10 @@ part of 'list_files_params.dart'; // ************************************************************************** ListFilesParams _$ListFilesParamsFromJson(Map json) => - ListFilesParams(json['path'] as String); + $checkedCreate('ListFilesParams', json, ($checkedConvert) { + final val = ListFilesParams($checkedConvert('path', (v) => v as String)); + return val; + }); Map _$ListFilesParamsToJson(ListFilesParams instance) => {'path': instance.path}; diff --git a/lib/api/marianumcloud/webdav/queries/list_files/list_files_response.g.dart b/lib/api/marianumcloud/webdav/queries/list_files/list_files_response.g.dart index 09123cc..c915e84 100644 --- a/lib/api/marianumcloud/webdav/queries/list_files/list_files_response.g.dart +++ b/lib/api/marianumcloud/webdav/queries/list_files/list_files_response.g.dart @@ -7,14 +7,23 @@ part of 'list_files_response.dart'; // ************************************************************************** ListFilesResponse _$ListFilesResponseFromJson(Map json) => - ListFilesResponse( - (json['files'] as List) - .map((e) => CacheableFile.fromJson(e as Map)) - .toSet(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), + $checkedCreate('ListFilesResponse', json, ($checkedConvert) { + final val = ListFilesResponse( + $checkedConvert( + 'files', + (v) => (v as List) + .map((e) => CacheableFile.fromJson(e as Map)) + .toSet(), + ), ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; + }); Map _$ListFilesResponseToJson(ListFilesResponse instance) => { diff --git a/lib/api/marianumconnect/models/mc_holiday.g.dart b/lib/api/marianumconnect/models/mc_holiday.g.dart index 4d52890..1fe887c 100644 --- a/lib/api/marianumconnect/models/mc_holiday.g.dart +++ b/lib/api/marianumconnect/models/mc_holiday.g.dart @@ -6,12 +6,22 @@ part of 'mc_holiday.dart'; // JsonSerializableGenerator // ************************************************************************** -McHoliday _$McHolidayFromJson(Map json) => McHoliday( - shortName: json['shortName'] as String, - longName: json['longName'] as String, - startDate: McHoliday._dateFromJson(json['startDate'] as String), - endDate: McHoliday._dateFromJson(json['endDate'] as String), -); +McHoliday _$McHolidayFromJson(Map json) => + $checkedCreate('McHoliday', json, ($checkedConvert) { + final val = McHoliday( + shortName: $checkedConvert('shortName', (v) => v as String), + longName: $checkedConvert('longName', (v) => v as String), + startDate: $checkedConvert( + 'startDate', + (v) => McHoliday._dateFromJson(v as String), + ), + endDate: $checkedConvert( + 'endDate', + (v) => McHoliday._dateFromJson(v as String), + ), + ); + return val; + }); Map _$McHolidayToJson(McHoliday instance) => { 'shortName': instance.shortName, diff --git a/lib/api/marianumconnect/queries/absence/absence_prefill_response.g.dart b/lib/api/marianumconnect/queries/absence/absence_prefill_response.g.dart index e8f5425..14ef1dd 100644 --- a/lib/api/marianumconnect/queries/absence/absence_prefill_response.g.dart +++ b/lib/api/marianumconnect/queries/absence/absence_prefill_response.g.dart @@ -8,12 +8,15 @@ part of 'absence_prefill_response.dart'; AbsencePrefillResponse _$AbsencePrefillResponseFromJson( Map json, -) => AbsencePrefillResponse( - firstName: json['firstName'] as String? ?? '', - lastName: json['lastName'] as String? ?? '', - className: json['className'] as String? ?? '', - phone: json['phone'] as String? ?? '', -); +) => $checkedCreate('AbsencePrefillResponse', json, ($checkedConvert) { + final val = AbsencePrefillResponse( + firstName: $checkedConvert('firstName', (v) => v as String? ?? ''), + lastName: $checkedConvert('lastName', (v) => v as String? ?? ''), + className: $checkedConvert('className', (v) => v as String? ?? ''), + phone: $checkedConvert('phone', (v) => v as String? ?? ''), + ); + return val; +}); Map _$AbsencePrefillResponseToJson( AbsencePrefillResponse instance, diff --git a/lib/api/marianumconnect/queries/auth_login/auth_login_response.g.dart b/lib/api/marianumconnect/queries/auth_login/auth_login_response.g.dart index 591ccc4..e8aabbe 100644 --- a/lib/api/marianumconnect/queries/auth_login/auth_login_response.g.dart +++ b/lib/api/marianumconnect/queries/auth_login/auth_login_response.g.dart @@ -7,14 +7,17 @@ part of 'auth_login_response.dart'; // ************************************************************************** AuthLoginUser _$AuthLoginUserFromJson(Map json) => - AuthLoginUser( - id: json['id'] as String, - username: json['username'] as String, - firstName: json['firstName'] as String, - lastName: json['lastName'] as String, - userType: json['userType'] as String?, - className: json['className'] as String?, - ); + $checkedCreate('AuthLoginUser', json, ($checkedConvert) { + final val = AuthLoginUser( + id: $checkedConvert('id', (v) => v as String), + username: $checkedConvert('username', (v) => v as String), + firstName: $checkedConvert('firstName', (v) => v as String), + lastName: $checkedConvert('lastName', (v) => v as String), + userType: $checkedConvert('userType', (v) => v as String?), + className: $checkedConvert('className', (v) => v as String?), + ); + return val; + }); Map _$AuthLoginUserToJson(AuthLoginUser instance) => { @@ -27,12 +30,21 @@ Map _$AuthLoginUserToJson(AuthLoginUser instance) => }; AuthLoginResponse _$AuthLoginResponseFromJson(Map json) => - AuthLoginResponse( - token: json['token'] as String, - tokenId: json['tokenId'] as String, - expiresAt: AuthLoginResponse._expiresFromJson(json['expiresAt']), - user: AuthLoginUser.fromJson(json['user'] as Map), - ); + $checkedCreate('AuthLoginResponse', json, ($checkedConvert) { + final val = AuthLoginResponse( + token: $checkedConvert('token', (v) => v as String), + tokenId: $checkedConvert('tokenId', (v) => v as String), + expiresAt: $checkedConvert( + 'expiresAt', + (v) => AuthLoginResponse._expiresFromJson(v), + ), + user: $checkedConvert( + 'user', + (v) => AuthLoginUser.fromJson(v as Map), + ), + ); + return val; + }); Map _$AuthLoginResponseToJson(AuthLoginResponse instance) => { diff --git a/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.dart b/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.dart index 8e36f9e..43e8c4c 100644 --- a/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.dart +++ b/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.dart @@ -25,6 +25,7 @@ class GetBreakersResponse extends ApiResponse { @JsonSerializable() class BreakerRule { + @JsonKey(unknownEnumValue: BreakerArea.unknown) List areas; String message; @@ -69,4 +70,7 @@ enum BreakerArea { feedback, @JsonValue('MORE') more, + + /// An area the backend added after this build; no module maps to it. + unknown, } diff --git a/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.g.dart b/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.g.dart index 9dcea44..16055a3 100644 --- a/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.g.dart +++ b/lib/api/marianumconnect/queries/get_breakers/get_breakers_response.g.dart @@ -7,15 +7,25 @@ part of 'get_breakers_response.dart'; // ************************************************************************** GetBreakersResponse _$GetBreakersResponseFromJson(Map json) => - GetBreakersResponse( - (json['rules'] as List?) - ?.map((e) => BreakerRule.fromJson(e as Map)) - .toList() ?? - [], - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), + $checkedCreate('GetBreakersResponse', json, ($checkedConvert) { + final val = GetBreakersResponse( + $checkedConvert( + 'rules', + (v) => + (v as List?) + ?.map((e) => BreakerRule.fromJson(e as Map)) + .toList() ?? + [], + ), ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; + }); Map _$GetBreakersResponseToJson( GetBreakersResponse instance, @@ -24,13 +34,26 @@ Map _$GetBreakersResponseToJson( 'rules': instance.rules.map((e) => e.toJson()).toList(), }; -BreakerRule _$BreakerRuleFromJson(Map json) => BreakerRule( - (json['areas'] as List) - .map((e) => $enumDecode(_$BreakerAreaEnumMap, e)) - .toList(), - json['message'] as String, - (json['maxBuild'] as num?)?.toInt(), -); +BreakerRule _$BreakerRuleFromJson(Map json) => + $checkedCreate('BreakerRule', json, ($checkedConvert) { + final val = BreakerRule( + $checkedConvert( + 'areas', + (v) => (v as List) + .map( + (e) => $enumDecode( + _$BreakerAreaEnumMap, + e, + unknownValue: BreakerArea.unknown, + ), + ) + .toList(), + ), + $checkedConvert('message', (v) => v as String), + $checkedConvert('maxBuild', (v) => (v as num?)?.toInt()), + ); + return val; + }); Map _$BreakerRuleToJson(BreakerRule instance) => { @@ -52,4 +75,5 @@ const _$BreakerAreaEnumMap = { BreakerArea.dates: 'DATES', BreakerArea.feedback: 'FEEDBACK', BreakerArea.more: 'MORE', + BreakerArea.unknown: 'unknown', }; diff --git a/lib/api/marianumconnect/queries/get_capabilities/get_capabilities_response.g.dart b/lib/api/marianumconnect/queries/get_capabilities/get_capabilities_response.g.dart index 2f5ac3e..55689f6 100644 --- a/lib/api/marianumconnect/queries/get_capabilities/get_capabilities_response.g.dart +++ b/lib/api/marianumconnect/queries/get_capabilities/get_capabilities_response.g.dart @@ -8,13 +8,28 @@ part of 'get_capabilities_response.dart'; CapabilitiesResponse _$CapabilitiesResponseFromJson( Map json, -) => CapabilitiesResponse( - viewForeignTimetables: json['viewForeignTimetables'] as bool? ?? false, - pushNotifications: json['pushNotifications'] as bool? ?? false, - timetablePastDays: (json['timetablePastDays'] as num?)?.toInt(), - timetableFutureDays: (json['timetableFutureDays'] as num?)?.toInt(), - userType: json['userType'] as String?, -); +) => $checkedCreate('CapabilitiesResponse', json, ($checkedConvert) { + final val = CapabilitiesResponse( + viewForeignTimetables: $checkedConvert( + 'viewForeignTimetables', + (v) => v as bool? ?? false, + ), + pushNotifications: $checkedConvert( + 'pushNotifications', + (v) => v as bool? ?? false, + ), + timetablePastDays: $checkedConvert( + 'timetablePastDays', + (v) => (v as num?)?.toInt(), + ), + timetableFutureDays: $checkedConvert( + 'timetableFutureDays', + (v) => (v as num?)?.toInt(), + ), + userType: $checkedConvert('userType', (v) => v as String?), + ); + return val; +}); Map _$CapabilitiesResponseToJson( CapabilitiesResponse instance, diff --git a/lib/api/marianumconnect/queries/get_ticker/get_ticker_response.g.dart b/lib/api/marianumconnect/queries/get_ticker/get_ticker_response.g.dart index 57c74ae..00a2403 100644 --- a/lib/api/marianumconnect/queries/get_ticker/get_ticker_response.g.dart +++ b/lib/api/marianumconnect/queries/get_ticker/get_ticker_response.g.dart @@ -7,14 +7,20 @@ part of 'get_ticker_response.dart'; // ************************************************************************** TickerResponse _$TickerResponseFromJson(Map json) => - TickerResponse( - schemaVersion: (json['schemaVersion'] as num?)?.toInt() ?? 1, - available: json['available'] as bool? ?? false, - hash: json['hash'] as String?, - publishedAt: json['publishedAt'] as String?, - webUrl: json['webUrl'] as String? ?? '/ticker', - content: json['content'] as Map?, - ); + $checkedCreate('TickerResponse', json, ($checkedConvert) { + final val = TickerResponse( + schemaVersion: $checkedConvert( + 'schemaVersion', + (v) => (v as num?)?.toInt() ?? 1, + ), + available: $checkedConvert('available', (v) => v as bool? ?? false), + hash: $checkedConvert('hash', (v) => v as String?), + publishedAt: $checkedConvert('publishedAt', (v) => v as String?), + webUrl: $checkedConvert('webUrl', (v) => v as String? ?? '/ticker'), + content: $checkedConvert('content', (v) => v as Map?), + ); + return val; + }); Map _$TickerResponseToJson(TickerResponse instance) => { diff --git a/lib/api/marianumconnect/queries/get_ticker_nav/get_ticker_nav_response.g.dart b/lib/api/marianumconnect/queries/get_ticker_nav/get_ticker_nav_response.g.dart index 59247c2..77183f3 100644 --- a/lib/api/marianumconnect/queries/get_ticker_nav/get_ticker_nav_response.g.dart +++ b/lib/api/marianumconnect/queries/get_ticker_nav/get_ticker_nav_response.g.dart @@ -7,15 +7,26 @@ part of 'get_ticker_nav_response.dart'; // ************************************************************************** TickerNavResponse _$TickerNavResponseFromJson(Map json) => - TickerNavResponse( - schemaVersion: (json['schemaVersion'] as num?)?.toInt() ?? 1, - navHash: json['navHash'] as String? ?? '', - sections: - (json['sections'] as List?) - ?.map((e) => TickerNavSection.fromJson(e as Map)) - .toList() ?? - [], - ); + $checkedCreate('TickerNavResponse', json, ($checkedConvert) { + final val = TickerNavResponse( + schemaVersion: $checkedConvert( + 'schemaVersion', + (v) => (v as num?)?.toInt() ?? 1, + ), + navHash: $checkedConvert('navHash', (v) => v as String? ?? ''), + sections: $checkedConvert( + 'sections', + (v) => + (v as List?) + ?.map( + (e) => TickerNavSection.fromJson(e as Map), + ) + .toList() ?? + [], + ), + ); + return val; + }); Map _$TickerNavResponseToJson(TickerNavResponse instance) => { @@ -25,14 +36,22 @@ Map _$TickerNavResponseToJson(TickerNavResponse instance) => }; TickerNavSection _$TickerNavSectionFromJson(Map json) => - TickerNavSection( - title: json['title'] as String? ?? '', - pages: - (json['pages'] as List?) - ?.map((e) => TickerNavPage.fromJson(e as Map)) - .toList() ?? - [], - ); + $checkedCreate('TickerNavSection', json, ($checkedConvert) { + final val = TickerNavSection( + title: $checkedConvert('title', (v) => v as String? ?? ''), + pages: $checkedConvert( + 'pages', + (v) => + (v as List?) + ?.map( + (e) => TickerNavPage.fromJson(e as Map), + ) + .toList() ?? + [], + ), + ); + return val; + }); Map _$TickerNavSectionToJson(TickerNavSection instance) => { @@ -41,15 +60,21 @@ Map _$TickerNavSectionToJson(TickerNavSection instance) => }; TickerNavPage _$TickerNavPageFromJson(Map json) => - TickerNavPage( - title: json['title'] as String? ?? '', - slug: json['slug'] as String? ?? '', - kind: json['kind'] as String? ?? 'CONTENT', - hash: json['hash'] as String?, - externalUrl: json['externalUrl'] as String?, - externalUrlNewTab: json['externalUrlNewTab'] as bool?, - fileUrl: json['fileUrl'] as String?, - ); + $checkedCreate('TickerNavPage', json, ($checkedConvert) { + final val = TickerNavPage( + title: $checkedConvert('title', (v) => v as String? ?? ''), + slug: $checkedConvert('slug', (v) => v as String? ?? ''), + kind: $checkedConvert('kind', (v) => v as String? ?? 'CONTENT'), + hash: $checkedConvert('hash', (v) => v as String?), + externalUrl: $checkedConvert('externalUrl', (v) => v as String?), + externalUrlNewTab: $checkedConvert( + 'externalUrlNewTab', + (v) => v as bool?, + ), + fileUrl: $checkedConvert('fileUrl', (v) => v as String?), + ); + return val; + }); Map _$TickerNavPageToJson(TickerNavPage instance) => { diff --git a/lib/api/marianumconnect/queries/get_ticker_page/get_ticker_page_response.g.dart b/lib/api/marianumconnect/queries/get_ticker_page/get_ticker_page_response.g.dart index 52e4c40..e60b15d 100644 --- a/lib/api/marianumconnect/queries/get_ticker_page/get_ticker_page_response.g.dart +++ b/lib/api/marianumconnect/queries/get_ticker_page/get_ticker_page_response.g.dart @@ -7,22 +7,31 @@ part of 'get_ticker_page_response.dart'; // ************************************************************************** TickerPageResponse _$TickerPageResponseFromJson(Map json) => - TickerPageResponse( - schemaVersion: (json['schemaVersion'] as num?)?.toInt() ?? 1, - slug: json['slug'] as String?, - title: json['title'] as String?, - kind: json['kind'] as String? ?? 'CONTENT', - content: json['content'] as Map?, - externalUrl: json['externalUrl'] as String?, - externalUrlNewTab: json['externalUrlNewTab'] as bool?, - fileUrl: json['fileUrl'] as String?, - contentType: json['contentType'] as String?, - filename: json['filename'] as String?, - hash: json['hash'] as String?, - webUrl: json['webUrl'] as String?, - publishedAt: json['publishedAt'] as String?, - fileFetchedAt: json['fileFetchedAt'] as String?, - ); + $checkedCreate('TickerPageResponse', json, ($checkedConvert) { + final val = TickerPageResponse( + schemaVersion: $checkedConvert( + 'schemaVersion', + (v) => (v as num?)?.toInt() ?? 1, + ), + slug: $checkedConvert('slug', (v) => v as String?), + title: $checkedConvert('title', (v) => v as String?), + kind: $checkedConvert('kind', (v) => v as String? ?? 'CONTENT'), + content: $checkedConvert('content', (v) => v as Map?), + externalUrl: $checkedConvert('externalUrl', (v) => v as String?), + externalUrlNewTab: $checkedConvert( + 'externalUrlNewTab', + (v) => v as bool?, + ), + fileUrl: $checkedConvert('fileUrl', (v) => v as String?), + contentType: $checkedConvert('contentType', (v) => v as String?), + filename: $checkedConvert('filename', (v) => v as String?), + hash: $checkedConvert('hash', (v) => v as String?), + webUrl: $checkedConvert('webUrl', (v) => v as String?), + publishedAt: $checkedConvert('publishedAt', (v) => v as String?), + fileFetchedAt: $checkedConvert('fileFetchedAt', (v) => v as String?), + ); + return val; + }); Map _$TickerPageResponseToJson(TickerPageResponse instance) => { diff --git a/lib/api/marianumconnect/queries/report_client_error/client_error_reporter.dart b/lib/api/marianumconnect/queries/report_client_error/client_error_reporter.dart index 45bc93d..55f458f 100644 --- a/lib/api/marianumconnect/queries/report_client_error/client_error_reporter.dart +++ b/lib/api/marianumconnect/queries/report_client_error/client_error_reporter.dart @@ -36,6 +36,15 @@ class ClientErrorReporter { ); } + /// Server entries the decoder could not map (see `decodeListLenient`): the + /// app keeps working without them, the report says which field drifted. + static void reportDecodeWarnings(String context, Iterable warnings) { + for (final warning in warnings) { + log('$context: skipped entry: $warning'); + _report(errorType: 'decode', message: warning, context: context); + } + } + static void _report({ required String errorType, required String message, diff --git a/lib/api/marianumconnect/queries/timetable_get_classes/timetable_get_classes_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_classes/timetable_get_classes_response.g.dart index 86f23c2..0a0c045 100644 --- a/lib/api/marianumconnect/queries/timetable_get_classes/timetable_get_classes_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_classes/timetable_get_classes_response.g.dart @@ -7,11 +7,14 @@ part of 'timetable_get_classes_response.dart'; // ************************************************************************** McTimetableClass _$McTimetableClassFromJson(Map json) => - McTimetableClass( - id: (json['id'] as num).toInt(), - shortName: json['shortName'] as String, - longName: json['longName'] as String, - ); + $checkedCreate('McTimetableClass', json, ($checkedConvert) { + final val = McTimetableClass( + id: $checkedConvert('id', (v) => (v as num).toInt()), + shortName: $checkedConvert('shortName', (v) => v as String), + longName: $checkedConvert('longName', (v) => v as String), + ); + return val; + }); Map _$McTimetableClassToJson(McTimetableClass instance) => { @@ -22,15 +25,23 @@ Map _$McTimetableClassToJson(McTimetableClass instance) => TimetableGetClassesResponse _$TimetableGetClassesResponseFromJson( Map json, -) => - TimetableGetClassesResponse( - result: (json['result'] as List) - .map((e) => McTimetableClass.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetClassesResponse', json, ($checkedConvert) { + final val = TimetableGetClassesResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map((e) => McTimetableClass.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetClassesResponseToJson( TimetableGetClassesResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart index 6d094a4..a2c3085 100644 --- a/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart @@ -8,15 +8,23 @@ part of 'timetable_get_holidays_response.dart'; TimetableGetHolidaysResponse _$TimetableGetHolidaysResponseFromJson( Map json, -) => - TimetableGetHolidaysResponse( - result: (json['result'] as List) - .map((e) => McHoliday.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetHolidaysResponse', json, ($checkedConvert) { + final val = TimetableGetHolidaysResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map((e) => McHoliday.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetHolidaysResponseToJson( TimetableGetHolidaysResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms_response.g.dart index 3c0de3c..1026409 100644 --- a/lib/api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms_response.g.dart @@ -6,11 +6,15 @@ part of 'timetable_get_rooms_response.dart'; // JsonSerializableGenerator // ************************************************************************** -McRoom _$McRoomFromJson(Map json) => McRoom( - id: (json['id'] as num).toInt(), - shortName: json['shortName'] as String, - longName: json['longName'] as String, -); +McRoom _$McRoomFromJson(Map json) => + $checkedCreate('McRoom', json, ($checkedConvert) { + final val = McRoom( + id: $checkedConvert('id', (v) => (v as num).toInt()), + shortName: $checkedConvert('shortName', (v) => v as String), + longName: $checkedConvert('longName', (v) => v as String), + ); + return val; + }); Map _$McRoomToJson(McRoom instance) => { 'id': instance.id, @@ -20,15 +24,23 @@ Map _$McRoomToJson(McRoom instance) => { TimetableGetRoomsResponse _$TimetableGetRoomsResponseFromJson( Map json, -) => - TimetableGetRoomsResponse( - result: (json['result'] as List) - .map((e) => McRoom.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetRoomsResponse', json, ($checkedConvert) { + final val = TimetableGetRoomsResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map((e) => McRoom.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetRoomsResponseToJson( TimetableGetRoomsResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_schoolyear/timetable_get_schoolyear_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_schoolyear/timetable_get_schoolyear_response.g.dart index 4046682..cb2137a 100644 --- a/lib/api/marianumconnect/queries/timetable_get_schoolyear/timetable_get_schoolyear_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_schoolyear/timetable_get_schoolyear_response.g.dart @@ -8,20 +8,27 @@ part of 'timetable_get_schoolyear_response.dart'; TimetableGetSchoolyearResponse _$TimetableGetSchoolyearResponseFromJson( Map json, -) => - TimetableGetSchoolyearResponse( - id: (json['id'] as num).toInt(), - name: json['name'] as String, - startDate: TimetableGetSchoolyearResponse._dateFromJson( - json['startDate'] as String, - ), - endDate: TimetableGetSchoolyearResponse._dateFromJson( - json['endDate'] as String, - ), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetSchoolyearResponse', json, ($checkedConvert) { + final val = TimetableGetSchoolyearResponse( + id: $checkedConvert('id', (v) => (v as num).toInt()), + name: $checkedConvert('name', (v) => v as String), + startDate: $checkedConvert( + 'startDate', + (v) => TimetableGetSchoolyearResponse._dateFromJson(v as String), + ), + endDate: $checkedConvert( + 'endDate', + (v) => TimetableGetSchoolyearResponse._dateFromJson(v as String), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetSchoolyearResponseToJson( TimetableGetSchoolyearResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_students/timetable_get_students_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_students/timetable_get_students_response.g.dart index 8588de3..b28d30c 100644 --- a/lib/api/marianumconnect/queries/timetable_get_students/timetable_get_students_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_students/timetable_get_students_response.g.dart @@ -7,12 +7,15 @@ part of 'timetable_get_students_response.dart'; // ************************************************************************** McTimetableStudent _$McTimetableStudentFromJson(Map json) => - McTimetableStudent( - id: (json['id'] as num).toInt(), - firstName: json['firstName'] as String, - lastName: json['lastName'] as String, - displayName: json['displayName'] as String, - ); + $checkedCreate('McTimetableStudent', json, ($checkedConvert) { + final val = McTimetableStudent( + id: $checkedConvert('id', (v) => (v as num).toInt()), + firstName: $checkedConvert('firstName', (v) => v as String), + lastName: $checkedConvert('lastName', (v) => v as String), + displayName: $checkedConvert('displayName', (v) => v as String), + ); + return val; + }); Map _$McTimetableStudentToJson(McTimetableStudent instance) => { @@ -24,15 +27,23 @@ Map _$McTimetableStudentToJson(McTimetableStudent instance) => TimetableGetStudentsResponse _$TimetableGetStudentsResponseFromJson( Map json, -) => - TimetableGetStudentsResponse( - result: (json['result'] as List) - .map((e) => McTimetableStudent.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetStudentsResponse', json, ($checkedConvert) { + final val = TimetableGetStudentsResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map((e) => McTimetableStudent.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetStudentsResponseToJson( TimetableGetStudentsResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.g.dart index d7672af..635c1ba 100644 --- a/lib/api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.g.dart @@ -6,12 +6,16 @@ part of 'timetable_get_subjects_response.dart'; // JsonSerializableGenerator // ************************************************************************** -McSubject _$McSubjectFromJson(Map json) => McSubject( - id: (json['id'] as num).toInt(), - shortName: json['shortName'] as String, - longName: json['longName'] as String, - color: json['color'] as String?, -); +McSubject _$McSubjectFromJson(Map json) => + $checkedCreate('McSubject', json, ($checkedConvert) { + final val = McSubject( + id: $checkedConvert('id', (v) => (v as num).toInt()), + shortName: $checkedConvert('shortName', (v) => v as String), + longName: $checkedConvert('longName', (v) => v as String), + color: $checkedConvert('color', (v) => v as String?), + ); + return val; + }); Map _$McSubjectToJson(McSubject instance) => { 'id': instance.id, @@ -22,15 +26,23 @@ Map _$McSubjectToJson(McSubject instance) => { TimetableGetSubjectsResponse _$TimetableGetSubjectsResponseFromJson( Map json, -) => - TimetableGetSubjectsResponse( - result: (json['result'] as List) - .map((e) => McSubject.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetSubjectsResponse', json, ($checkedConvert) { + final val = TimetableGetSubjectsResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map((e) => McSubject.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetSubjectsResponseToJson( TimetableGetSubjectsResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_teachers/timetable_get_teachers_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_teachers/timetable_get_teachers_response.g.dart index ca72e62..5fdfd36 100644 --- a/lib/api/marianumconnect/queries/timetable_get_teachers/timetable_get_teachers_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_teachers/timetable_get_teachers_response.g.dart @@ -8,11 +8,14 @@ part of 'timetable_get_teachers_response.dart'; McTimetableTeacherElement _$McTimetableTeacherElementFromJson( Map json, -) => McTimetableTeacherElement( - id: (json['id'] as num).toInt(), - shortName: json['shortName'] as String, - displayName: json['displayName'] as String, -); +) => $checkedCreate('McTimetableTeacherElement', json, ($checkedConvert) { + final val = McTimetableTeacherElement( + id: $checkedConvert('id', (v) => (v as num).toInt()), + shortName: $checkedConvert('shortName', (v) => v as String), + displayName: $checkedConvert('displayName', (v) => v as String), + ); + return val; +}); Map _$McTimetableTeacherElementToJson( McTimetableTeacherElement instance, @@ -24,18 +27,26 @@ Map _$McTimetableTeacherElementToJson( TimetableGetTeachersResponse _$TimetableGetTeachersResponseFromJson( Map json, -) => - TimetableGetTeachersResponse( - result: (json['result'] as List) - .map( - (e) => - McTimetableTeacherElement.fromJson(e as Map), - ) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetTeachersResponse', json, ($checkedConvert) { + final val = TimetableGetTeachersResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map( + (e) => + McTimetableTeacherElement.fromJson(e as Map), + ) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetTeachersResponseToJson( TimetableGetTeachersResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.g.dart index ff96032..a22695c 100644 --- a/lib/api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.g.dart @@ -7,12 +7,24 @@ part of 'timetable_get_timegrid_response.dart'; // ************************************************************************** McTimegridUnit _$McTimegridUnitFromJson(Map json) => - McTimegridUnit( - dayOfWeek: _dayFromJson(json['dayOfWeek'] as String), - label: json['label'] as String, - startTime: McTimegridUnit._timeFromJson(json['startTime'] as String), - endTime: McTimegridUnit._timeFromJson(json['endTime'] as String), - ); + $checkedCreate('McTimegridUnit', json, ($checkedConvert) { + final val = McTimegridUnit( + dayOfWeek: $checkedConvert( + 'dayOfWeek', + (v) => _dayFromJson(v as String), + ), + label: $checkedConvert('label', (v) => v as String), + startTime: $checkedConvert( + 'startTime', + (v) => McTimegridUnit._timeFromJson(v as String), + ), + endTime: $checkedConvert( + 'endTime', + (v) => McTimegridUnit._timeFromJson(v as String), + ), + ); + return val; + }); Map _$McTimegridUnitToJson(McTimegridUnit instance) => { @@ -24,15 +36,23 @@ Map _$McTimegridUnitToJson(McTimegridUnit instance) => TimetableGetTimegridResponse _$TimetableGetTimegridResponseFromJson( Map json, -) => - TimetableGetTimegridResponse( - result: (json['result'] as List) - .map((e) => McTimegridUnit.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetTimegridResponse', json, ($checkedConvert) { + final val = TimetableGetTimegridResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map((e) => McTimegridUnit.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetTimegridResponseToJson( TimetableGetTimegridResponse instance, diff --git a/lib/api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.g.dart index d32bd40..650a5d5 100644 --- a/lib/api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.g.dart @@ -7,14 +7,23 @@ part of 'timetable_get_week_response.dart'; // ************************************************************************** McTimetableTeacher _$McTimetableTeacherFromJson(Map json) => - McTimetableTeacher( - shortName: json['shortName'] as String, - displayName: json['displayName'] as String, - originalShortName: json['originalShortName'] as String?, - originalDisplayName: json['originalDisplayName'] as String?, - id: (json['id'] as num?)?.toInt(), - originalId: (json['originalId'] as num?)?.toInt(), - ); + $checkedCreate('McTimetableTeacher', json, ($checkedConvert) { + final val = McTimetableTeacher( + shortName: $checkedConvert('shortName', (v) => v as String), + displayName: $checkedConvert('displayName', (v) => v as String), + originalShortName: $checkedConvert( + 'originalShortName', + (v) => v as String?, + ), + originalDisplayName: $checkedConvert( + 'originalDisplayName', + (v) => v as String?, + ), + id: $checkedConvert('id', (v) => (v as num?)?.toInt()), + originalId: $checkedConvert('originalId', (v) => (v as num?)?.toInt()), + ); + return val; + }); Map _$McTimetableTeacherToJson(McTimetableTeacher instance) => { @@ -26,31 +35,53 @@ Map _$McTimetableTeacherToJson(McTimetableTeacher instance) => 'originalId': instance.originalId, }; -McTimetableEntry _$McTimetableEntryFromJson(Map json) => - McTimetableEntry( - id: (json['id'] as num).toInt(), - date: McTimetableEntry._dateFromJson(json['date'] as String), - startTime: McTimetableEntry._timeFromJson(json['startTime'] as String), - endTime: McTimetableEntry._timeFromJson(json['endTime'] as String), - subjects: (json['subjects'] as List) - .map((e) => e as String) - .toList(), - teachers: (json['teachers'] as List) +McTimetableEntry _$McTimetableEntryFromJson( + Map json, +) => $checkedCreate('McTimetableEntry', json, ($checkedConvert) { + final val = McTimetableEntry( + id: $checkedConvert('id', (v) => (v as num).toInt()), + date: $checkedConvert( + 'date', + (v) => McTimetableEntry._dateFromJson(v as String), + ), + startTime: $checkedConvert( + 'startTime', + (v) => McTimetableEntry._timeFromJson(v as String), + ), + endTime: $checkedConvert( + 'endTime', + (v) => McTimetableEntry._timeFromJson(v as String), + ), + subjects: $checkedConvert( + 'subjects', + (v) => (v as List).map((e) => e as String).toList(), + ), + teachers: $checkedConvert( + 'teachers', + (v) => (v as List) .map((e) => McTimetableTeacher.fromJson(e as Map)) .toList(), - rooms: (json['rooms'] as List).map((e) => e as String).toList(), - classNames: (json['classNames'] as List) - .map((e) => e as String) - .toList(), - lessonType: json['lessonType'] as String, - status: json['status'] as String, - substitutionText: json['substitutionText'] as String?, - lessonText: json['lessonText'] as String?, - infoText: json['infoText'] as String?, - classIds: (json['classIds'] as List?) - ?.map((e) => (e as num).toInt()) - .toList(), - ); + ), + rooms: $checkedConvert( + 'rooms', + (v) => (v as List).map((e) => e as String).toList(), + ), + classNames: $checkedConvert( + 'classNames', + (v) => (v as List).map((e) => e as String).toList(), + ), + lessonType: $checkedConvert('lessonType', (v) => v as String), + status: $checkedConvert('status', (v) => v as String), + substitutionText: $checkedConvert('substitutionText', (v) => v as String?), + lessonText: $checkedConvert('lessonText', (v) => v as String?), + infoText: $checkedConvert('infoText', (v) => v as String?), + classIds: $checkedConvert( + 'classIds', + (v) => (v as List?)?.map((e) => (e as num).toInt()).toList(), + ), + ); + return val; +}); Map _$McTimetableEntryToJson(McTimetableEntry instance) => { @@ -72,17 +103,31 @@ Map _$McTimetableEntryToJson(McTimetableEntry instance) => TimetableGetWeekResponse _$TimetableGetWeekResponseFromJson( Map json, -) => - TimetableGetWeekResponse( - from: McTimetableEntry._dateFromJson(json['from'] as String), - until: McTimetableEntry._dateFromJson(json['until'] as String), - entries: (json['entries'] as List) - .map((e) => McTimetableEntry.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('TimetableGetWeekResponse', json, ($checkedConvert) { + final val = TimetableGetWeekResponse( + from: $checkedConvert( + 'from', + (v) => McTimetableEntry._dateFromJson(v as String), + ), + until: $checkedConvert( + 'until', + (v) => McTimetableEntry._dateFromJson(v as String), + ), + entries: $checkedConvert( + 'entries', + (v) => (v as List) + .map((e) => McTimetableEntry.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$TimetableGetWeekResponseToJson( TimetableGetWeekResponse instance, diff --git a/lib/api/marianumconnect/queries/user_search/user_search_response.g.dart b/lib/api/marianumconnect/queries/user_search/user_search_response.g.dart index d9f7e46..d12a916 100644 --- a/lib/api/marianumconnect/queries/user_search/user_search_response.g.dart +++ b/lib/api/marianumconnect/queries/user_search/user_search_response.g.dart @@ -7,13 +7,16 @@ part of 'user_search_response.dart'; // ************************************************************************** McUserSearchResult _$McUserSearchResultFromJson(Map json) => - McUserSearchResult( - username: json['username'] as String, - firstName: json['firstName'] as String, - lastName: json['lastName'] as String, - userType: json['userType'] as String, - className: json['className'] as String?, - ); + $checkedCreate('McUserSearchResult', json, ($checkedConvert) { + final val = McUserSearchResult( + username: $checkedConvert('username', (v) => v as String), + firstName: $checkedConvert('firstName', (v) => v as String), + lastName: $checkedConvert('lastName', (v) => v as String), + userType: $checkedConvert('userType', (v) => v as String), + className: $checkedConvert('className', (v) => v as String?), + ); + return val; + }); Map _$McUserSearchResultToJson(McUserSearchResult instance) => { @@ -25,14 +28,25 @@ Map _$McUserSearchResultToJson(McUserSearchResult instance) => }; UserSearchResponse _$UserSearchResponseFromJson(Map json) => - UserSearchResponse( - result: (json['result'] as List) - .map((e) => McUserSearchResult.fromJson(e as Map)) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), + $checkedCreate('UserSearchResponse', json, ($checkedConvert) { + final val = UserSearchResponse( + result: $checkedConvert( + 'result', + (v) => (v as List) + .map( + (e) => McUserSearchResult.fromJson(e as Map), + ) + .toList(), + ), ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; + }); Map _$UserSearchResponseToJson(UserSearchResponse instance) => { diff --git a/lib/api/mhsl/custom_timetable_event/custom_timetable_event.g.dart b/lib/api/mhsl/custom_timetable_event/custom_timetable_event.g.dart index bb4fffa..af4d87a 100644 --- a/lib/api/mhsl/custom_timetable_event/custom_timetable_event.g.dart +++ b/lib/api/mhsl/custom_timetable_event/custom_timetable_event.g.dart @@ -8,18 +8,33 @@ part of 'custom_timetable_event.dart'; CustomTimetableEvent _$CustomTimetableEventFromJson( Map json, -) => CustomTimetableEvent( - id: json['id'] as String, - title: json['title'] as String, - description: json['description'] as String, - startDate: CustomTimetableEvent._dateFromJson(json['startDate'] as String), - endDate: CustomTimetableEvent._dateFromJson(json['endDate'] as String), - color: json['color'] as String?, - rrule: json['rrule'] as String, - skipHolidays: json['skipHolidays'] as bool? ?? false, - createdAt: CustomTimetableEvent._dateFromJson(json['createdAt'] as String), - updatedAt: CustomTimetableEvent._dateFromJson(json['updatedAt'] as String), -); +) => $checkedCreate('CustomTimetableEvent', json, ($checkedConvert) { + final val = CustomTimetableEvent( + id: $checkedConvert('id', (v) => v as String), + title: $checkedConvert('title', (v) => v as String), + description: $checkedConvert('description', (v) => v as String), + startDate: $checkedConvert( + 'startDate', + (v) => CustomTimetableEvent._dateFromJson(v as String), + ), + endDate: $checkedConvert( + 'endDate', + (v) => CustomTimetableEvent._dateFromJson(v as String), + ), + color: $checkedConvert('color', (v) => v as String?), + rrule: $checkedConvert('rrule', (v) => v as String), + skipHolidays: $checkedConvert('skipHolidays', (v) => v as bool? ?? false), + createdAt: $checkedConvert( + 'createdAt', + (v) => CustomTimetableEvent._dateFromJson(v as String), + ), + updatedAt: $checkedConvert( + 'updatedAt', + (v) => CustomTimetableEvent._dateFromJson(v as String), + ), + ); + return val; +}); Map _$CustomTimetableEventToJson( CustomTimetableEvent instance, diff --git a/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_params.g.dart b/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_params.g.dart index 01fc5a5..e19648d 100644 --- a/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_params.g.dart +++ b/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_params.g.dart @@ -8,7 +8,12 @@ part of 'get_custom_timetable_event_params.dart'; GetCustomTimetableEventParams _$GetCustomTimetableEventParamsFromJson( Map json, -) => GetCustomTimetableEventParams(json['user'] as String); +) => $checkedCreate('GetCustomTimetableEventParams', json, ($checkedConvert) { + final val = GetCustomTimetableEventParams( + $checkedConvert('user', (v) => v as String), + ); + return val; +}); Map _$GetCustomTimetableEventParamsToJson( GetCustomTimetableEventParams instance, diff --git a/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_response.g.dart b/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_response.g.dart index 5bed445..3f7e510 100644 --- a/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_response.g.dart +++ b/lib/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_response.g.dart @@ -8,17 +8,23 @@ part of 'get_custom_timetable_event_response.dart'; GetCustomTimetableEventResponse _$GetCustomTimetableEventResponseFromJson( Map json, -) => - GetCustomTimetableEventResponse( - (json['events'] as List) - .map( - (e) => CustomTimetableEvent.fromJson(e as Map), - ) - .toList(), - ) - ..headers = (json['headers'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ); +) => $checkedCreate('GetCustomTimetableEventResponse', json, ($checkedConvert) { + final val = GetCustomTimetableEventResponse( + $checkedConvert( + 'events', + (v) => (v as List) + .map((e) => CustomTimetableEvent.fromJson(e as Map)) + .toList(), + ), + ); + $checkedConvert( + 'headers', + (v) => val.headers = (v as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); + return val; +}); Map _$GetCustomTimetableEventResponseToJson( GetCustomTimetableEventResponse instance, diff --git a/lib/api/mhsl/custom_timetable_event/remove/remove_custom_timetable_event_params.g.dart b/lib/api/mhsl/custom_timetable_event/remove/remove_custom_timetable_event_params.g.dart index 4e85a31..d26aa24 100644 --- a/lib/api/mhsl/custom_timetable_event/remove/remove_custom_timetable_event_params.g.dart +++ b/lib/api/mhsl/custom_timetable_event/remove/remove_custom_timetable_event_params.g.dart @@ -8,7 +8,13 @@ part of 'remove_custom_timetable_event_params.dart'; RemoveCustomTimetableEventParams _$RemoveCustomTimetableEventParamsFromJson( Map json, -) => RemoveCustomTimetableEventParams(json['id'] as String); +) => + $checkedCreate('RemoveCustomTimetableEventParams', json, ($checkedConvert) { + final val = RemoveCustomTimetableEventParams( + $checkedConvert('id', (v) => v as String), + ); + return val; + }); Map _$RemoveCustomTimetableEventParamsToJson( RemoveCustomTimetableEventParams instance, diff --git a/lib/routing/app_routes.dart b/lib/routing/app_routes.dart index aa9ddb6..499d91b 100644 --- a/lib/routing/app_routes.dart +++ b/lib/routing/app_routes.dart @@ -407,7 +407,7 @@ class AppRoutes { // would race the fresh one and could regress the server cursor. context.read().markRoomAsRead( room.token, - room.lastMessage.id, + room.lastMessage?.id ?? room.lastReadMessage, ); NotificationTasks.clearNotificationsForChat(room.token); TalkNavigator.pushSplitView( diff --git a/lib/state/app/infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_save_context.g.dart b/lib/state/app/infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_save_context.g.dart index 99c92e8..cb6574e 100644 --- a/lib/state/app/infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_save_context.g.dart +++ b/lib/state/app/infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_save_context.g.dart @@ -7,7 +7,12 @@ part of 'loadable_save_context.dart'; // ************************************************************************** _LoadableSaveContext _$LoadableSaveContextFromJson(Map json) => - _LoadableSaveContext(timestamp: (json['timestamp'] as num).toInt()); + $checkedCreate('_LoadableSaveContext', json, ($checkedConvert) { + final val = _LoadableSaveContext( + timestamp: $checkedConvert('timestamp', (v) => (v as num).toInt()), + ); + return val; + }); Map _$LoadableSaveContextToJson( _LoadableSaveContext instance, diff --git a/lib/state/app/modules/breaker/bloc/breaker_state.g.dart b/lib/state/app/modules/breaker/bloc/breaker_state.g.dart index d47f3e3..7079f7d 100644 --- a/lib/state/app/modules/breaker/bloc/breaker_state.g.dart +++ b/lib/state/app/modules/breaker/bloc/breaker_state.g.dart @@ -7,13 +7,17 @@ part of 'breaker_state.dart'; // ************************************************************************** _BreakerState _$BreakerStateFromJson(Map json) => - _BreakerState( - response: json['response'] == null - ? null - : GetBreakersResponse.fromJson( - json['response'] as Map, - ), - ); + $checkedCreate('_BreakerState', json, ($checkedConvert) { + final val = _BreakerState( + response: $checkedConvert( + 'response', + (v) => v == null + ? null + : GetBreakersResponse.fromJson(v as Map), + ), + ); + return val; + }); Map _$BreakerStateToJson(_BreakerState instance) => {'response': instance.response}; diff --git a/lib/state/app/modules/capabilities/bloc/capabilities_state.g.dart b/lib/state/app/modules/capabilities/bloc/capabilities_state.g.dart index c50fed3..420dda3 100644 --- a/lib/state/app/modules/capabilities/bloc/capabilities_state.g.dart +++ b/lib/state/app/modules/capabilities/bloc/capabilities_state.g.dart @@ -7,14 +7,29 @@ part of 'capabilities_state.dart'; // ************************************************************************** _CapabilitiesState _$CapabilitiesStateFromJson(Map json) => - _CapabilitiesState( - viewForeignTimetables: json['viewForeignTimetables'] as bool? ?? false, - pushNotifications: json['pushNotifications'] as bool? ?? false, - timetablePastDays: (json['timetablePastDays'] as num?)?.toInt(), - timetableFutureDays: (json['timetableFutureDays'] as num?)?.toInt(), - userType: json['userType'] as String?, - loaded: json['loaded'] as bool? ?? false, - ); + $checkedCreate('_CapabilitiesState', json, ($checkedConvert) { + final val = _CapabilitiesState( + viewForeignTimetables: $checkedConvert( + 'viewForeignTimetables', + (v) => v as bool? ?? false, + ), + pushNotifications: $checkedConvert( + 'pushNotifications', + (v) => v as bool? ?? false, + ), + timetablePastDays: $checkedConvert( + 'timetablePastDays', + (v) => (v as num?)?.toInt(), + ), + timetableFutureDays: $checkedConvert( + 'timetableFutureDays', + (v) => (v as num?)?.toInt(), + ), + userType: $checkedConvert('userType', (v) => v as String?), + loaded: $checkedConvert('loaded', (v) => v as bool? ?? false), + ); + return val; + }); Map _$CapabilitiesStateToJson(_CapabilitiesState instance) => { diff --git a/lib/state/app/modules/chat/bloc/chat_bloc.dart b/lib/state/app/modules/chat/bloc/chat_bloc.dart index 83b2bc8..e2b9a1a 100644 --- a/lib/state/app/modules/chat/bloc/chat_bloc.dart +++ b/lib/state/app/modules/chat/bloc/chat_bloc.dart @@ -411,6 +411,7 @@ class ChatBloc case GetRoomResponseObjectMessageType.deletedComment: case GetRoomResponseObjectMessageType.system: case GetRoomResponseObjectMessageType.command: + case GetRoomResponseObjectMessageType.unknown: break; } } diff --git a/lib/state/app/modules/chat/bloc/chat_state.g.dart b/lib/state/app/modules/chat/bloc/chat_state.g.dart index abf6a7c..c3d21c4 100644 --- a/lib/state/app/modules/chat/bloc/chat_state.g.dart +++ b/lib/state/app/modules/chat/bloc/chat_state.g.dart @@ -6,14 +6,30 @@ part of 'chat_state.dart'; // JsonSerializableGenerator // ************************************************************************** -_ChatState _$ChatStateFromJson(Map json) => _ChatState( - currentToken: json['currentToken'] as String? ?? '', - chatResponse: json['chatResponse'] == null - ? null - : GetChatResponse.fromJson(json['chatResponse'] as Map), - referenceMessageId: (json['referenceMessageId'] as num?)?.toInt(), - hasMoreOld: json['hasMoreOld'] as bool? ?? true, - isLoadingOlder: json['isLoadingOlder'] as bool? ?? false, +_ChatState _$ChatStateFromJson(Map json) => $checkedCreate( + '_ChatState', + json, + ($checkedConvert) { + final val = _ChatState( + currentToken: $checkedConvert('currentToken', (v) => v as String? ?? ''), + chatResponse: $checkedConvert( + 'chatResponse', + (v) => v == null + ? null + : GetChatResponse.fromJson(v as Map), + ), + referenceMessageId: $checkedConvert( + 'referenceMessageId', + (v) => (v as num?)?.toInt(), + ), + hasMoreOld: $checkedConvert('hasMoreOld', (v) => v as bool? ?? true), + isLoadingOlder: $checkedConvert( + 'isLoadingOlder', + (v) => v as bool? ?? false, + ), + ); + return val; + }, ); Map _$ChatStateToJson(_ChatState instance) => diff --git a/lib/state/app/modules/chat_list/bloc/chat_list_bloc.dart b/lib/state/app/modules/chat_list/bloc/chat_list_bloc.dart index 54681e2..e9b475a 100644 --- a/lib/state/app/modules/chat_list/bloc/chat_list_bloc.dart +++ b/lib/state/app/modules/chat_list/bloc/chat_list_bloc.dart @@ -187,16 +187,18 @@ class ChatListBloc /// Clears unread too — long-poll only feeds this in for an actively-open chat. void applyIncomingMessage(String token, GetChatResponseObject message) { _mutateRoom(token, (r) { - final wasRead = - r.unreadMessages == 0 && r.lastReadMessage >= message.id; - final hasNewer = r.lastMessage.id >= message.id; + final wasRead = r.unreadMessages == 0 && r.lastReadMessage >= message.id; + final lastId = r.lastMessage?.id ?? 0; + final hasNewer = lastId >= message.id; if (wasRead && hasNewer) return false; r.unreadMessages = 0; r.unreadMention = false; r.unreadMentionDirect = false; if (message.id > r.lastReadMessage) r.lastReadMessage = message.id; - if (message.id > r.lastMessage.id) r.lastMessage = message; - if (message.timestamp > r.lastActivity) r.lastActivity = message.timestamp; + if (message.id > lastId) r.lastMessage = message; + if (message.timestamp > r.lastActivity) { + r.lastActivity = message.timestamp; + } return true; }); } diff --git a/lib/state/app/modules/chat_list/bloc/chat_list_state.g.dart b/lib/state/app/modules/chat_list/bloc/chat_list_state.g.dart index 1a28f8c..1385cac 100644 --- a/lib/state/app/modules/chat_list/bloc/chat_list_state.g.dart +++ b/lib/state/app/modules/chat_list/bloc/chat_list_state.g.dart @@ -7,11 +7,17 @@ part of 'chat_list_state.dart'; // ************************************************************************** _ChatListState _$ChatListStateFromJson(Map json) => - _ChatListState( - rooms: json['rooms'] == null - ? null - : GetRoomResponse.fromJson(json['rooms'] as Map), - ); + $checkedCreate('_ChatListState', json, ($checkedConvert) { + final val = _ChatListState( + rooms: $checkedConvert( + 'rooms', + (v) => v == null + ? null + : GetRoomResponse.fromJson(v as Map), + ), + ); + return val; + }); Map _$ChatListStateToJson(_ChatListState instance) => {'rooms': instance.rooms}; diff --git a/lib/state/app/modules/files/bloc/files_state.g.dart b/lib/state/app/modules/files/bloc/files_state.g.dart index 7d5d345..7d355d6 100644 --- a/lib/state/app/modules/files/bloc/files_state.g.dart +++ b/lib/state/app/modules/files/bloc/files_state.g.dart @@ -6,16 +6,24 @@ part of 'files_state.dart'; // JsonSerializableGenerator // ************************************************************************** -_FilesState _$FilesStateFromJson(Map json) => _FilesState( - currentPath: - (json['currentPath'] as List?) - ?.map((e) => e as String) - .toList() ?? - const [], - listing: json['listing'] == null - ? null - : ListFilesResponse.fromJson(json['listing'] as Map), -); +_FilesState _$FilesStateFromJson(Map json) => + $checkedCreate('_FilesState', json, ($checkedConvert) { + final val = _FilesState( + currentPath: $checkedConvert( + 'currentPath', + (v) => + (v as List?)?.map((e) => e as String).toList() ?? + const [], + ), + listing: $checkedConvert( + 'listing', + (v) => v == null + ? null + : ListFilesResponse.fromJson(v as Map), + ), + ); + return val; + }); Map _$FilesStateToJson(_FilesState instance) => { diff --git a/lib/state/app/modules/grade_averages/bloc/grade_averages_state.g.dart b/lib/state/app/modules/grade_averages/bloc/grade_averages_state.g.dart index 9373ca9..e5dab37 100644 --- a/lib/state/app/modules/grade_averages/bloc/grade_averages_state.g.dart +++ b/lib/state/app/modules/grade_averages/bloc/grade_averages_state.g.dart @@ -7,15 +7,19 @@ part of 'grade_averages_state.dart'; // ************************************************************************** _GradeAveragesState _$GradeAveragesStateFromJson(Map json) => - _GradeAveragesState( - gradingSystem: $enumDecode( - _$GradeAveragesGradingSystemEnumMap, - json['gradingSystem'], - ), - grades: (json['grades'] as List) - .map((e) => (e as num).toInt()) - .toList(), - ); + $checkedCreate('_GradeAveragesState', json, ($checkedConvert) { + final val = _GradeAveragesState( + gradingSystem: $checkedConvert( + 'gradingSystem', + (v) => $enumDecode(_$GradeAveragesGradingSystemEnumMap, v), + ), + grades: $checkedConvert( + 'grades', + (v) => (v as List).map((e) => (e as num).toInt()).toList(), + ), + ); + return val; + }); Map _$GradeAveragesStateToJson( _GradeAveragesState instance, diff --git a/lib/state/app/modules/holidays/bloc/holidays_state.g.dart b/lib/state/app/modules/holidays/bloc/holidays_state.g.dart index 4173e20..2446ef6 100644 --- a/lib/state/app/modules/holidays/bloc/holidays_state.g.dart +++ b/lib/state/app/modules/holidays/bloc/holidays_state.g.dart @@ -7,13 +7,19 @@ part of 'holidays_state.dart'; // ************************************************************************** _HolidaysState _$HolidaysStateFromJson(Map json) => - _HolidaysState( - showPastHolidays: json['showPastHolidays'] as bool, - showDisclaimer: json['showDisclaimer'] as bool, - holidays: (json['holidays'] as List) - .map((e) => McHoliday.fromJson(e as Map)) - .toList(), - ); + $checkedCreate('_HolidaysState', json, ($checkedConvert) { + final val = _HolidaysState( + showPastHolidays: $checkedConvert('showPastHolidays', (v) => v as bool), + showDisclaimer: $checkedConvert('showDisclaimer', (v) => v as bool), + holidays: $checkedConvert( + 'holidays', + (v) => (v as List) + .map((e) => McHoliday.fromJson(e as Map)) + .toList(), + ), + ); + return val; + }); Map _$HolidaysStateToJson(_HolidaysState instance) => { diff --git a/lib/state/app/modules/marianum_dates/bloc/marianum_dates_state.g.dart b/lib/state/app/modules/marianum_dates/bloc/marianum_dates_state.g.dart index e923443..5636183 100644 --- a/lib/state/app/modules/marianum_dates/bloc/marianum_dates_state.g.dart +++ b/lib/state/app/modules/marianum_dates/bloc/marianum_dates_state.g.dart @@ -7,12 +7,18 @@ part of 'marianum_dates_state.dart'; // ************************************************************************** _MarianumDatesState _$MarianumDatesStateFromJson(Map json) => - _MarianumDatesState( - showPastEvents: json['showPastEvents'] as bool, - events: (json['events'] as List) - .map((e) => MarianumDate.fromJson(e as Map)) - .toList(), - ); + $checkedCreate('_MarianumDatesState', json, ($checkedConvert) { + final val = _MarianumDatesState( + showPastEvents: $checkedConvert('showPastEvents', (v) => v as bool), + events: $checkedConvert( + 'events', + (v) => (v as List) + .map((e) => MarianumDate.fromJson(e as Map)) + .toList(), + ), + ); + return val; + }); Map _$MarianumDatesStateToJson(_MarianumDatesState instance) => { @@ -21,14 +27,17 @@ Map _$MarianumDatesStateToJson(_MarianumDatesState instance) => }; _MarianumDate _$MarianumDateFromJson(Map json) => - _MarianumDate( - uid: json['uid'] as String, - title: json['title'] as String, - description: json['description'] as String?, - start: DateTime.parse(json['start'] as String), - end: DateTime.parse(json['end'] as String), - isAllDay: json['isAllDay'] as bool, - ); + $checkedCreate('_MarianumDate', json, ($checkedConvert) { + final val = _MarianumDate( + uid: $checkedConvert('uid', (v) => v as String), + title: $checkedConvert('title', (v) => v as String), + description: $checkedConvert('description', (v) => v as String?), + start: $checkedConvert('start', (v) => DateTime.parse(v as String)), + end: $checkedConvert('end', (v) => DateTime.parse(v as String)), + isAllDay: $checkedConvert('isAllDay', (v) => v as bool), + ); + return val; + }); Map _$MarianumDateToJson(_MarianumDate instance) => { diff --git a/lib/state/app/modules/marianum_message/bloc/marianum_message_state.g.dart b/lib/state/app/modules/marianum_message/bloc/marianum_message_state.g.dart index e6c21ec..0df04bc 100644 --- a/lib/state/app/modules/marianum_message/bloc/marianum_message_state.g.dart +++ b/lib/state/app/modules/marianum_message/bloc/marianum_message_state.g.dart @@ -8,36 +8,49 @@ part of 'marianum_message_state.dart'; _MarianumMessageState _$MarianumMessageStateFromJson( Map json, -) => _MarianumMessageState( - messageList: MarianumMessageList.fromJson( - json['messageList'] as Map, - ), -); +) => $checkedCreate('_MarianumMessageState', json, ($checkedConvert) { + final val = _MarianumMessageState( + messageList: $checkedConvert( + 'messageList', + (v) => MarianumMessageList.fromJson(v as Map), + ), + ); + return val; +}); Map _$MarianumMessageStateToJson( _MarianumMessageState instance, ) => {'messageList': instance.messageList}; _MarianumMessageList _$MarianumMessageListFromJson(Map json) => - _MarianumMessageList( - base: json['base'] as String, - messages: (json['messages'] as List) - .map((e) => MarianumMessage.fromJson(e as Map)) - .toList(), - ); + $checkedCreate('_MarianumMessageList', json, ($checkedConvert) { + final val = _MarianumMessageList( + base: $checkedConvert('base', (v) => v as String), + messages: $checkedConvert( + 'messages', + (v) => (v as List) + .map((e) => MarianumMessage.fromJson(e as Map)) + .toList(), + ), + ); + return val; + }); Map _$MarianumMessageListToJson( _MarianumMessageList instance, ) => {'base': instance.base, 'messages': instance.messages}; _MarianumMessage _$MarianumMessageFromJson(Map json) => - _MarianumMessage( - id: json['id'] as String? ?? '', - name: json['name'] as String, - date: json['date'] as String, - description: json['description'] as String? ?? '', - url: json['url'] as String, - ); + $checkedCreate('_MarianumMessage', json, ($checkedConvert) { + final val = _MarianumMessage( + id: $checkedConvert('id', (v) => v as String? ?? ''), + name: $checkedConvert('name', (v) => v as String), + date: $checkedConvert('date', (v) => v as String), + description: $checkedConvert('description', (v) => v as String? ?? ''), + url: $checkedConvert('url', (v) => v as String), + ); + return val; + }); Map _$MarianumMessageToJson(_MarianumMessage instance) => { diff --git a/lib/state/app/modules/nextcloud_capabilities/bloc/nextcloud_capabilities_state.g.dart b/lib/state/app/modules/nextcloud_capabilities/bloc/nextcloud_capabilities_state.g.dart index 98aed49..8b386cc 100644 --- a/lib/state/app/modules/nextcloud_capabilities/bloc/nextcloud_capabilities_state.g.dart +++ b/lib/state/app/modules/nextcloud_capabilities/bloc/nextcloud_capabilities_state.g.dart @@ -8,24 +8,56 @@ part of 'nextcloud_capabilities_state.dart'; _NextcloudCapabilitiesState _$NextcloudCapabilitiesStateFromJson( Map json, -) => _NextcloudCapabilitiesState( - apiEnabled: json['apiEnabled'] as bool? ?? false, - publicEnabled: json['publicEnabled'] as bool? ?? false, - publicMultipleLinks: json['publicMultipleLinks'] as bool? ?? false, - publicUploadEnabled: json['publicUploadEnabled'] as bool? ?? false, - publicPasswordEnforced: json['publicPasswordEnforced'] as bool? ?? false, - publicExpireEnabled: json['publicExpireEnabled'] as bool? ?? false, - publicExpireDays: (json['publicExpireDays'] as num?)?.toInt(), - publicExpireEnforced: json['publicExpireEnforced'] as bool? ?? false, - groupEnabled: json['groupEnabled'] as bool? ?? false, - resharing: json['resharing'] as bool? ?? false, - passwordMinLength: (json['passwordMinLength'] as num?)?.toInt(), - passwordEnforceUpperLower: - json['passwordEnforceUpperLower'] as bool? ?? false, - passwordEnforceNumeric: json['passwordEnforceNumeric'] as bool? ?? false, - passwordEnforceSpecial: json['passwordEnforceSpecial'] as bool? ?? false, - loaded: json['loaded'] as bool? ?? false, -); +) => $checkedCreate('_NextcloudCapabilitiesState', json, ($checkedConvert) { + final val = _NextcloudCapabilitiesState( + apiEnabled: $checkedConvert('apiEnabled', (v) => v as bool? ?? false), + publicEnabled: $checkedConvert('publicEnabled', (v) => v as bool? ?? false), + publicMultipleLinks: $checkedConvert( + 'publicMultipleLinks', + (v) => v as bool? ?? false, + ), + publicUploadEnabled: $checkedConvert( + 'publicUploadEnabled', + (v) => v as bool? ?? false, + ), + publicPasswordEnforced: $checkedConvert( + 'publicPasswordEnforced', + (v) => v as bool? ?? false, + ), + publicExpireEnabled: $checkedConvert( + 'publicExpireEnabled', + (v) => v as bool? ?? false, + ), + publicExpireDays: $checkedConvert( + 'publicExpireDays', + (v) => (v as num?)?.toInt(), + ), + publicExpireEnforced: $checkedConvert( + 'publicExpireEnforced', + (v) => v as bool? ?? false, + ), + groupEnabled: $checkedConvert('groupEnabled', (v) => v as bool? ?? false), + resharing: $checkedConvert('resharing', (v) => v as bool? ?? false), + passwordMinLength: $checkedConvert( + 'passwordMinLength', + (v) => (v as num?)?.toInt(), + ), + passwordEnforceUpperLower: $checkedConvert( + 'passwordEnforceUpperLower', + (v) => v as bool? ?? false, + ), + passwordEnforceNumeric: $checkedConvert( + 'passwordEnforceNumeric', + (v) => v as bool? ?? false, + ), + passwordEnforceSpecial: $checkedConvert( + 'passwordEnforceSpecial', + (v) => v as bool? ?? false, + ), + loaded: $checkedConvert('loaded', (v) => v as bool? ?? false), + ); + return val; +}); Map _$NextcloudCapabilitiesStateToJson( _NextcloudCapabilitiesState instance, diff --git a/lib/state/app/modules/ticker/bloc/ticker_page_state.g.dart b/lib/state/app/modules/ticker/bloc/ticker_page_state.g.dart index 59bf6e5..4480c03 100644 --- a/lib/state/app/modules/ticker/bloc/ticker_page_state.g.dart +++ b/lib/state/app/modules/ticker/bloc/ticker_page_state.g.dart @@ -7,11 +7,17 @@ part of 'ticker_page_state.dart'; // ************************************************************************** _TickerPageState _$TickerPageStateFromJson(Map json) => - _TickerPageState( - page: json['page'] == null - ? null - : TickerPageResponse.fromJson(json['page'] as Map), - ); + $checkedCreate('_TickerPageState', json, ($checkedConvert) { + final val = _TickerPageState( + page: $checkedConvert( + 'page', + (v) => v == null + ? null + : TickerPageResponse.fromJson(v as Map), + ), + ); + return val; + }); Map _$TickerPageStateToJson(_TickerPageState instance) => {'page': instance.page}; diff --git a/lib/state/app/modules/ticker/bloc/ticker_state.g.dart b/lib/state/app/modules/ticker/bloc/ticker_state.g.dart index 252682b..2b80f5f 100644 --- a/lib/state/app/modules/ticker/bloc/ticker_state.g.dart +++ b/lib/state/app/modules/ticker/bloc/ticker_state.g.dart @@ -6,15 +6,25 @@ part of 'ticker_state.dart'; // JsonSerializableGenerator // ************************************************************************** -_TickerState _$TickerStateFromJson(Map json) => _TickerState( - ticker: json['ticker'] == null - ? null - : TickerResponse.fromJson(json['ticker'] as Map), - nav: json['nav'] == null - ? null - : TickerNavResponse.fromJson(json['nav'] as Map), - selectedSlug: json['selectedSlug'] as String?, -); +_TickerState _$TickerStateFromJson(Map json) => + $checkedCreate('_TickerState', json, ($checkedConvert) { + final val = _TickerState( + ticker: $checkedConvert( + 'ticker', + (v) => v == null + ? null + : TickerResponse.fromJson(v as Map), + ), + nav: $checkedConvert( + 'nav', + (v) => v == null + ? null + : TickerNavResponse.fromJson(v as Map), + ), + selectedSlug: $checkedConvert('selectedSlug', (v) => v as String?), + ); + return val; + }); Map _$TickerStateToJson(_TickerState instance) => { diff --git a/lib/state/app/modules/timetable/bloc/timetable_state.g.dart b/lib/state/app/modules/timetable/bloc/timetable_state.g.dart index a9daee3..d4bf905 100644 --- a/lib/state/app/modules/timetable/bloc/timetable_state.g.dart +++ b/lib/state/app/modules/timetable/bloc/timetable_state.g.dart @@ -6,56 +6,74 @@ part of 'timetable_state.dart'; // JsonSerializableGenerator // ************************************************************************** -_TimetableState _$TimetableStateFromJson(Map json) => - _TimetableState( - weekCache: - (json['weekCache'] as Map?)?.map( +_TimetableState _$TimetableStateFromJson( + Map json, +) => $checkedCreate('_TimetableState', json, ($checkedConvert) { + final val = _TimetableState( + weekCache: $checkedConvert( + 'weekCache', + (v) => + (v as Map?)?.map( (k, e) => MapEntry( k, TimetableGetWeekResponse.fromJson(e as Map), ), ) ?? const {}, - rooms: json['rooms'] == null + ), + rooms: $checkedConvert( + 'rooms', + (v) => v == null ? null - : TimetableGetRoomsResponse.fromJson( - json['rooms'] as Map, - ), - subjects: json['subjects'] == null + : TimetableGetRoomsResponse.fromJson(v as Map), + ), + subjects: $checkedConvert( + 'subjects', + (v) => v == null ? null - : TimetableGetSubjectsResponse.fromJson( - json['subjects'] as Map, - ), - schoolHolidays: json['schoolHolidays'] == null + : TimetableGetSubjectsResponse.fromJson(v as Map), + ), + schoolHolidays: $checkedConvert( + 'schoolHolidays', + (v) => v == null ? null - : TimetableGetHolidaysResponse.fromJson( - json['schoolHolidays'] as Map, - ), - schoolyear: json['schoolyear'] == null + : TimetableGetHolidaysResponse.fromJson(v as Map), + ), + schoolyear: $checkedConvert( + 'schoolyear', + (v) => v == null ? null - : TimetableGetSchoolyearResponse.fromJson( - json['schoolyear'] as Map, - ), - timegrid: json['timegrid'] == null + : TimetableGetSchoolyearResponse.fromJson(v as Map), + ), + timegrid: $checkedConvert( + 'timegrid', + (v) => v == null ? null - : TimetableGetTimegridResponse.fromJson( - json['timegrid'] as Map, - ), - customEvents: json['customEvents'] == null + : TimetableGetTimegridResponse.fromJson(v as Map), + ), + customEvents: $checkedConvert( + 'customEvents', + (v) => v == null ? null - : GetCustomTimetableEventResponse.fromJson( - json['customEvents'] as Map, - ), - startDate: DateTime.parse(json['startDate'] as String), - endDate: DateTime.parse(json['endDate'] as String), - dataVersion: (json['dataVersion'] as num?)?.toInt() ?? 0, - accessibleStartDate: json['accessibleStartDate'] == null - ? null - : DateTime.parse(json['accessibleStartDate'] as String), - accessibleEndDate: json['accessibleEndDate'] == null - ? null - : DateTime.parse(json['accessibleEndDate'] as String), - ); + : GetCustomTimetableEventResponse.fromJson(v as Map), + ), + startDate: $checkedConvert('startDate', (v) => DateTime.parse(v as String)), + endDate: $checkedConvert('endDate', (v) => DateTime.parse(v as String)), + dataVersion: $checkedConvert( + 'dataVersion', + (v) => (v as num?)?.toInt() ?? 0, + ), + accessibleStartDate: $checkedConvert( + 'accessibleStartDate', + (v) => v == null ? null : DateTime.parse(v as String), + ), + accessibleEndDate: $checkedConvert( + 'accessibleEndDate', + (v) => v == null ? null : DateTime.parse(v as String), + ), + ); + return val; +}); Map _$TimetableStateToJson(_TimetableState instance) => { diff --git a/lib/storage/chat_background_settings.g.dart b/lib/storage/chat_background_settings.g.dart index db468fb..4be1c6b 100644 --- a/lib/storage/chat_background_settings.g.dart +++ b/lib/storage/chat_background_settings.g.dart @@ -8,14 +8,23 @@ part of 'chat_background_settings.dart'; ChatBackgroundSettings _$ChatBackgroundSettingsFromJson( Map json, -) => ChatBackgroundSettings( - type: $enumDecode(_$ChatBackgroundTypeEnumMap, json['type']), - fit: $enumDecode(_$ChatBackgroundFitEnumMap, json['fit']), - colorValue: (json['colorValue'] as num?)?.toInt(), - imageVersion: (json['imageVersion'] as num).toInt(), - dim: (json['dim'] as num).toDouble(), - blur: (json['blur'] as num).toDouble(), -); +) => $checkedCreate('ChatBackgroundSettings', json, ($checkedConvert) { + final val = ChatBackgroundSettings( + type: $checkedConvert( + 'type', + (v) => $enumDecode(_$ChatBackgroundTypeEnumMap, v), + ), + fit: $checkedConvert( + 'fit', + (v) => $enumDecode(_$ChatBackgroundFitEnumMap, v), + ), + colorValue: $checkedConvert('colorValue', (v) => (v as num?)?.toInt()), + imageVersion: $checkedConvert('imageVersion', (v) => (v as num).toInt()), + dim: $checkedConvert('dim', (v) => (v as num).toDouble()), + blur: $checkedConvert('blur', (v) => (v as num).toDouble()), + ); + return val; +}); Map _$ChatBackgroundSettingsToJson( ChatBackgroundSettings instance, diff --git a/lib/storage/dev_tools_settings.g.dart b/lib/storage/dev_tools_settings.g.dart index f3f4972..0c2d997 100644 --- a/lib/storage/dev_tools_settings.g.dart +++ b/lib/storage/dev_tools_settings.g.dart @@ -7,23 +7,49 @@ part of 'dev_tools_settings.dart'; // ************************************************************************** DevToolsSettings _$DevToolsSettingsFromJson(Map json) => - DevToolsSettings( - showPerformanceOverlay: json['showPerformanceOverlay'] as bool, - showFrameStats: json['showFrameStats'] as bool? ?? false, - showMemoryStats: json['showMemoryStats'] as bool? ?? false, - showSemanticsDebugger: json['showSemanticsDebugger'] as bool? ?? false, - slowAnimations: json['slowAnimations'] as bool? ?? false, - textScaleOverride: (json['textScaleOverride'] as num?)?.toDouble() ?? 0, - marianumConnectEndpoint: - $enumDecodeNullable( - _$MarianumConnectEndpointEnumMap, - json['marianumConnectEndpoint'], - ) ?? - MarianumConnectEndpoint.live, - marianumConnectCustomUrl: - json['marianumConnectCustomUrl'] as String? ?? '', - emergencyNoticeUrl: json['emergencyNoticeUrl'] as String? ?? '', - ); + $checkedCreate('DevToolsSettings', json, ($checkedConvert) { + final val = DevToolsSettings( + showPerformanceOverlay: $checkedConvert( + 'showPerformanceOverlay', + (v) => v as bool, + ), + showFrameStats: $checkedConvert( + 'showFrameStats', + (v) => v as bool? ?? false, + ), + showMemoryStats: $checkedConvert( + 'showMemoryStats', + (v) => v as bool? ?? false, + ), + showSemanticsDebugger: $checkedConvert( + 'showSemanticsDebugger', + (v) => v as bool? ?? false, + ), + slowAnimations: $checkedConvert( + 'slowAnimations', + (v) => v as bool? ?? false, + ), + textScaleOverride: $checkedConvert( + 'textScaleOverride', + (v) => (v as num?)?.toDouble() ?? 0, + ), + marianumConnectEndpoint: $checkedConvert( + 'marianumConnectEndpoint', + (v) => + $enumDecodeNullable(_$MarianumConnectEndpointEnumMap, v) ?? + MarianumConnectEndpoint.live, + ), + marianumConnectCustomUrl: $checkedConvert( + 'marianumConnectCustomUrl', + (v) => v as String? ?? '', + ), + emergencyNoticeUrl: $checkedConvert( + 'emergencyNoticeUrl', + (v) => v as String? ?? '', + ), + ); + return val; + }); Map _$DevToolsSettingsToJson(DevToolsSettings instance) => { diff --git a/lib/storage/file_settings.g.dart b/lib/storage/file_settings.g.dart index 38d4aa5..d810277 100644 --- a/lib/storage/file_settings.g.dart +++ b/lib/storage/file_settings.g.dart @@ -6,11 +6,18 @@ part of 'file_settings.dart'; // JsonSerializableGenerator // ************************************************************************** -FileSettings _$FileSettingsFromJson(Map json) => FileSettings( - sortFoldersToTop: json['sortFoldersToTop'] as bool, - ascending: json['ascending'] as bool, - sortBy: $enumDecode(_$SortOptionEnumMap, json['sortBy']), -); +FileSettings _$FileSettingsFromJson(Map json) => + $checkedCreate('FileSettings', json, ($checkedConvert) { + final val = FileSettings( + sortFoldersToTop: $checkedConvert('sortFoldersToTop', (v) => v as bool), + ascending: $checkedConvert('ascending', (v) => v as bool), + sortBy: $checkedConvert( + 'sortBy', + (v) => $enumDecode(_$SortOptionEnumMap, v), + ), + ); + return val; + }); Map _$FileSettingsToJson(FileSettings instance) => { diff --git a/lib/storage/file_view_settings.g.dart b/lib/storage/file_view_settings.g.dart index 44d2e30..2e673e6 100644 --- a/lib/storage/file_view_settings.g.dart +++ b/lib/storage/file_view_settings.g.dart @@ -7,9 +7,15 @@ part of 'file_view_settings.dart'; // ************************************************************************** FileViewSettings _$FileViewSettingsFromJson(Map json) => - FileViewSettings( - alwaysOpenExternally: json['alwaysOpenExternally'] as bool, - ); + $checkedCreate('FileViewSettings', json, ($checkedConvert) { + final val = FileViewSettings( + alwaysOpenExternally: $checkedConvert( + 'alwaysOpenExternally', + (v) => v as bool, + ), + ); + return val; + }); Map _$FileViewSettingsToJson(FileViewSettings instance) => {'alwaysOpenExternally': instance.alwaysOpenExternally}; diff --git a/lib/storage/haptic_settings.g.dart b/lib/storage/haptic_settings.g.dart index db1f522..486ce23 100644 --- a/lib/storage/haptic_settings.g.dart +++ b/lib/storage/haptic_settings.g.dart @@ -7,7 +7,15 @@ part of 'haptic_settings.dart'; // ************************************************************************** HapticSettings _$HapticSettingsFromJson(Map json) => - HapticSettings(level: $enumDecode(_$HapticLevelEnumMap, json['level'])); + $checkedCreate('HapticSettings', json, ($checkedConvert) { + final val = HapticSettings( + level: $checkedConvert( + 'level', + (v) => $enumDecode(_$HapticLevelEnumMap, v), + ), + ); + return val; + }); Map _$HapticSettingsToJson(HapticSettings instance) => {'level': _$HapticLevelEnumMap[instance.level]!}; diff --git a/lib/storage/holidays_settings.g.dart b/lib/storage/holidays_settings.g.dart index 976acb6..16e849e 100644 --- a/lib/storage/holidays_settings.g.dart +++ b/lib/storage/holidays_settings.g.dart @@ -7,10 +7,16 @@ part of 'holidays_settings.dart'; // ************************************************************************** HolidaysSettings _$HolidaysSettingsFromJson(Map json) => - HolidaysSettings( - dismissedDisclaimer: json['dismissedDisclaimer'] as bool, - showPastEvents: json['showPastEvents'] as bool, - ); + $checkedCreate('HolidaysSettings', json, ($checkedConvert) { + final val = HolidaysSettings( + dismissedDisclaimer: $checkedConvert( + 'dismissedDisclaimer', + (v) => v as bool, + ), + showPastEvents: $checkedConvert('showPastEvents', (v) => v as bool), + ); + return val; + }); Map _$HolidaysSettingsToJson(HolidaysSettings instance) => { diff --git a/lib/storage/modules_settings.g.dart b/lib/storage/modules_settings.g.dart index fe9b776..db07192 100644 --- a/lib/storage/modules_settings.g.dart +++ b/lib/storage/modules_settings.g.dart @@ -7,17 +7,35 @@ part of 'modules_settings.dart'; // ************************************************************************** ModulesSettings _$ModulesSettingsFromJson(Map json) => - ModulesSettings( - moduleOrder: (json['moduleOrder'] as List) - .map((e) => $enumDecode(_$ModulesEnumMap, e)) - .toList(), - hiddenModules: (json['hiddenModules'] as List) - .map((e) => $enumDecode(_$ModulesEnumMap, e)) - .toList(), - autoFillBottomBar: json['autoFillBottomBar'] as bool? ?? true, - fixedBottomBarSlots: (json['fixedBottomBarSlots'] as num?)?.toInt() ?? 3, - teacherDefaultsApplied: json['teacherDefaultsApplied'] as bool? ?? false, - ); + $checkedCreate('ModulesSettings', json, ($checkedConvert) { + final val = ModulesSettings( + moduleOrder: $checkedConvert( + 'moduleOrder', + (v) => (v as List) + .map((e) => $enumDecode(_$ModulesEnumMap, e)) + .toList(), + ), + hiddenModules: $checkedConvert( + 'hiddenModules', + (v) => (v as List) + .map((e) => $enumDecode(_$ModulesEnumMap, e)) + .toList(), + ), + autoFillBottomBar: $checkedConvert( + 'autoFillBottomBar', + (v) => v as bool? ?? true, + ), + fixedBottomBarSlots: $checkedConvert( + 'fixedBottomBarSlots', + (v) => (v as num?)?.toInt() ?? 3, + ), + teacherDefaultsApplied: $checkedConvert( + 'teacherDefaultsApplied', + (v) => v as bool? ?? false, + ), + ); + return val; + }); Map _$ModulesSettingsToJson( ModulesSettings instance, diff --git a/lib/storage/notification_settings.g.dart b/lib/storage/notification_settings.g.dart index e468d36..4cfce38 100644 --- a/lib/storage/notification_settings.g.dart +++ b/lib/storage/notification_settings.g.dart @@ -8,11 +8,16 @@ part of 'notification_settings.dart'; NotificationSettings _$NotificationSettingsFromJson( Map json, -) => NotificationSettings( - enabled: json['enabled'] as bool? ?? true, - talkPermissionPromptShown: - json['talkPermissionPromptShown'] as bool? ?? false, -); +) => $checkedCreate('NotificationSettings', json, ($checkedConvert) { + final val = NotificationSettings( + enabled: $checkedConvert('enabled', (v) => v as bool? ?? true), + talkPermissionPromptShown: $checkedConvert( + 'talkPermissionPromptShown', + (v) => v as bool? ?? false, + ), + ); + return val; +}); Map _$NotificationSettingsToJson( NotificationSettings instance, diff --git a/lib/storage/settings.g.dart b/lib/storage/settings.g.dart index 76c739f..d692eca 100644 --- a/lib/storage/settings.g.dart +++ b/lib/storage/settings.g.dart @@ -6,43 +6,61 @@ part of 'settings.dart'; // JsonSerializableGenerator // ************************************************************************** -Settings _$SettingsFromJson(Map json) => Settings( - appTheme: Settings._themeFromJson(json['appTheme'] as String), - devToolsEnabled: json['devToolsEnabled'] as bool, - modulesSettings: ModulesSettings.fromJson( - json['modulesSettings'] as Map, - ), - timetableSettings: TimetableSettings.fromJson( - json['timetableSettings'] as Map, - ), - timetableFavoritesSettings: TimetableFavoritesSettings.fromJson( - json['timetableFavoritesSettings'] as Map, - ), - talkSettings: TalkSettings.fromJson( - json['talkSettings'] as Map, - ), - chatBackgroundSettings: ChatBackgroundSettings.fromJson( - json['chatBackgroundSettings'] as Map, - ), - fileSettings: FileSettings.fromJson( - json['fileSettings'] as Map, - ), - holidaysSettings: HolidaysSettings.fromJson( - json['holidaysSettings'] as Map, - ), - fileViewSettings: FileViewSettings.fromJson( - json['fileViewSettings'] as Map, - ), - notificationSettings: NotificationSettings.fromJson( - json['notificationSettings'] as Map, - ), - devToolsSettings: DevToolsSettings.fromJson( - json['devToolsSettings'] as Map, - ), - hapticSettings: HapticSettings.fromJson( - json['hapticSettings'] as Map, - ), -); +Settings _$SettingsFromJson(Map json) => + $checkedCreate('Settings', json, ($checkedConvert) { + final val = Settings( + appTheme: $checkedConvert( + 'appTheme', + (v) => Settings._themeFromJson(v as String), + ), + devToolsEnabled: $checkedConvert('devToolsEnabled', (v) => v as bool), + modulesSettings: $checkedConvert( + 'modulesSettings', + (v) => ModulesSettings.fromJson(v as Map), + ), + timetableSettings: $checkedConvert( + 'timetableSettings', + (v) => TimetableSettings.fromJson(v as Map), + ), + timetableFavoritesSettings: $checkedConvert( + 'timetableFavoritesSettings', + (v) => TimetableFavoritesSettings.fromJson(v as Map), + ), + talkSettings: $checkedConvert( + 'talkSettings', + (v) => TalkSettings.fromJson(v as Map), + ), + chatBackgroundSettings: $checkedConvert( + 'chatBackgroundSettings', + (v) => ChatBackgroundSettings.fromJson(v as Map), + ), + fileSettings: $checkedConvert( + 'fileSettings', + (v) => FileSettings.fromJson(v as Map), + ), + holidaysSettings: $checkedConvert( + 'holidaysSettings', + (v) => HolidaysSettings.fromJson(v as Map), + ), + fileViewSettings: $checkedConvert( + 'fileViewSettings', + (v) => FileViewSettings.fromJson(v as Map), + ), + notificationSettings: $checkedConvert( + 'notificationSettings', + (v) => NotificationSettings.fromJson(v as Map), + ), + devToolsSettings: $checkedConvert( + 'devToolsSettings', + (v) => DevToolsSettings.fromJson(v as Map), + ), + hapticSettings: $checkedConvert( + 'hapticSettings', + (v) => HapticSettings.fromJson(v as Map), + ), + ); + return val; + }); Map _$SettingsToJson(Settings instance) => { 'appTheme': Settings._themeToJson(instance.appTheme), diff --git a/lib/storage/talk_settings.g.dart b/lib/storage/talk_settings.g.dart index 0b3e55b..520fab0 100644 --- a/lib/storage/talk_settings.g.dart +++ b/lib/storage/talk_settings.g.dart @@ -6,12 +6,25 @@ part of 'talk_settings.dart'; // JsonSerializableGenerator // ************************************************************************** -TalkSettings _$TalkSettingsFromJson(Map json) => TalkSettings( - sortFavoritesToTop: json['sortFavoritesToTop'] as bool, - sortUnreadToTop: json['sortUnreadToTop'] as bool, - drafts: Map.from(json['drafts'] as Map), - draftReplies: Map.from(json['draftReplies'] as Map), -); +TalkSettings _$TalkSettingsFromJson(Map json) => + $checkedCreate('TalkSettings', json, ($checkedConvert) { + final val = TalkSettings( + sortFavoritesToTop: $checkedConvert( + 'sortFavoritesToTop', + (v) => v as bool, + ), + sortUnreadToTop: $checkedConvert('sortUnreadToTop', (v) => v as bool), + drafts: $checkedConvert( + 'drafts', + (v) => Map.from(v as Map), + ), + draftReplies: $checkedConvert( + 'draftReplies', + (v) => Map.from(v as Map), + ), + ); + return val; + }); Map _$TalkSettingsToJson(TalkSettings instance) => { diff --git a/lib/storage/timetable_favorites_settings.g.dart b/lib/storage/timetable_favorites_settings.g.dart index 54f0d0e..9973a2a 100644 --- a/lib/storage/timetable_favorites_settings.g.dart +++ b/lib/storage/timetable_favorites_settings.g.dart @@ -8,11 +8,17 @@ part of 'timetable_favorites_settings.dart'; FavoriteTimetableElement _$FavoriteTimetableElementFromJson( Map json, -) => FavoriteTimetableElement( - type: $enumDecode(_$TimetableElementTypeEnumMap, json['type']), - id: (json['id'] as num).toInt(), - label: json['label'] as String, -); +) => $checkedCreate('FavoriteTimetableElement', json, ($checkedConvert) { + final val = FavoriteTimetableElement( + type: $checkedConvert( + 'type', + (v) => $enumDecode(_$TimetableElementTypeEnumMap, v), + ), + id: $checkedConvert('id', (v) => (v as num).toInt()), + label: $checkedConvert('label', (v) => v as String), + ); + return val; +}); Map _$FavoriteTimetableElementToJson( FavoriteTimetableElement instance, @@ -31,11 +37,19 @@ const _$TimetableElementTypeEnumMap = { TimetableFavoritesSettings _$TimetableFavoritesSettingsFromJson( Map json, -) => TimetableFavoritesSettings( - favorites: (json['favorites'] as List) - .map((e) => FavoriteTimetableElement.fromJson(e as Map)) - .toList(), -); +) => $checkedCreate('TimetableFavoritesSettings', json, ($checkedConvert) { + final val = TimetableFavoritesSettings( + favorites: $checkedConvert( + 'favorites', + (v) => (v as List) + .map( + (e) => FavoriteTimetableElement.fromJson(e as Map), + ) + .toList(), + ), + ); + return val; +}); Map _$TimetableFavoritesSettingsToJson( TimetableFavoritesSettings instance, diff --git a/lib/storage/timetable_settings.g.dart b/lib/storage/timetable_settings.g.dart index 87c60d7..cf6e890 100644 --- a/lib/storage/timetable_settings.g.dart +++ b/lib/storage/timetable_settings.g.dart @@ -7,13 +7,19 @@ part of 'timetable_settings.dart'; // ************************************************************************** TimetableSettings _$TimetableSettingsFromJson(Map json) => - TimetableSettings( - connectDoubleLessons: json['connectDoubleLessons'] as bool, - timetableNameMode: $enumDecode( - _$TimetableNameModeEnumMap, - json['timetableNameMode'], - ), - ); + $checkedCreate('TimetableSettings', json, ($checkedConvert) { + final val = TimetableSettings( + connectDoubleLessons: $checkedConvert( + 'connectDoubleLessons', + (v) => v as bool, + ), + timetableNameMode: $checkedConvert( + 'timetableNameMode', + (v) => $enumDecode(_$TimetableNameModeEnumMap, v), + ), + ); + return val; + }); Map _$TimetableSettingsToJson( TimetableSettings instance, diff --git a/lib/view/pages/talk/widgets/chat_bubble.dart b/lib/view/pages/talk/widgets/chat_bubble.dart index fbdd722..3f33521 100644 --- a/lib/view/pages/talk/widgets/chat_bubble.dart +++ b/lib/view/pages/talk/widgets/chat_bubble.dart @@ -121,6 +121,7 @@ class _ChatBubbleState extends State case GetRoomResponseObjectMessageType.comment: case GetRoomResponseObjectMessageType.voiceMessage: case GetRoomResponseObjectMessageType.command: + case GetRoomResponseObjectMessageType.unknown: return null; } } diff --git a/lib/view/pages/talk/widgets/chat_tile.dart b/lib/view/pages/talk/widgets/chat_tile.dart index ba56047..e8a4d47 100644 --- a/lib/view/pages/talk/widgets/chat_tile.dart +++ b/lib/view/pages/talk/widgets/chat_tile.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../api/marianumcloud/talk/actions/talk_actions.dart'; +import '../../../../api/marianumcloud/talk/chat/get_chat_response.dart'; import '../../../../api/marianumcloud/talk/chat/rich_object_string_processor.dart'; import '../../../../api/marianumcloud/talk/room/get_room_response.dart'; import '../../../../api/marianumcloud/talk/room/notification_level.dart'; @@ -69,8 +70,7 @@ class _ChatTileState extends State { /// Memoised per last message: the tile rebuilds on every chat-list emit and /// the Markdown strip is a full parse. Keyed by content, since every refresh /// delivers new message objects. - String _lastMessagePreview() { - final last = widget.data.lastMessage; + String _lastMessagePreview(GetChatResponseObject last) { final key = (last.id, last.message, last.markdown); if (key == _previewFor) return _preview; final text = RichObjectStringProcessor.parseToString( @@ -84,9 +84,16 @@ class _ChatTileState extends State { Object? _previewFor; String _preview = ''; + String _subtitle() { + final last = widget.data.lastMessage; + if (last == null) return 'Noch keine Nachrichten'; + return '${last.sentAt.formatRelative()}: ${_lastMessagePreview(last)}'; + } + Future _setCurrentAsRead() async { final token = widget.data.token; - final lastId = widget.data.lastMessage.id; + final lastId = widget.data.lastMessage?.id; + if (lastId == null) return; context.read().markRoomAsRead(token, lastId); unawaited(NotificationTasks.clearNotificationsForChat(token)); await context.read().sendServerReadMarker(token, lastId); @@ -173,11 +180,7 @@ class _ChatTileState extends State { ], ], ), - subtitle: Text( - '${widget.data.lastMessage.sentAt.formatRelative()}: ' - '${_lastMessagePreview()}', - overflow: TextOverflow.ellipsis, - ), + subtitle: Text(_subtitle(), overflow: TextOverflow.ellipsis), trailing: widget.data.unreadMessages <= 0 ? null : Semantics( diff --git a/lib/widget_data/widget_data.g.dart b/lib/widget_data/widget_data.g.dart index de71751..37f7f9f 100644 --- a/lib/widget_data/widget_data.g.dart +++ b/lib/widget_data/widget_data.g.dart @@ -7,19 +7,31 @@ part of 'widget_data.dart'; // ************************************************************************** _WidgetLesson _$WidgetLessonFromJson(Map json) => - _WidgetLesson( - start: DateTime.parse(json['start'] as String), - end: DateTime.parse(json['end'] as String), - subjectShort: json['subjectShort'] as String, - subjectLong: json['subjectLong'] as String?, - room: json['room'] as String?, - teacher: json['teacher'] as String?, - originalTeacher: json['originalTeacher'] as String?, - status: $enumDecode(_$WidgetLessonStatusEnumMap, json['status']), - customColor: json['customColor'] as String?, - color: json['color'] as String?, - siblingCount: (json['siblingCount'] as num?)?.toInt() ?? 0, - ); + $checkedCreate('_WidgetLesson', json, ($checkedConvert) { + final val = _WidgetLesson( + start: $checkedConvert('start', (v) => DateTime.parse(v as String)), + end: $checkedConvert('end', (v) => DateTime.parse(v as String)), + subjectShort: $checkedConvert('subjectShort', (v) => v as String), + subjectLong: $checkedConvert('subjectLong', (v) => v as String?), + room: $checkedConvert('room', (v) => v as String?), + teacher: $checkedConvert('teacher', (v) => v as String?), + originalTeacher: $checkedConvert( + 'originalTeacher', + (v) => v as String?, + ), + status: $checkedConvert( + 'status', + (v) => $enumDecode(_$WidgetLessonStatusEnumMap, v), + ), + customColor: $checkedConvert('customColor', (v) => v as String?), + color: $checkedConvert('color', (v) => v as String?), + siblingCount: $checkedConvert( + 'siblingCount', + (v) => (v as num?)?.toInt() ?? 0, + ), + ); + return val; + }); Map _$WidgetLessonToJson(_WidgetLesson instance) => { @@ -48,13 +60,25 @@ const _$WidgetLessonStatusEnumMap = { }; _WidgetPeriod _$WidgetPeriodFromJson(Map json) => - _WidgetPeriod( - name: json['name'] as String, - startMinutes: (json['startMinutes'] as num).toInt(), - endMinutes: (json['endMinutes'] as num).toInt(), - virtualStartMinutes: (json['virtualStartMinutes'] as num).toInt(), - virtualEndMinutes: (json['virtualEndMinutes'] as num).toInt(), - ); + $checkedCreate('_WidgetPeriod', json, ($checkedConvert) { + final val = _WidgetPeriod( + name: $checkedConvert('name', (v) => v as String), + startMinutes: $checkedConvert( + 'startMinutes', + (v) => (v as num).toInt(), + ), + endMinutes: $checkedConvert('endMinutes', (v) => (v as num).toInt()), + virtualStartMinutes: $checkedConvert( + 'virtualStartMinutes', + (v) => (v as num).toInt(), + ), + virtualEndMinutes: $checkedConvert( + 'virtualEndMinutes', + (v) => (v as num).toInt(), + ), + ); + return val; + }); Map _$WidgetPeriodToJson(_WidgetPeriod instance) => { @@ -66,11 +90,14 @@ Map _$WidgetPeriodToJson(_WidgetPeriod instance) => }; _WidgetDayInfo _$WidgetDayInfoFromJson(Map json) => - _WidgetDayInfo( - date: DateTime.parse(json['date'] as String), - isHoliday: json['isHoliday'] as bool? ?? false, - holidayName: json['holidayName'] as String?, - ); + $checkedCreate('_WidgetDayInfo', json, ($checkedConvert) { + final val = _WidgetDayInfo( + date: $checkedConvert('date', (v) => DateTime.parse(v as String)), + isHoliday: $checkedConvert('isHoliday', (v) => v as bool? ?? false), + holidayName: $checkedConvert('holidayName', (v) => v as String?), + ); + return val; + }); Map _$WidgetDayInfoToJson(_WidgetDayInfo instance) => { @@ -79,26 +106,42 @@ Map _$WidgetDayInfoToJson(_WidgetDayInfo instance) => 'holidayName': instance.holidayName, }; -_WidgetTimetableData _$WidgetTimetableDataFromJson(Map json) => - _WidgetTimetableData( - fetchedAt: DateTime.parse(json['fetchedAt'] as String), - anchorDate: DateTime.parse(json['anchorDate'] as String), - lessons: (json['lessons'] as List) +_WidgetTimetableData _$WidgetTimetableDataFromJson( + Map json, +) => $checkedCreate('_WidgetTimetableData', json, ($checkedConvert) { + final val = _WidgetTimetableData( + fetchedAt: $checkedConvert('fetchedAt', (v) => DateTime.parse(v as String)), + anchorDate: $checkedConvert( + 'anchorDate', + (v) => DateTime.parse(v as String), + ), + lessons: $checkedConvert( + 'lessons', + (v) => (v as List) .map((e) => WidgetLesson.fromJson(e as Map)) .toList(), - periods: - (json['periods'] as List?) + ), + periods: $checkedConvert( + 'periods', + (v) => + (v as List?) ?.map((e) => WidgetPeriod.fromJson(e as Map)) .toList() ?? const [], - isHoliday: json['isHoliday'] as bool? ?? false, - holidayName: json['holidayName'] as String?, - days: - (json['days'] as List?) + ), + isHoliday: $checkedConvert('isHoliday', (v) => v as bool? ?? false), + holidayName: $checkedConvert('holidayName', (v) => v as String?), + days: $checkedConvert( + 'days', + (v) => + (v as List?) ?.map((e) => WidgetDayInfo.fromJson(e as Map)) .toList() ?? const [], - ); + ), + ); + return val; +}); Map _$WidgetTimetableDataToJson( _WidgetTimetableData instance, diff --git a/test/api/autocomplete_response_test.dart b/test/api/autocomplete_response_test.dart new file mode 100644 index 0000000..1199b68 --- /dev/null +++ b/test/api/autocomplete_response_test.dart @@ -0,0 +1,32 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:marianum_mobile/api/json_lenient.dart'; +import 'package:marianum_mobile/api/marianumcloud/autocomplete/autocomplete_response.dart'; + +void main() { + test('accepts the status as object, string or empty', () { + final response = AutocompleteResponse.fromJson({ + 'data': [ + { + 'id': 'a', + 'label': 'A', + 'status': {'status': 'online', 'message': null}, + }, + {'id': 'b', 'label': 'B', 'status': ''}, + {'id': 'c', 'label': 'C', 'status': 'dnd'}, + ], + }); + expect(response.data.map((e) => e.status), ['online', null, 'dnd']); + expect(drainDecodeWarnings(), isEmpty); + }); + + test('skips an entry without id instead of failing the search', () { + final response = AutocompleteResponse.fromJson({ + 'data': [ + {'label': 'no id'}, + {'id': 'b', 'label': 'B'}, + ], + }); + expect(response.data.single.id, 'b'); + expect(drainDecodeWarnings().single, contains('"id"')); + }); +} diff --git a/test/talk/get_participants_response_test.dart b/test/talk/get_participants_response_test.dart new file mode 100644 index 0000000..cd1e5e9 --- /dev/null +++ b/test/talk/get_participants_response_test.dart @@ -0,0 +1,23 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:marianum_mobile/api/marianumcloud/talk/get_participants/get_participants_response.dart'; + +void main() { + test('reads inCall as a bitmask', () { + final participant = GetParticipantsResponseObject.fromJson({ + 'attendeeId': 1, + 'actorType': 'users', + 'actorId': 'u', + 'displayName': 'U', + 'participantType': 3, + 'lastPing': 0, + 'inCall': 7, + 'permissions': 0, + 'attendeePermissions': 0, + 'sessionIds': [], + }); + expect(participant.isInCall, isTrue); + expect(participant.inCallWithAudio, isTrue); + expect(participant.inCallWithVideo, isTrue); + expect(participant.inCallViaPhone, isFalse); + }); +} diff --git a/test/talk/get_room_response_test.dart b/test/talk/get_room_response_test.dart new file mode 100644 index 0000000..13800b7 --- /dev/null +++ b/test/talk/get_room_response_test.dart @@ -0,0 +1,122 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:marianum_mobile/api/json_lenient.dart'; +import 'package:marianum_mobile/api/marianumcloud/talk/chat/get_chat_response.dart'; +import 'package:marianum_mobile/api/marianumcloud/talk/room/get_room_response.dart'; + +Map _room({bool withLastMessage = true}) => { + 'id': 1, + 'token': 'abc', + 'type': 2, + 'name': 'room', + 'displayName': 'Room', + 'description': '', + 'participantType': 3, + 'participantFlags': 0, + 'readOnly': 0, + 'listable': 0, + 'lastPing': 0, + 'sessionId': '0', + 'hasPassword': false, + 'hasCall': false, + 'callFlag': 0, + 'canStartCall': true, + 'canDeleteConversation': false, + 'canLeaveConversation': true, + 'lastActivity': 1700000000, + 'isFavorite': false, + 'notificationLevel': 0, + 'unreadMessages': 0, + 'unreadMention': false, + 'unreadMentionDirect': false, + 'lastReadMessage': 0, + 'lastCommonReadMessage': 0, + if (withLastMessage) + 'lastMessage': { + 'id': 7, + 'token': 'abc', + 'actorType': 'users', + 'actorId': 'u', + 'actorDisplayName': 'U', + 'timestamp': 1700000000, + 'systemMessage': '', + 'messageType': 'comment', + 'isReplyable': true, + 'referenceId': '', + 'message': 'hi', + }, +}; + +void main() { + setUp(drainDecodeWarnings); + + test('skips a room that does not parse and records class and key', () { + final broken = _room()..remove('displayName'); + final response = GetRoomResponse.fromJson({ + 'data': [broken, _room()], + }); + expect(response.data.length, 1); + final warnings = drainDecodeWarnings(); + expect(warnings, hasLength(1)); + expect(warnings.single, contains('GetRoomResponseObject')); + expect(warnings.single, contains('"displayName"')); + }); + + test('parses a room whose lastMessage the server omitted', () { + final response = GetRoomResponse.fromJson({ + 'data': [_room(withLastMessage: false), _room()], + }); + final rooms = response.data.toList(); + expect(rooms[0].lastMessage, isNull); + expect(rooms[1].lastMessage?.id, 7); + expect(drainDecodeWarnings(), isEmpty); + }); + + test('maps unknown enum values to their fallbacks', () { + final room = _room() + ..['type'] = 99 + ..['notificationLevel'] = 42; + (room['lastMessage'] as Map) + ..['actorType'] = 'emails' + ..['messageType'] = 'record-video' + ..['messageParameters'] = { + 'actor': {'type': 'deck-card', 'id': '1', 'name': 'Card'}, + }; + final parsed = GetRoomResponse.fromJson({ + 'data': [room], + }).data.single; + expect(parsed.type, GetRoomResponseObjectConversationType.unknown); + expect( + parsed.notificationLevel, + GetRoomResponseObjectParticipantNotificationLevel.defaultLevel, + ); + expect( + parsed.lastMessage?.actorType, + GetRoomResponseObjectMessageActorType.email, + ); + expect( + parsed.lastMessage?.messageType, + GetRoomResponseObjectMessageType.unknown, + ); + expect( + parsed.lastMessage?.messageParameters?['actor']?.type, + RichObjectStringObjectType.unknown, + ); + expect(drainDecodeWarnings(), isEmpty); + }); + + test('turns a deleted parent into a placeholder', () { + final room = _room(); + (room['lastMessage'] as Map)['parent'] = { + 'id': 3, + 'deleted': true, + }; + final parent = GetRoomResponse.fromJson({ + 'data': [room], + }).data.single.lastMessage?.parent; + expect(parent?.id, 3); + expect( + parent?.messageType, + GetRoomResponseObjectMessageType.deletedComment, + ); + }); +}