diff --git a/packages/stream_video/lib/globals.dart b/packages/stream_video/lib/globals.dart index 8b67b4d8a..711d88186 100644 --- a/packages/stream_video/lib/globals.dart +++ b/packages/stream_video/lib/globals.dart @@ -5,7 +5,7 @@ import 'protobuf/video/sfu/models/models.pb.dart'; const String streamSdkName = 'stream-flutter'; const String streamVideoVersion = '1.2.4'; -const String openapiModelsVersion = '202.0.0'; +const String openapiModelsVersion = '219.11.0'; const String protocolModelsVersion = '1.40.1'; const String androidWebRTCVersion = webrtc.androidWebRTCVersion; const String iosWebRTCVersion = webrtc.iosWebRTCVersion; diff --git a/packages/stream_video/lib/open_api/video/coordinator/api.dart b/packages/stream_video/lib/open_api/video/coordinator/api.dart index ef4966d9e..e549ce70c 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/api.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/api.dart @@ -68,6 +68,8 @@ part 'model/call_member_removed_event.dart'; part 'model/call_member_updated_event.dart'; part 'model/call_member_updated_permission_event.dart'; part 'model/call_missed_event.dart'; +part 'model/call_moderation_blur_event.dart'; +part 'model/call_moderation_warning_event.dart'; part 'model/call_notification_event.dart'; part 'model/call_participant_count_report.dart'; part 'model/call_participant_count_report_response.dart'; @@ -135,6 +137,7 @@ part 'model/egress_hls_response.dart'; part 'model/egress_rtmp_response.dart'; part 'model/egress_response.dart'; part 'model/end_call_response.dart'; +part 'model/feeds_preferences_response.dart'; part 'model/file_upload_config.dart'; part 'model/frame_recording_response.dart'; part 'model/frame_recording_settings_request.dart'; @@ -153,6 +156,9 @@ part 'model/hls_settings_request.dart'; part 'model/hls_settings_response.dart'; part 'model/health_check_event.dart'; part 'model/ice_server.dart'; +part 'model/individual_recording_response.dart'; +part 'model/individual_recording_settings_request.dart'; +part 'model/individual_recording_settings_response.dart'; part 'model/ingress_audio_encoding_options_request.dart'; part 'model/ingress_audio_encoding_response.dart'; part 'model/ingress_settings_request.dart'; @@ -191,7 +197,7 @@ part 'model/pin_response.dart'; part 'model/privacy_settings.dart'; part 'model/published_track_flags.dart'; part 'model/publisher_stats_response.dart'; -part 'model/push_preferences.dart'; +part 'model/push_preferences_response.dart'; part 'model/quality_score_report.dart'; part 'model/quality_score_report_response.dart'; part 'model/query_aggregate_call_stats_request.dart'; @@ -208,6 +214,8 @@ part 'model/rtmp_broadcast_request.dart'; part 'model/rtmp_ingress.dart'; part 'model/rtmp_settings_request.dart'; part 'model/rtmp_settings_response.dart'; +part 'model/raw_recording_settings_request.dart'; +part 'model/raw_recording_settings_response.dart'; part 'model/reaction_response.dart'; part 'model/read_receipts.dart'; part 'model/record_settings_request.dart'; diff --git a/packages/stream_video/lib/open_api/video/coordinator/api/productvideo_api.dart b/packages/stream_video/lib/open_api/video/coordinator/api/productvideo_api.dart index 7c0afc3eb..2053eba98 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/api/productvideo_api.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/api/productvideo_api.dart @@ -2765,17 +2765,21 @@ class ProductvideoApi { /// /// * [String] id (required): /// + /// * [String] recordingType (required): + /// /// * [StartRecordingRequest] startRecordingRequest (required): /// StartRecordingRequest Future startRecordingWithHttpInfo( String type, String id, + String recordingType, StartRecordingRequest startRecordingRequest, ) async { // ignore: prefer_const_declarations - final path = r'/video/call/{type}/{id}/start_recording' + final path = r'/video/call/{type}/{id}/recordings/{recording_type}/start' .replaceAll('{type}', type) - .replaceAll('{id}', id); + .replaceAll('{id}', id) + .replaceAll('{recording_type}', recordingType); // ignore: prefer_final_locals Object? postBody = startRecordingRequest; @@ -2807,16 +2811,20 @@ class ProductvideoApi { /// /// * [String] id (required): /// + /// * [String] recordingType (required): + /// /// * [StartRecordingRequest] startRecordingRequest (required): /// StartRecordingRequest Future startRecording( String type, String id, + String recordingType, StartRecordingRequest startRecordingRequest, ) async { final response = await startRecordingWithHttpInfo( type, id, + recordingType, startRecordingRequest, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -3397,23 +3405,30 @@ class ProductvideoApi { /// * [String] type (required): /// /// * [String] id (required): + /// + /// * [String] recordingType (required): + /// + /// * [Object] body (required): Future stopRecordingWithHttpInfo( String type, String id, + String recordingType, + Object body, ) async { // ignore: prefer_const_declarations - final path = r'/video/call/{type}/{id}/stop_recording' + final path = r'/video/call/{type}/{id}/recordings/{recording_type}/stop' .replaceAll('{type}', type) - .replaceAll('{id}', id); + .replaceAll('{id}', id) + .replaceAll('{recording_type}', recordingType); // ignore: prefer_final_locals - Object? postBody; + Object? postBody = body; final queryParams = []; final headerParams = {}; final formParams = {}; - const contentTypes = []; + const contentTypes = ['application/json']; return apiClient.invokeAPI( path, @@ -3435,13 +3450,21 @@ class ProductvideoApi { /// * [String] type (required): /// /// * [String] id (required): + /// + /// * [String] recordingType (required): + /// + /// * [Object] body (required): Future stopRecording( String type, String id, + String recordingType, + Object body, ) async { final response = await stopRecordingWithHttpInfo( type, id, + recordingType, + body, ); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); diff --git a/packages/stream_video/lib/open_api/video/coordinator/api_client.dart b/packages/stream_video/lib/open_api/video/coordinator/api_client.dart index 3a51110b0..75bfc12e7 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/api_client.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/api_client.dart @@ -305,6 +305,10 @@ class ApiClient { return CallMemberUpdatedPermissionEvent.fromJson(value); case 'CallMissedEvent': return CallMissedEvent.fromJson(value); + case 'CallModerationBlurEvent': + return CallModerationBlurEvent.fromJson(value); + case 'CallModerationWarningEvent': + return CallModerationWarningEvent.fromJson(value); case 'CallNotificationEvent': return CallNotificationEvent.fromJson(value); case 'CallParticipantCountReport': @@ -476,6 +480,12 @@ class ApiClient { return HealthCheckEvent.fromJson(value); case 'ICEServer': return ICEServer.fromJson(value); + case 'IndividualRecordingResponse': + return IndividualRecordingResponse.fromJson(value); + case 'IndividualRecordingSettingsRequest': + return IndividualRecordingSettingsRequest.fromJson(value); + case 'IndividualRecordingSettingsResponse': + return IndividualRecordingSettingsResponse.fromJson(value); case 'IngressAudioEncodingOptionsRequest': return IngressAudioEncodingOptionsRequest.fromJson(value); case 'IngressAudioEncodingResponse': @@ -552,8 +562,8 @@ class ApiClient { return PublishedTrackFlags.fromJson(value); case 'PublisherStatsResponse': return PublisherStatsResponse.fromJson(value); - case 'PushPreferences': - return PushPreferences.fromJson(value); + case 'PushPreferencesResponse': + return PushPreferencesResponse.fromJson(value); case 'QualityScoreReport': return QualityScoreReport.fromJson(value); case 'QualityScoreReportResponse': @@ -586,6 +596,10 @@ class ApiClient { return RTMPSettingsRequest.fromJson(value); case 'RTMPSettingsResponse': return RTMPSettingsResponse.fromJson(value); + case 'RawRecordingSettingsRequest': + return RawRecordingSettingsRequest.fromJson(value); + case 'RawRecordingSettingsResponse': + return RawRecordingSettingsResponse.fromJson(value); case 'ReactionResponse': return ReactionResponse.fromJson(value); case 'ReadReceipts': @@ -606,6 +620,7 @@ class ApiClient { return RequestPermissionRequest.fromJson(value); case 'RequestPermissionResponse': return RequestPermissionResponse.fromJson(value); + //MANUAL_EDIT case 'DurationResponse': return DurationResponse.fromJson(value); case 'RingCallRequest': diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_moderation_blur_event.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_moderation_blur_event.dart new file mode 100644 index 000000000..0be0d2fb8 --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_moderation_blur_event.dart @@ -0,0 +1,157 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CallModerationBlurEvent { + /// Returns a new [CallModerationBlurEvent] instance. + CallModerationBlurEvent({ + required this.callCid, + required this.createdAt, + this.custom = const {}, + this.type = 'call.moderation_blur', + required this.userId, + }); + + String callCid; + + DateTime createdAt; + + /// Custom data associated with the moderation action + Map custom; + + /// The type of event: \"call.moderation_blur\" in this case + String type; + + /// The user ID whose video stream is being blurred + String userId; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is CallModerationBlurEvent && + other.callCid == callCid && + other.createdAt == createdAt && + _deepEquality.equals(other.custom, custom) && + other.type == type && + other.userId == userId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (callCid.hashCode) + + (createdAt.hashCode) + + (custom.hashCode) + + (type.hashCode) + + (userId.hashCode); + + @override + String toString() => + 'CallModerationBlurEvent[callCid=$callCid, createdAt=$createdAt, custom=$custom, type=$type, userId=$userId]'; + + Map toJson() { + final json = {}; + json[r'call_cid'] = this.callCid; + json[r'created_at'] = this.createdAt.toUtc().toIso8601String(); + json[r'custom'] = this.custom; + json[r'type'] = this.type; + json[r'user_id'] = this.userId; + return json; + } + + /// Returns a new [CallModerationBlurEvent] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CallModerationBlurEvent? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "CallModerationBlurEvent[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "CallModerationBlurEvent[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CallModerationBlurEvent( + callCid: mapValueOfType(json, r'call_cid')!, + createdAt: mapDateTime(json, r'created_at', r'')!, + custom: mapCastOfType(json, r'custom')!, + type: mapValueOfType(json, r'type')!, + userId: mapValueOfType(json, r'user_id')!, + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CallModerationBlurEvent.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CallModerationBlurEvent.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CallModerationBlurEvent-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = CallModerationBlurEvent.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'call_cid', + 'created_at', + 'custom', + 'type', + 'user_id', + }; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_moderation_warning_event.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_moderation_warning_event.dart new file mode 100644 index 000000000..2cb368f83 --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_moderation_warning_event.dart @@ -0,0 +1,166 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CallModerationWarningEvent { + /// Returns a new [CallModerationWarningEvent] instance. + CallModerationWarningEvent({ + required this.callCid, + required this.createdAt, + this.custom = const {}, + required this.message, + this.type = 'call.moderation_warning', + required this.userId, + }); + + String callCid; + + DateTime createdAt; + + /// Custom data associated with the moderation action + Map custom; + + /// The warning message + String message; + + /// The type of event: \"call.moderation_warning\" in this case + String type; + + /// The user ID who is receiving the warning + String userId; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is CallModerationWarningEvent && + other.callCid == callCid && + other.createdAt == createdAt && + _deepEquality.equals(other.custom, custom) && + other.message == message && + other.type == type && + other.userId == userId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (callCid.hashCode) + + (createdAt.hashCode) + + (custom.hashCode) + + (message.hashCode) + + (type.hashCode) + + (userId.hashCode); + + @override + String toString() => + 'CallModerationWarningEvent[callCid=$callCid, createdAt=$createdAt, custom=$custom, message=$message, type=$type, userId=$userId]'; + + Map toJson() { + final json = {}; + json[r'call_cid'] = this.callCid; + json[r'created_at'] = this.createdAt.toUtc().toIso8601String(); + json[r'custom'] = this.custom; + json[r'message'] = this.message; + json[r'type'] = this.type; + json[r'user_id'] = this.userId; + return json; + } + + /// Returns a new [CallModerationWarningEvent] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CallModerationWarningEvent? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "CallModerationWarningEvent[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "CallModerationWarningEvent[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return CallModerationWarningEvent( + callCid: mapValueOfType(json, r'call_cid')!, + createdAt: mapDateTime(json, r'created_at', r'')!, + custom: mapCastOfType(json, r'custom')!, + message: mapValueOfType(json, r'message')!, + type: mapValueOfType(json, r'type')!, + userId: mapValueOfType(json, r'user_id')!, + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CallModerationWarningEvent.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = CallModerationWarningEvent.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CallModerationWarningEvent-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = CallModerationWarningEvent.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'call_cid', + 'created_at', + 'custom', + 'message', + 'type', + 'user_id', + }; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording.dart index d57954cc9..452d7aa68 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording.dart @@ -15,6 +15,7 @@ class CallRecording { CallRecording({ required this.endTime, required this.filename, + required this.recordingType, required this.sessionId, required this.startTime, required this.url, @@ -24,6 +25,8 @@ class CallRecording { String filename; + String recordingType; + String sessionId; DateTime startTime; @@ -36,6 +39,7 @@ class CallRecording { other is CallRecording && other.endTime == endTime && other.filename == filename && + other.recordingType == recordingType && other.sessionId == sessionId && other.startTime == startTime && other.url == url; @@ -45,18 +49,20 @@ class CallRecording { // ignore: unnecessary_parenthesis (endTime.hashCode) + (filename.hashCode) + + (recordingType.hashCode) + (sessionId.hashCode) + (startTime.hashCode) + (url.hashCode); @override String toString() => - 'CallRecording[endTime=$endTime, filename=$filename, sessionId=$sessionId, startTime=$startTime, url=$url]'; + 'CallRecording[endTime=$endTime, filename=$filename, recordingType=$recordingType, sessionId=$sessionId, startTime=$startTime, url=$url]'; Map toJson() { final json = {}; json[r'end_time'] = this.endTime.toUtc().toIso8601String(); json[r'filename'] = this.filename; + json[r'recording_type'] = this.recordingType; json[r'session_id'] = this.sessionId; json[r'start_time'] = this.startTime.toUtc().toIso8601String(); json[r'url'] = this.url; @@ -86,6 +92,7 @@ class CallRecording { return CallRecording( endTime: mapDateTime(json, r'end_time', r'')!, filename: mapValueOfType(json, r'filename')!, + recordingType: mapValueOfType(json, r'recording_type')!, sessionId: mapValueOfType(json, r'session_id')!, startTime: mapDateTime(json, r'start_time', r'')!, url: mapValueOfType(json, r'url')!, @@ -147,6 +154,7 @@ class CallRecording { static const requiredKeys = { 'end_time', 'filename', + 'recording_type', 'session_id', 'start_time', 'url', diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_failed_event.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_failed_event.dart index edf9358b4..6a2bececc 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_failed_event.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_failed_event.dart @@ -16,6 +16,7 @@ class CallRecordingFailedEvent { required this.callCid, required this.createdAt, required this.egressId, + required this.recordingType, this.type = 'call.recording_failed', }); @@ -25,6 +26,9 @@ class CallRecordingFailedEvent { String egressId; + /// The type of recording + CallRecordingFailedEventRecordingTypeEnum recordingType; + /// The type of event: \"call.recording_failed\" in this case String type; @@ -35,6 +39,7 @@ class CallRecordingFailedEvent { other.callCid == callCid && other.createdAt == createdAt && other.egressId == egressId && + other.recordingType == recordingType && other.type == type; @override @@ -43,17 +48,19 @@ class CallRecordingFailedEvent { (callCid.hashCode) + (createdAt.hashCode) + (egressId.hashCode) + + (recordingType.hashCode) + (type.hashCode); @override String toString() => - 'CallRecordingFailedEvent[callCid=$callCid, createdAt=$createdAt, egressId=$egressId, type=$type]'; + 'CallRecordingFailedEvent[callCid=$callCid, createdAt=$createdAt, egressId=$egressId, recordingType=$recordingType, type=$type]'; Map toJson() { final json = {}; json[r'call_cid'] = this.callCid; json[r'created_at'] = this.createdAt.toUtc().toIso8601String(); json[r'egress_id'] = this.egressId; + json[r'recording_type'] = this.recordingType; json[r'type'] = this.type; return json; } @@ -82,6 +89,8 @@ class CallRecordingFailedEvent { callCid: mapValueOfType(json, r'call_cid')!, createdAt: mapDateTime(json, r'created_at', r'')!, egressId: mapValueOfType(json, r'egress_id')!, + recordingType: CallRecordingFailedEventRecordingTypeEnum.fromJson( + json[r'recording_type'])!, type: mapValueOfType(json, r'type')!, ); } @@ -142,6 +151,95 @@ class CallRecordingFailedEvent { 'call_cid', 'created_at', 'egress_id', + 'recording_type', 'type', }; } + +/// The type of recording +class CallRecordingFailedEventRecordingTypeEnum { + /// Instantiate a new enum with the provided [value]. + const CallRecordingFailedEventRecordingTypeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const composite = + CallRecordingFailedEventRecordingTypeEnum._(r'composite'); + static const individual = + CallRecordingFailedEventRecordingTypeEnum._(r'individual'); + static const raw = CallRecordingFailedEventRecordingTypeEnum._(r'raw'); + + /// List of all possible values in this [enum][CallRecordingFailedEventRecordingTypeEnum]. + static const values = [ + composite, + individual, + raw, + ]; + + static CallRecordingFailedEventRecordingTypeEnum? fromJson(dynamic value) => + CallRecordingFailedEventRecordingTypeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CallRecordingFailedEventRecordingTypeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [CallRecordingFailedEventRecordingTypeEnum] to String, +/// and [decode] dynamic data back to [CallRecordingFailedEventRecordingTypeEnum]. +class CallRecordingFailedEventRecordingTypeEnumTypeTransformer { + factory CallRecordingFailedEventRecordingTypeEnumTypeTransformer() => + _instance ??= + const CallRecordingFailedEventRecordingTypeEnumTypeTransformer._(); + + const CallRecordingFailedEventRecordingTypeEnumTypeTransformer._(); + + String encode(CallRecordingFailedEventRecordingTypeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a CallRecordingFailedEventRecordingTypeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + CallRecordingFailedEventRecordingTypeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'composite': + return CallRecordingFailedEventRecordingTypeEnum.composite; + case r'individual': + return CallRecordingFailedEventRecordingTypeEnum.individual; + case r'raw': + return CallRecordingFailedEventRecordingTypeEnum.raw; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [CallRecordingFailedEventRecordingTypeEnumTypeTransformer] instance. + static CallRecordingFailedEventRecordingTypeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_ready_event.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_ready_event.dart index d0a71e369..f4378a6b4 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_ready_event.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_ready_event.dart @@ -17,6 +17,7 @@ class CallRecordingReadyEvent { required this.callRecording, required this.createdAt, required this.egressId, + required this.recordingType, this.type = 'call.recording_ready', }); @@ -28,6 +29,9 @@ class CallRecordingReadyEvent { String egressId; + /// The type of recording + CallRecordingReadyEventRecordingTypeEnum recordingType; + /// The type of event: \"call.recording_ready\" in this case String type; @@ -39,6 +43,7 @@ class CallRecordingReadyEvent { other.callRecording == callRecording && other.createdAt == createdAt && other.egressId == egressId && + other.recordingType == recordingType && other.type == type; @override @@ -48,11 +53,12 @@ class CallRecordingReadyEvent { (callRecording.hashCode) + (createdAt.hashCode) + (egressId.hashCode) + + (recordingType.hashCode) + (type.hashCode); @override String toString() => - 'CallRecordingReadyEvent[callCid=$callCid, callRecording=$callRecording, createdAt=$createdAt, egressId=$egressId, type=$type]'; + 'CallRecordingReadyEvent[callCid=$callCid, callRecording=$callRecording, createdAt=$createdAt, egressId=$egressId, recordingType=$recordingType, type=$type]'; Map toJson() { final json = {}; @@ -60,6 +66,7 @@ class CallRecordingReadyEvent { json[r'call_recording'] = this.callRecording; json[r'created_at'] = this.createdAt.toUtc().toIso8601String(); json[r'egress_id'] = this.egressId; + json[r'recording_type'] = this.recordingType; json[r'type'] = this.type; return json; } @@ -89,6 +96,8 @@ class CallRecordingReadyEvent { callRecording: CallRecording.fromJson(json[r'call_recording'])!, createdAt: mapDateTime(json, r'created_at', r'')!, egressId: mapValueOfType(json, r'egress_id')!, + recordingType: CallRecordingReadyEventRecordingTypeEnum.fromJson( + json[r'recording_type'])!, type: mapValueOfType(json, r'type')!, ); } @@ -150,6 +159,95 @@ class CallRecordingReadyEvent { 'call_recording', 'created_at', 'egress_id', + 'recording_type', 'type', }; } + +/// The type of recording +class CallRecordingReadyEventRecordingTypeEnum { + /// Instantiate a new enum with the provided [value]. + const CallRecordingReadyEventRecordingTypeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const composite = + CallRecordingReadyEventRecordingTypeEnum._(r'composite'); + static const individual = + CallRecordingReadyEventRecordingTypeEnum._(r'individual'); + static const raw = CallRecordingReadyEventRecordingTypeEnum._(r'raw'); + + /// List of all possible values in this [enum][CallRecordingReadyEventRecordingTypeEnum]. + static const values = [ + composite, + individual, + raw, + ]; + + static CallRecordingReadyEventRecordingTypeEnum? fromJson(dynamic value) => + CallRecordingReadyEventRecordingTypeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CallRecordingReadyEventRecordingTypeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [CallRecordingReadyEventRecordingTypeEnum] to String, +/// and [decode] dynamic data back to [CallRecordingReadyEventRecordingTypeEnum]. +class CallRecordingReadyEventRecordingTypeEnumTypeTransformer { + factory CallRecordingReadyEventRecordingTypeEnumTypeTransformer() => + _instance ??= + const CallRecordingReadyEventRecordingTypeEnumTypeTransformer._(); + + const CallRecordingReadyEventRecordingTypeEnumTypeTransformer._(); + + String encode(CallRecordingReadyEventRecordingTypeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a CallRecordingReadyEventRecordingTypeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + CallRecordingReadyEventRecordingTypeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'composite': + return CallRecordingReadyEventRecordingTypeEnum.composite; + case r'individual': + return CallRecordingReadyEventRecordingTypeEnum.individual; + case r'raw': + return CallRecordingReadyEventRecordingTypeEnum.raw; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [CallRecordingReadyEventRecordingTypeEnumTypeTransformer] instance. + static CallRecordingReadyEventRecordingTypeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_started_event.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_started_event.dart index e40555ef2..63b6bdc40 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_started_event.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_started_event.dart @@ -16,6 +16,7 @@ class CallRecordingStartedEvent { required this.callCid, required this.createdAt, required this.egressId, + required this.recordingType, this.type = 'call.recording_started', }); @@ -25,6 +26,9 @@ class CallRecordingStartedEvent { String egressId; + /// The type of recording + CallRecordingStartedEventRecordingTypeEnum recordingType; + /// The type of event: \"call.recording_started\" in this case String type; @@ -35,6 +39,7 @@ class CallRecordingStartedEvent { other.callCid == callCid && other.createdAt == createdAt && other.egressId == egressId && + other.recordingType == recordingType && other.type == type; @override @@ -43,17 +48,19 @@ class CallRecordingStartedEvent { (callCid.hashCode) + (createdAt.hashCode) + (egressId.hashCode) + + (recordingType.hashCode) + (type.hashCode); @override String toString() => - 'CallRecordingStartedEvent[callCid=$callCid, createdAt=$createdAt, egressId=$egressId, type=$type]'; + 'CallRecordingStartedEvent[callCid=$callCid, createdAt=$createdAt, egressId=$egressId, recordingType=$recordingType, type=$type]'; Map toJson() { final json = {}; json[r'call_cid'] = this.callCid; json[r'created_at'] = this.createdAt.toUtc().toIso8601String(); json[r'egress_id'] = this.egressId; + json[r'recording_type'] = this.recordingType; json[r'type'] = this.type; return json; } @@ -82,6 +89,8 @@ class CallRecordingStartedEvent { callCid: mapValueOfType(json, r'call_cid')!, createdAt: mapDateTime(json, r'created_at', r'')!, egressId: mapValueOfType(json, r'egress_id')!, + recordingType: CallRecordingStartedEventRecordingTypeEnum.fromJson( + json[r'recording_type'])!, type: mapValueOfType(json, r'type')!, ); } @@ -142,6 +151,95 @@ class CallRecordingStartedEvent { 'call_cid', 'created_at', 'egress_id', + 'recording_type', 'type', }; } + +/// The type of recording +class CallRecordingStartedEventRecordingTypeEnum { + /// Instantiate a new enum with the provided [value]. + const CallRecordingStartedEventRecordingTypeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const composite = + CallRecordingStartedEventRecordingTypeEnum._(r'composite'); + static const individual = + CallRecordingStartedEventRecordingTypeEnum._(r'individual'); + static const raw = CallRecordingStartedEventRecordingTypeEnum._(r'raw'); + + /// List of all possible values in this [enum][CallRecordingStartedEventRecordingTypeEnum]. + static const values = [ + composite, + individual, + raw, + ]; + + static CallRecordingStartedEventRecordingTypeEnum? fromJson(dynamic value) => + CallRecordingStartedEventRecordingTypeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CallRecordingStartedEventRecordingTypeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [CallRecordingStartedEventRecordingTypeEnum] to String, +/// and [decode] dynamic data back to [CallRecordingStartedEventRecordingTypeEnum]. +class CallRecordingStartedEventRecordingTypeEnumTypeTransformer { + factory CallRecordingStartedEventRecordingTypeEnumTypeTransformer() => + _instance ??= + const CallRecordingStartedEventRecordingTypeEnumTypeTransformer._(); + + const CallRecordingStartedEventRecordingTypeEnumTypeTransformer._(); + + String encode(CallRecordingStartedEventRecordingTypeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a CallRecordingStartedEventRecordingTypeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + CallRecordingStartedEventRecordingTypeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'composite': + return CallRecordingStartedEventRecordingTypeEnum.composite; + case r'individual': + return CallRecordingStartedEventRecordingTypeEnum.individual; + case r'raw': + return CallRecordingStartedEventRecordingTypeEnum.raw; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [CallRecordingStartedEventRecordingTypeEnumTypeTransformer] instance. + static CallRecordingStartedEventRecordingTypeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_stopped_event.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_stopped_event.dart index ca229ba23..13eea3d78 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_stopped_event.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_recording_stopped_event.dart @@ -16,6 +16,7 @@ class CallRecordingStoppedEvent { required this.callCid, required this.createdAt, required this.egressId, + required this.recordingType, this.type = 'call.recording_stopped', }); @@ -25,6 +26,9 @@ class CallRecordingStoppedEvent { String egressId; + /// The type of recording + CallRecordingStoppedEventRecordingTypeEnum recordingType; + /// The type of event: \"call.recording_stopped\" in this case String type; @@ -35,6 +39,7 @@ class CallRecordingStoppedEvent { other.callCid == callCid && other.createdAt == createdAt && other.egressId == egressId && + other.recordingType == recordingType && other.type == type; @override @@ -43,17 +48,19 @@ class CallRecordingStoppedEvent { (callCid.hashCode) + (createdAt.hashCode) + (egressId.hashCode) + + (recordingType.hashCode) + (type.hashCode); @override String toString() => - 'CallRecordingStoppedEvent[callCid=$callCid, createdAt=$createdAt, egressId=$egressId, type=$type]'; + 'CallRecordingStoppedEvent[callCid=$callCid, createdAt=$createdAt, egressId=$egressId, recordingType=$recordingType, type=$type]'; Map toJson() { final json = {}; json[r'call_cid'] = this.callCid; json[r'created_at'] = this.createdAt.toUtc().toIso8601String(); json[r'egress_id'] = this.egressId; + json[r'recording_type'] = this.recordingType; json[r'type'] = this.type; return json; } @@ -82,6 +89,8 @@ class CallRecordingStoppedEvent { callCid: mapValueOfType(json, r'call_cid')!, createdAt: mapDateTime(json, r'created_at', r'')!, egressId: mapValueOfType(json, r'egress_id')!, + recordingType: CallRecordingStoppedEventRecordingTypeEnum.fromJson( + json[r'recording_type'])!, type: mapValueOfType(json, r'type')!, ); } @@ -142,6 +151,95 @@ class CallRecordingStoppedEvent { 'call_cid', 'created_at', 'egress_id', + 'recording_type', 'type', }; } + +/// The type of recording +class CallRecordingStoppedEventRecordingTypeEnum { + /// Instantiate a new enum with the provided [value]. + const CallRecordingStoppedEventRecordingTypeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const composite = + CallRecordingStoppedEventRecordingTypeEnum._(r'composite'); + static const individual = + CallRecordingStoppedEventRecordingTypeEnum._(r'individual'); + static const raw = CallRecordingStoppedEventRecordingTypeEnum._(r'raw'); + + /// List of all possible values in this [enum][CallRecordingStoppedEventRecordingTypeEnum]. + static const values = [ + composite, + individual, + raw, + ]; + + static CallRecordingStoppedEventRecordingTypeEnum? fromJson(dynamic value) => + CallRecordingStoppedEventRecordingTypeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = CallRecordingStoppedEventRecordingTypeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [CallRecordingStoppedEventRecordingTypeEnum] to String, +/// and [decode] dynamic data back to [CallRecordingStoppedEventRecordingTypeEnum]. +class CallRecordingStoppedEventRecordingTypeEnumTypeTransformer { + factory CallRecordingStoppedEventRecordingTypeEnumTypeTransformer() => + _instance ??= + const CallRecordingStoppedEventRecordingTypeEnumTypeTransformer._(); + + const CallRecordingStoppedEventRecordingTypeEnumTypeTransformer._(); + + String encode(CallRecordingStoppedEventRecordingTypeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a CallRecordingStoppedEventRecordingTypeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + CallRecordingStoppedEventRecordingTypeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'composite': + return CallRecordingStoppedEventRecordingTypeEnum.composite; + case r'individual': + return CallRecordingStoppedEventRecordingTypeEnum.individual; + case r'raw': + return CallRecordingStoppedEventRecordingTypeEnum.raw; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [CallRecordingStoppedEventRecordingTypeEnumTypeTransformer] instance. + static CallRecordingStoppedEventRecordingTypeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_response.dart index 906381f82..1a102cab5 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_response.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_response.dart @@ -28,6 +28,7 @@ class CallResponse { required this.ingress, this.joinAheadTimeSeconds, required this.recording, + this.routingNumber, this.session, required this.settings, this.startsAt, @@ -92,6 +93,15 @@ class CallResponse { bool recording; + /// 10-digit routing number for SIP routing + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? routingNumber; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -156,6 +166,7 @@ class CallResponse { other.ingress == ingress && other.joinAheadTimeSeconds == joinAheadTimeSeconds && other.recording == recording && + other.routingNumber == routingNumber && other.session == session && other.settings == settings && other.startsAt == startsAt && @@ -184,6 +195,7 @@ class CallResponse { (ingress.hashCode) + (joinAheadTimeSeconds == null ? 0 : joinAheadTimeSeconds!.hashCode) + (recording.hashCode) + + (routingNumber == null ? 0 : routingNumber!.hashCode) + (session == null ? 0 : session!.hashCode) + (settings.hashCode) + (startsAt == null ? 0 : startsAt!.hashCode) + @@ -196,7 +208,7 @@ class CallResponse { @override String toString() => - 'CallResponse[backstage=$backstage, blockedUserIds=$blockedUserIds, captioning=$captioning, channelCid=$channelCid, cid=$cid, createdAt=$createdAt, createdBy=$createdBy, currentSessionId=$currentSessionId, custom=$custom, egress=$egress, endedAt=$endedAt, id=$id, ingress=$ingress, joinAheadTimeSeconds=$joinAheadTimeSeconds, recording=$recording, session=$session, settings=$settings, startsAt=$startsAt, team=$team, thumbnails=$thumbnails, transcribing=$transcribing, translating=$translating, type=$type, updatedAt=$updatedAt]'; + 'CallResponse[backstage=$backstage, blockedUserIds=$blockedUserIds, captioning=$captioning, channelCid=$channelCid, cid=$cid, createdAt=$createdAt, createdBy=$createdBy, currentSessionId=$currentSessionId, custom=$custom, egress=$egress, endedAt=$endedAt, id=$id, ingress=$ingress, joinAheadTimeSeconds=$joinAheadTimeSeconds, recording=$recording, routingNumber=$routingNumber, session=$session, settings=$settings, startsAt=$startsAt, team=$team, thumbnails=$thumbnails, transcribing=$transcribing, translating=$translating, type=$type, updatedAt=$updatedAt]'; Map toJson() { final json = {}; @@ -227,6 +239,11 @@ class CallResponse { json[r'join_ahead_time_seconds'] = null; } json[r'recording'] = this.recording; + if (this.routingNumber != null) { + json[r'routing_number'] = this.routingNumber; + } else { + json[r'routing_number'] = null; + } if (this.session != null) { json[r'session'] = this.session; } else { @@ -296,6 +313,7 @@ class CallResponse { joinAheadTimeSeconds: mapValueOfType(json, r'join_ahead_time_seconds'), recording: mapValueOfType(json, r'recording')!, + routingNumber: mapValueOfType(json, r'routing_number'), session: CallSessionResponse.fromJson(json[r'session']), settings: CallSettingsResponse.fromJson(json[r'settings'])!, startsAt: mapDateTime(json, r'starts_at', r''), diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_request.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_request.dart index bbbdefdc9..f4f592ab0 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_request.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_request.dart @@ -18,8 +18,10 @@ class CallSettingsRequest { this.broadcasting, this.frameRecording, this.geofencing, + this.individualRecording, this.ingress, this.limits, + this.rawRecording, this.recording, this.ring, this.screensharing, @@ -69,6 +71,14 @@ class CallSettingsRequest { /// GeofenceSettingsRequest? geofencing; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + IndividualRecordingSettingsRequest? individualRecording; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -85,6 +95,14 @@ class CallSettingsRequest { /// LimitsSettingsRequest? limits; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + RawRecordingSettingsRequest? rawRecording; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -150,8 +168,10 @@ class CallSettingsRequest { other.broadcasting == broadcasting && other.frameRecording == frameRecording && other.geofencing == geofencing && + other.individualRecording == individualRecording && other.ingress == ingress && other.limits == limits && + other.rawRecording == rawRecording && other.recording == recording && other.ring == ring && other.screensharing == screensharing && @@ -168,8 +188,10 @@ class CallSettingsRequest { (broadcasting == null ? 0 : broadcasting!.hashCode) + (frameRecording == null ? 0 : frameRecording!.hashCode) + (geofencing == null ? 0 : geofencing!.hashCode) + + (individualRecording == null ? 0 : individualRecording!.hashCode) + (ingress == null ? 0 : ingress!.hashCode) + (limits == null ? 0 : limits!.hashCode) + + (rawRecording == null ? 0 : rawRecording!.hashCode) + (recording == null ? 0 : recording!.hashCode) + (ring == null ? 0 : ring!.hashCode) + (screensharing == null ? 0 : screensharing!.hashCode) + @@ -180,7 +202,7 @@ class CallSettingsRequest { @override String toString() => - 'CallSettingsRequest[audio=$audio, backstage=$backstage, broadcasting=$broadcasting, frameRecording=$frameRecording, geofencing=$geofencing, ingress=$ingress, limits=$limits, recording=$recording, ring=$ring, screensharing=$screensharing, session=$session, thumbnails=$thumbnails, transcription=$transcription, video=$video]'; + 'CallSettingsRequest[audio=$audio, backstage=$backstage, broadcasting=$broadcasting, frameRecording=$frameRecording, geofencing=$geofencing, individualRecording=$individualRecording, ingress=$ingress, limits=$limits, rawRecording=$rawRecording, recording=$recording, ring=$ring, screensharing=$screensharing, session=$session, thumbnails=$thumbnails, transcription=$transcription, video=$video]'; Map toJson() { final json = {}; @@ -209,6 +231,11 @@ class CallSettingsRequest { } else { json[r'geofencing'] = null; } + if (this.individualRecording != null) { + json[r'individual_recording'] = this.individualRecording; + } else { + json[r'individual_recording'] = null; + } if (this.ingress != null) { json[r'ingress'] = this.ingress; } else { @@ -219,6 +246,11 @@ class CallSettingsRequest { } else { json[r'limits'] = null; } + if (this.rawRecording != null) { + json[r'raw_recording'] = this.rawRecording; + } else { + json[r'raw_recording'] = null; + } if (this.recording != null) { json[r'recording'] = this.recording; } else { @@ -284,8 +316,12 @@ class CallSettingsRequest { frameRecording: FrameRecordingSettingsRequest.fromJson(json[r'frame_recording']), geofencing: GeofenceSettingsRequest.fromJson(json[r'geofencing']), + individualRecording: IndividualRecordingSettingsRequest.fromJson( + json[r'individual_recording']), ingress: IngressSettingsRequest.fromJson(json[r'ingress']), limits: LimitsSettingsRequest.fromJson(json[r'limits']), + rawRecording: + RawRecordingSettingsRequest.fromJson(json[r'raw_recording']), recording: RecordSettingsRequest.fromJson(json[r'recording']), ring: RingSettingsRequest.fromJson(json[r'ring']), screensharing: diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_response.dart index 2f3fb06f6..8b899b997 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_response.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/call_settings_response.dart @@ -18,8 +18,10 @@ class CallSettingsResponse { required this.broadcasting, required this.frameRecording, required this.geofencing, + required this.individualRecording, this.ingress, required this.limits, + required this.rawRecording, required this.recording, required this.ring, required this.screensharing, @@ -39,6 +41,8 @@ class CallSettingsResponse { GeofenceSettingsResponse geofencing; + IndividualRecordingSettingsResponse individualRecording; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -49,6 +53,8 @@ class CallSettingsResponse { LimitsSettingsResponse limits; + RawRecordingSettingsResponse rawRecording; + RecordSettingsResponse recording; RingSettingsResponse ring; @@ -72,8 +78,10 @@ class CallSettingsResponse { other.broadcasting == broadcasting && other.frameRecording == frameRecording && other.geofencing == geofencing && + other.individualRecording == individualRecording && other.ingress == ingress && other.limits == limits && + other.rawRecording == rawRecording && other.recording == recording && other.ring == ring && other.screensharing == screensharing && @@ -90,8 +98,10 @@ class CallSettingsResponse { (broadcasting.hashCode) + (frameRecording.hashCode) + (geofencing.hashCode) + + (individualRecording.hashCode) + (ingress == null ? 0 : ingress!.hashCode) + (limits.hashCode) + + (rawRecording.hashCode) + (recording.hashCode) + (ring.hashCode) + (screensharing.hashCode) + @@ -102,7 +112,7 @@ class CallSettingsResponse { @override String toString() => - 'CallSettingsResponse[audio=$audio, backstage=$backstage, broadcasting=$broadcasting, frameRecording=$frameRecording, geofencing=$geofencing, ingress=$ingress, limits=$limits, recording=$recording, ring=$ring, screensharing=$screensharing, session=$session, thumbnails=$thumbnails, transcription=$transcription, video=$video]'; + 'CallSettingsResponse[audio=$audio, backstage=$backstage, broadcasting=$broadcasting, frameRecording=$frameRecording, geofencing=$geofencing, individualRecording=$individualRecording, ingress=$ingress, limits=$limits, rawRecording=$rawRecording, recording=$recording, ring=$ring, screensharing=$screensharing, session=$session, thumbnails=$thumbnails, transcription=$transcription, video=$video]'; Map toJson() { final json = {}; @@ -111,12 +121,14 @@ class CallSettingsResponse { json[r'broadcasting'] = this.broadcasting; json[r'frame_recording'] = this.frameRecording; json[r'geofencing'] = this.geofencing; + json[r'individual_recording'] = this.individualRecording; if (this.ingress != null) { json[r'ingress'] = this.ingress; } else { json[r'ingress'] = null; } json[r'limits'] = this.limits; + json[r'raw_recording'] = this.rawRecording; json[r'recording'] = this.recording; json[r'ring'] = this.ring; json[r'screensharing'] = this.screensharing; @@ -155,8 +167,12 @@ class CallSettingsResponse { frameRecording: FrameRecordingSettingsResponse.fromJson(json[r'frame_recording'])!, geofencing: GeofenceSettingsResponse.fromJson(json[r'geofencing'])!, + individualRecording: IndividualRecordingSettingsResponse.fromJson( + json[r'individual_recording'])!, ingress: IngressSettingsResponse.fromJson(json[r'ingress']), limits: LimitsSettingsResponse.fromJson(json[r'limits'])!, + rawRecording: + RawRecordingSettingsResponse.fromJson(json[r'raw_recording'])!, recording: RecordSettingsResponse.fromJson(json[r'recording'])!, ring: RingSettingsResponse.fromJson(json[r'ring'])!, screensharing: @@ -227,7 +243,9 @@ class CallSettingsResponse { 'broadcasting', 'frame_recording', 'geofencing', + 'individual_recording', 'limits', + 'raw_recording', 'recording', 'ring', 'screensharing', diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/feeds_preferences_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/feeds_preferences_response.dart new file mode 100644 index 000000000..993ad4164 --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/feeds_preferences_response.dart @@ -0,0 +1,208 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class FeedsPreferencesResponse { + /// Returns a new [FeedsPreferencesResponse] instance. + FeedsPreferencesResponse({ + this.comment, + this.commentReaction, + this.customActivityTypes = const {}, + this.follow, + this.mention, + this.reaction, + }); + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? comment; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? commentReaction; + + Map customActivityTypes; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? follow; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? mention; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? reaction; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is FeedsPreferencesResponse && + other.comment == comment && + other.commentReaction == commentReaction && + _deepEquality.equals( + other.customActivityTypes, customActivityTypes) && + other.follow == follow && + other.mention == mention && + other.reaction == reaction; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (comment == null ? 0 : comment!.hashCode) + + (commentReaction == null ? 0 : commentReaction!.hashCode) + + (customActivityTypes.hashCode) + + (follow == null ? 0 : follow!.hashCode) + + (mention == null ? 0 : mention!.hashCode) + + (reaction == null ? 0 : reaction!.hashCode); + + @override + String toString() => + 'FeedsPreferencesResponse[comment=$comment, commentReaction=$commentReaction, customActivityTypes=$customActivityTypes, follow=$follow, mention=$mention, reaction=$reaction]'; + + Map toJson() { + final json = {}; + if (this.comment != null) { + json[r'comment'] = this.comment; + } else { + json[r'comment'] = null; + } + if (this.commentReaction != null) { + json[r'comment_reaction'] = this.commentReaction; + } else { + json[r'comment_reaction'] = null; + } + json[r'custom_activity_types'] = this.customActivityTypes; + if (this.follow != null) { + json[r'follow'] = this.follow; + } else { + json[r'follow'] = null; + } + if (this.mention != null) { + json[r'mention'] = this.mention; + } else { + json[r'mention'] = null; + } + if (this.reaction != null) { + json[r'reaction'] = this.reaction; + } else { + json[r'reaction'] = null; + } + return json; + } + + /// Returns a new [FeedsPreferencesResponse] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static FeedsPreferencesResponse? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "FeedsPreferencesResponse[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "FeedsPreferencesResponse[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return FeedsPreferencesResponse( + comment: mapValueOfType(json, r'comment'), + commentReaction: mapValueOfType(json, r'comment_reaction'), + customActivityTypes: + mapCastOfType(json, r'custom_activity_types') ?? + const {}, + follow: mapValueOfType(json, r'follow'), + mention: mapValueOfType(json, r'mention'), + reaction: mapValueOfType(json, r'reaction'), + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = FeedsPreferencesResponse.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = FeedsPreferencesResponse.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of FeedsPreferencesResponse-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = FeedsPreferencesResponse.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = {}; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/get_call_report_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/get_call_report_response.dart index 9e072c829..87df64793 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/get_call_report_response.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/get_call_report_response.dart @@ -16,6 +16,7 @@ class GetCallReportResponse { this.chatActivity, required this.duration, required this.report, + this.session, required this.sessionId, this.videoReactions = const [], }); @@ -33,6 +34,14 @@ class GetCallReportResponse { ReportResponse report; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + CallSessionResponse? session; + String sessionId; List videoReactions; @@ -44,6 +53,7 @@ class GetCallReportResponse { other.chatActivity == chatActivity && other.duration == duration && other.report == report && + other.session == session && other.sessionId == sessionId && _deepEquality.equals(other.videoReactions, videoReactions); @@ -53,12 +63,13 @@ class GetCallReportResponse { (chatActivity == null ? 0 : chatActivity!.hashCode) + (duration.hashCode) + (report.hashCode) + + (session == null ? 0 : session!.hashCode) + (sessionId.hashCode) + (videoReactions.hashCode); @override String toString() => - 'GetCallReportResponse[chatActivity=$chatActivity, duration=$duration, report=$report, sessionId=$sessionId, videoReactions=$videoReactions]'; + 'GetCallReportResponse[chatActivity=$chatActivity, duration=$duration, report=$report, session=$session, sessionId=$sessionId, videoReactions=$videoReactions]'; Map toJson() { final json = {}; @@ -69,6 +80,11 @@ class GetCallReportResponse { } json[r'duration'] = this.duration; json[r'report'] = this.report; + if (this.session != null) { + json[r'session'] = this.session; + } else { + json[r'session'] = null; + } json[r'session_id'] = this.sessionId; json[r'video_reactions'] = this.videoReactions; return json; @@ -99,6 +115,7 @@ class GetCallReportResponse { ChatActivityStatsResponse.fromJson(json[r'chat_activity']), duration: mapValueOfType(json, r'duration')!, report: ReportResponse.fromJson(json[r'report'])!, + session: CallSessionResponse.fromJson(json[r'session']), sessionId: mapValueOfType(json, r'session_id')!, videoReactions: VideoReactionsResponse.listFromJson(json[r'video_reactions']), diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/go_live_request.dart b/packages/stream_video/lib/open_api/video/coordinator/model/go_live_request.dart index 60a58576d..6a8b82d32 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/go_live_request.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/go_live_request.dart @@ -15,7 +15,10 @@ class GoLiveRequest { GoLiveRequest({ this.recordingStorageName, this.startClosedCaption, + this.startCompositeRecording, this.startHls, + this.startIndividualRecording, + this.startRawRecording, this.startRecording, this.startTranscription, this.transcriptionStorageName, @@ -37,6 +40,14 @@ class GoLiveRequest { /// bool? startClosedCaption; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? startCompositeRecording; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -45,6 +56,22 @@ class GoLiveRequest { /// bool? startHls; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? startIndividualRecording; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? startRawRecording; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -75,7 +102,10 @@ class GoLiveRequest { other is GoLiveRequest && other.recordingStorageName == recordingStorageName && other.startClosedCaption == startClosedCaption && + other.startCompositeRecording == startCompositeRecording && other.startHls == startHls && + other.startIndividualRecording == startIndividualRecording && + other.startRawRecording == startRawRecording && other.startRecording == startRecording && other.startTranscription == startTranscription && other.transcriptionStorageName == transcriptionStorageName; @@ -85,7 +115,14 @@ class GoLiveRequest { // ignore: unnecessary_parenthesis (recordingStorageName == null ? 0 : recordingStorageName!.hashCode) + (startClosedCaption == null ? 0 : startClosedCaption!.hashCode) + + (startCompositeRecording == null + ? 0 + : startCompositeRecording!.hashCode) + (startHls == null ? 0 : startHls!.hashCode) + + (startIndividualRecording == null + ? 0 + : startIndividualRecording!.hashCode) + + (startRawRecording == null ? 0 : startRawRecording!.hashCode) + (startRecording == null ? 0 : startRecording!.hashCode) + (startTranscription == null ? 0 : startTranscription!.hashCode) + (transcriptionStorageName == null @@ -94,7 +131,7 @@ class GoLiveRequest { @override String toString() => - 'GoLiveRequest[recordingStorageName=$recordingStorageName, startClosedCaption=$startClosedCaption, startHls=$startHls, startRecording=$startRecording, startTranscription=$startTranscription, transcriptionStorageName=$transcriptionStorageName]'; + 'GoLiveRequest[recordingStorageName=$recordingStorageName, startClosedCaption=$startClosedCaption, startCompositeRecording=$startCompositeRecording, startHls=$startHls, startIndividualRecording=$startIndividualRecording, startRawRecording=$startRawRecording, startRecording=$startRecording, startTranscription=$startTranscription, transcriptionStorageName=$transcriptionStorageName]'; Map toJson() { final json = {}; @@ -108,11 +145,26 @@ class GoLiveRequest { } else { json[r'start_closed_caption'] = null; } + if (this.startCompositeRecording != null) { + json[r'start_composite_recording'] = this.startCompositeRecording; + } else { + json[r'start_composite_recording'] = null; + } if (this.startHls != null) { json[r'start_hls'] = this.startHls; } else { json[r'start_hls'] = null; } + if (this.startIndividualRecording != null) { + json[r'start_individual_recording'] = this.startIndividualRecording; + } else { + json[r'start_individual_recording'] = null; + } + if (this.startRawRecording != null) { + json[r'start_raw_recording'] = this.startRawRecording; + } else { + json[r'start_raw_recording'] = null; + } if (this.startRecording != null) { json[r'start_recording'] = this.startRecording; } else { @@ -155,7 +207,12 @@ class GoLiveRequest { recordingStorageName: mapValueOfType(json, r'recording_storage_name'), startClosedCaption: mapValueOfType(json, r'start_closed_caption'), + startCompositeRecording: + mapValueOfType(json, r'start_composite_recording'), startHls: mapValueOfType(json, r'start_hls'), + startIndividualRecording: + mapValueOfType(json, r'start_individual_recording'), + startRawRecording: mapValueOfType(json, r'start_raw_recording'), startRecording: mapValueOfType(json, r'start_recording'), startTranscription: mapValueOfType(json, r'start_transcription'), transcriptionStorageName: diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_response.dart new file mode 100644 index 000000000..f6448d167 --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_response.dart @@ -0,0 +1,120 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class IndividualRecordingResponse { + /// Returns a new [IndividualRecordingResponse] instance. + IndividualRecordingResponse({ + required this.status, + }); + + String status; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is IndividualRecordingResponse && other.status == status; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (status.hashCode); + + @override + String toString() => 'IndividualRecordingResponse[status=$status]'; + + Map toJson() { + final json = {}; + json[r'status'] = this.status; + return json; + } + + /// Returns a new [IndividualRecordingResponse] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static IndividualRecordingResponse? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "IndividualRecordingResponse[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "IndividualRecordingResponse[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return IndividualRecordingResponse( + status: mapValueOfType(json, r'status')!, + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = IndividualRecordingResponse.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = IndividualRecordingResponse.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of IndividualRecordingResponse-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = IndividualRecordingResponse.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'status', + }; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_settings_request.dart b/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_settings_request.dart new file mode 100644 index 000000000..c5b9cb81e --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_settings_request.dart @@ -0,0 +1,210 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class IndividualRecordingSettingsRequest { + /// Returns a new [IndividualRecordingSettingsRequest] instance. + IndividualRecordingSettingsRequest({ + required this.mode, + }); + + IndividualRecordingSettingsRequestModeEnum mode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is IndividualRecordingSettingsRequest && other.mode == mode; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (mode.hashCode); + + @override + String toString() => 'IndividualRecordingSettingsRequest[mode=$mode]'; + + Map toJson() { + final json = {}; + json[r'mode'] = this.mode; + return json; + } + + /// Returns a new [IndividualRecordingSettingsRequest] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static IndividualRecordingSettingsRequest? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "IndividualRecordingSettingsRequest[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "IndividualRecordingSettingsRequest[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return IndividualRecordingSettingsRequest( + mode: + IndividualRecordingSettingsRequestModeEnum.fromJson(json[r'mode'])!, + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = IndividualRecordingSettingsRequest.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson( + dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = IndividualRecordingSettingsRequest.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of IndividualRecordingSettingsRequest-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = IndividualRecordingSettingsRequest.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'mode', + }; +} + +class IndividualRecordingSettingsRequestModeEnum { + /// Instantiate a new enum with the provided [value]. + const IndividualRecordingSettingsRequestModeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const available = + IndividualRecordingSettingsRequestModeEnum._(r'available'); + static const disabled = + IndividualRecordingSettingsRequestModeEnum._(r'disabled'); + static const autoOn = + IndividualRecordingSettingsRequestModeEnum._(r'auto-on'); + + /// List of all possible values in this [enum][IndividualRecordingSettingsRequestModeEnum]. + static const values = [ + available, + disabled, + autoOn, + ]; + + static IndividualRecordingSettingsRequestModeEnum? fromJson(dynamic value) => + IndividualRecordingSettingsRequestModeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = IndividualRecordingSettingsRequestModeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [IndividualRecordingSettingsRequestModeEnum] to String, +/// and [decode] dynamic data back to [IndividualRecordingSettingsRequestModeEnum]. +class IndividualRecordingSettingsRequestModeEnumTypeTransformer { + factory IndividualRecordingSettingsRequestModeEnumTypeTransformer() => + _instance ??= + const IndividualRecordingSettingsRequestModeEnumTypeTransformer._(); + + const IndividualRecordingSettingsRequestModeEnumTypeTransformer._(); + + String encode(IndividualRecordingSettingsRequestModeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a IndividualRecordingSettingsRequestModeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + IndividualRecordingSettingsRequestModeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'available': + return IndividualRecordingSettingsRequestModeEnum.available; + case r'disabled': + return IndividualRecordingSettingsRequestModeEnum.disabled; + case r'auto-on': + return IndividualRecordingSettingsRequestModeEnum.autoOn; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [IndividualRecordingSettingsRequestModeEnumTypeTransformer] instance. + static IndividualRecordingSettingsRequestModeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_settings_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_settings_response.dart new file mode 100644 index 000000000..f58cfd74e --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/individual_recording_settings_response.dart @@ -0,0 +1,211 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class IndividualRecordingSettingsResponse { + /// Returns a new [IndividualRecordingSettingsResponse] instance. + IndividualRecordingSettingsResponse({ + required this.mode, + }); + + IndividualRecordingSettingsResponseModeEnum mode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is IndividualRecordingSettingsResponse && other.mode == mode; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (mode.hashCode); + + @override + String toString() => 'IndividualRecordingSettingsResponse[mode=$mode]'; + + Map toJson() { + final json = {}; + json[r'mode'] = this.mode; + return json; + } + + /// Returns a new [IndividualRecordingSettingsResponse] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static IndividualRecordingSettingsResponse? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "IndividualRecordingSettingsResponse[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "IndividualRecordingSettingsResponse[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return IndividualRecordingSettingsResponse( + mode: IndividualRecordingSettingsResponseModeEnum.fromJson( + json[r'mode'])!, + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = IndividualRecordingSettingsResponse.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson( + dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = IndividualRecordingSettingsResponse.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of IndividualRecordingSettingsResponse-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = IndividualRecordingSettingsResponse.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'mode', + }; +} + +class IndividualRecordingSettingsResponseModeEnum { + /// Instantiate a new enum with the provided [value]. + const IndividualRecordingSettingsResponseModeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const available = + IndividualRecordingSettingsResponseModeEnum._(r'available'); + static const disabled = + IndividualRecordingSettingsResponseModeEnum._(r'disabled'); + static const autoOn = + IndividualRecordingSettingsResponseModeEnum._(r'auto-on'); + + /// List of all possible values in this [enum][IndividualRecordingSettingsResponseModeEnum]. + static const values = [ + available, + disabled, + autoOn, + ]; + + static IndividualRecordingSettingsResponseModeEnum? fromJson(dynamic value) => + IndividualRecordingSettingsResponseModeEnumTypeTransformer() + .decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = IndividualRecordingSettingsResponseModeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [IndividualRecordingSettingsResponseModeEnum] to String, +/// and [decode] dynamic data back to [IndividualRecordingSettingsResponseModeEnum]. +class IndividualRecordingSettingsResponseModeEnumTypeTransformer { + factory IndividualRecordingSettingsResponseModeEnumTypeTransformer() => + _instance ??= + const IndividualRecordingSettingsResponseModeEnumTypeTransformer._(); + + const IndividualRecordingSettingsResponseModeEnumTypeTransformer._(); + + String encode(IndividualRecordingSettingsResponseModeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a IndividualRecordingSettingsResponseModeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + IndividualRecordingSettingsResponseModeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'available': + return IndividualRecordingSettingsResponseModeEnum.available; + case r'disabled': + return IndividualRecordingSettingsResponseModeEnum.disabled; + case r'auto-on': + return IndividualRecordingSettingsResponseModeEnum.autoOn; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [IndividualRecordingSettingsResponseModeEnumTypeTransformer] instance. + static IndividualRecordingSettingsResponseModeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/own_capability.dart b/packages/stream_video/lib/open_api/video/coordinator/model/own_capability.dart index 2d4105fca..7a8502adb 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/own_capability.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/own_capability.dart @@ -48,6 +48,9 @@ class OwnCapability { OwnCapability._(r'start-closed-captions-call'); static const startFrameRecordCall = OwnCapability._(r'start-frame-record-call'); + static const startIndividualRecordCall = + OwnCapability._(r'start-individual-record-call'); + static const startRawRecordCall = OwnCapability._(r'start-raw-record-call'); static const startRecordCall = OwnCapability._(r'start-record-call'); static const startTranscriptionCall = OwnCapability._(r'start-transcription-call'); @@ -55,6 +58,9 @@ class OwnCapability { static const stopClosedCaptionsCall = OwnCapability._(r'stop-closed-captions-call'); static const stopFrameRecordCall = OwnCapability._(r'stop-frame-record-call'); + static const stopIndividualRecordCall = + OwnCapability._(r'stop-individual-record-call'); + static const stopRawRecordCall = OwnCapability._(r'stop-raw-record-call'); static const stopRecordCall = OwnCapability._(r'stop-record-call'); static const stopTranscriptionCall = OwnCapability._(r'stop-transcription-call'); @@ -87,11 +93,15 @@ class OwnCapability { startBroadcastCall, startClosedCaptionsCall, startFrameRecordCall, + startIndividualRecordCall, + startRawRecordCall, startRecordCall, startTranscriptionCall, stopBroadcastCall, stopClosedCaptionsCall, stopFrameRecordCall, + stopIndividualRecordCall, + stopRawRecordCall, stopRecordCall, stopTranscriptionCall, updateCall, @@ -183,6 +193,10 @@ class OwnCapabilityTypeTransformer { return OwnCapability.startClosedCaptionsCall; case r'start-frame-record-call': return OwnCapability.startFrameRecordCall; + case r'start-individual-record-call': + return OwnCapability.startIndividualRecordCall; + case r'start-raw-record-call': + return OwnCapability.startRawRecordCall; case r'start-record-call': return OwnCapability.startRecordCall; case r'start-transcription-call': @@ -193,6 +207,10 @@ class OwnCapabilityTypeTransformer { return OwnCapability.stopClosedCaptionsCall; case r'stop-frame-record-call': return OwnCapability.stopFrameRecordCall; + case r'stop-individual-record-call': + return OwnCapability.stopIndividualRecordCall; + case r'stop-raw-record-call': + return OwnCapability.stopRawRecordCall; case r'stop-record-call': return OwnCapability.stopRecordCall; case r'stop-transcription-call': diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/own_user_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/own_user_response.dart index a2bef77c2..c6f8c95fb 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/own_user_response.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/own_user_response.dart @@ -108,7 +108,7 @@ class OwnUserResponse { /// source code must fall back to having a nullable type. /// Consider adding a "default:" property in the specification file to hide this note. /// - PushPreferences? pushPreferences; + PushPreferencesResponse? pushPreferences; /// /// Please note: This property should have been non-nullable! Since the specification file @@ -278,7 +278,8 @@ class OwnUserResponse { lastActive: mapDateTime(json, r'last_active', r''), name: mapValueOfType(json, r'name'), privacySettings: mapValueOfType(json, r'privacy_settings'), - pushPreferences: PushPreferences.fromJson(json[r'push_preferences']), + pushPreferences: + PushPreferencesResponse.fromJson(json[r'push_preferences']), revokeTokensIssuedBefore: mapDateTime(json, r'revoke_tokens_issued_before', r''), role: mapValueOfType(json, r'role')!, diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/push_preferences.dart b/packages/stream_video/lib/open_api/video/coordinator/model/push_preferences_response.dart similarity index 58% rename from packages/stream_video/lib/open_api/video/coordinator/model/push_preferences.dart rename to packages/stream_video/lib/open_api/video/coordinator/model/push_preferences_response.dart index 1e74ea11f..ce44ccff6 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/push_preferences.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/push_preferences_response.dart @@ -10,12 +10,14 @@ part of openapi.api; -class PushPreferences { - /// Returns a new [PushPreferences] instance. - PushPreferences({ +class PushPreferencesResponse { + /// Returns a new [PushPreferencesResponse] instance. + PushPreferencesResponse({ this.callLevel, this.chatLevel, this.disabledUntil, + this.feedsLevel, + this.feedsPreferences, }); /// @@ -42,24 +44,44 @@ class PushPreferences { /// DateTime? disabledUntil; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? feedsLevel; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + FeedsPreferencesResponse? feedsPreferences; + @override bool operator ==(Object other) => identical(this, other) || - other is PushPreferences && + other is PushPreferencesResponse && other.callLevel == callLevel && other.chatLevel == chatLevel && - other.disabledUntil == disabledUntil; + other.disabledUntil == disabledUntil && + other.feedsLevel == feedsLevel && + other.feedsPreferences == feedsPreferences; @override int get hashCode => // ignore: unnecessary_parenthesis (callLevel == null ? 0 : callLevel!.hashCode) + (chatLevel == null ? 0 : chatLevel!.hashCode) + - (disabledUntil == null ? 0 : disabledUntil!.hashCode); + (disabledUntil == null ? 0 : disabledUntil!.hashCode) + + (feedsLevel == null ? 0 : feedsLevel!.hashCode) + + (feedsPreferences == null ? 0 : feedsPreferences!.hashCode); @override String toString() => - 'PushPreferences[callLevel=$callLevel, chatLevel=$chatLevel, disabledUntil=$disabledUntil]'; + 'PushPreferencesResponse[callLevel=$callLevel, chatLevel=$chatLevel, disabledUntil=$disabledUntil, feedsLevel=$feedsLevel, feedsPreferences=$feedsPreferences]'; Map toJson() { final json = {}; @@ -78,13 +100,23 @@ class PushPreferences { } else { json[r'disabled_until'] = null; } + if (this.feedsLevel != null) { + json[r'feeds_level'] = this.feedsLevel; + } else { + json[r'feeds_level'] = null; + } + if (this.feedsPreferences != null) { + json[r'feeds_preferences'] = this.feedsPreferences; + } else { + json[r'feeds_preferences'] = null; + } return json; } - /// Returns a new [PushPreferences] instance and imports its values from + /// Returns a new [PushPreferencesResponse] instance and imports its values from /// [value] if it's a [Map], null otherwise. // ignore: prefer_constructors_over_static_methods - static PushPreferences? fromJson(dynamic value) { + static PushPreferencesResponse? fromJson(dynamic value) { if (value is Map) { final json = value.cast(); @@ -94,30 +126,33 @@ class PushPreferences { assert(() { requiredKeys.forEach((key) { assert(json.containsKey(key), - 'Required key "PushPreferences[$key]" is missing from JSON.'); + 'Required key "PushPreferencesResponse[$key]" is missing from JSON.'); assert(json[key] != null, - 'Required key "PushPreferences[$key]" has a null value in JSON.'); + 'Required key "PushPreferencesResponse[$key]" has a null value in JSON.'); }); return true; }()); - return PushPreferences( + return PushPreferencesResponse( callLevel: mapValueOfType(json, r'call_level'), chatLevel: mapValueOfType(json, r'chat_level'), disabledUntil: mapDateTime(json, r'disabled_until', r''), + feedsLevel: mapValueOfType(json, r'feeds_level'), + feedsPreferences: + FeedsPreferencesResponse.fromJson(json[r'feeds_preferences']), ); } return null; } - static List listFromJson( + static List listFromJson( dynamic json, { bool growable = false, }) { - final result = []; + final result = []; if (json is List && json.isNotEmpty) { for (final row in json) { - final value = PushPreferences.fromJson(row); + final value = PushPreferencesResponse.fromJson(row); if (value != null) { result.add(value); } @@ -126,12 +161,12 @@ class PushPreferences { return result.toList(growable: growable); } - static Map mapFromJson(dynamic json) { - final map = {}; + static Map mapFromJson(dynamic json) { + final map = {}; if (json is Map && json.isNotEmpty) { json = json.cast(); // ignore: parameter_assignments for (final entry in json.entries) { - final value = PushPreferences.fromJson(entry.value); + final value = PushPreferencesResponse.fromJson(entry.value); if (value != null) { map[entry.key] = value; } @@ -140,17 +175,17 @@ class PushPreferences { return map; } - // maps a json object with a list of PushPreferences-objects as value to a dart map - static Map> mapListFromJson( + // maps a json object with a list of PushPreferencesResponse-objects as value to a dart map + static Map> mapListFromJson( dynamic json, { bool growable = false, }) { - final map = >{}; + final map = >{}; if (json is Map && json.isNotEmpty) { // ignore: parameter_assignments json = json.cast(); for (final entry in json.entries) { - map[entry.key] = PushPreferences.listFromJson( + map[entry.key] = PushPreferencesResponse.listFromJson( entry.value, growable: growable, ); diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/raw_recording_settings_request.dart b/packages/stream_video/lib/open_api/video/coordinator/model/raw_recording_settings_request.dart new file mode 100644 index 000000000..b0c6d8905 --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/raw_recording_settings_request.dart @@ -0,0 +1,204 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RawRecordingSettingsRequest { + /// Returns a new [RawRecordingSettingsRequest] instance. + RawRecordingSettingsRequest({ + required this.mode, + }); + + RawRecordingSettingsRequestModeEnum mode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is RawRecordingSettingsRequest && other.mode == mode; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (mode.hashCode); + + @override + String toString() => 'RawRecordingSettingsRequest[mode=$mode]'; + + Map toJson() { + final json = {}; + json[r'mode'] = this.mode; + return json; + } + + /// Returns a new [RawRecordingSettingsRequest] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RawRecordingSettingsRequest? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "RawRecordingSettingsRequest[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "RawRecordingSettingsRequest[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return RawRecordingSettingsRequest( + mode: RawRecordingSettingsRequestModeEnum.fromJson(json[r'mode'])!, + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = RawRecordingSettingsRequest.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = RawRecordingSettingsRequest.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RawRecordingSettingsRequest-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = RawRecordingSettingsRequest.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'mode', + }; +} + +class RawRecordingSettingsRequestModeEnum { + /// Instantiate a new enum with the provided [value]. + const RawRecordingSettingsRequestModeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const available = RawRecordingSettingsRequestModeEnum._(r'available'); + static const disabled = RawRecordingSettingsRequestModeEnum._(r'disabled'); + static const autoOn = RawRecordingSettingsRequestModeEnum._(r'auto-on'); + + /// List of all possible values in this [enum][RawRecordingSettingsRequestModeEnum]. + static const values = [ + available, + disabled, + autoOn, + ]; + + static RawRecordingSettingsRequestModeEnum? fromJson(dynamic value) => + RawRecordingSettingsRequestModeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = RawRecordingSettingsRequestModeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [RawRecordingSettingsRequestModeEnum] to String, +/// and [decode] dynamic data back to [RawRecordingSettingsRequestModeEnum]. +class RawRecordingSettingsRequestModeEnumTypeTransformer { + factory RawRecordingSettingsRequestModeEnumTypeTransformer() => _instance ??= + const RawRecordingSettingsRequestModeEnumTypeTransformer._(); + + const RawRecordingSettingsRequestModeEnumTypeTransformer._(); + + String encode(RawRecordingSettingsRequestModeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a RawRecordingSettingsRequestModeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + RawRecordingSettingsRequestModeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'available': + return RawRecordingSettingsRequestModeEnum.available; + case r'disabled': + return RawRecordingSettingsRequestModeEnum.disabled; + case r'auto-on': + return RawRecordingSettingsRequestModeEnum.autoOn; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [RawRecordingSettingsRequestModeEnumTypeTransformer] instance. + static RawRecordingSettingsRequestModeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/raw_recording_settings_response.dart b/packages/stream_video/lib/open_api/video/coordinator/model/raw_recording_settings_response.dart new file mode 100644 index 000000000..7f8b7e742 --- /dev/null +++ b/packages/stream_video/lib/open_api/video/coordinator/model/raw_recording_settings_response.dart @@ -0,0 +1,204 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RawRecordingSettingsResponse { + /// Returns a new [RawRecordingSettingsResponse] instance. + RawRecordingSettingsResponse({ + required this.mode, + }); + + RawRecordingSettingsResponseModeEnum mode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is RawRecordingSettingsResponse && other.mode == mode; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (mode.hashCode); + + @override + String toString() => 'RawRecordingSettingsResponse[mode=$mode]'; + + Map toJson() { + final json = {}; + json[r'mode'] = this.mode; + return json; + } + + /// Returns a new [RawRecordingSettingsResponse] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RawRecordingSettingsResponse? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), + 'Required key "RawRecordingSettingsResponse[$key]" is missing from JSON.'); + assert(json[key] != null, + 'Required key "RawRecordingSettingsResponse[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return RawRecordingSettingsResponse( + mode: RawRecordingSettingsResponseModeEnum.fromJson(json[r'mode'])!, + ); + } + return null; + } + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = RawRecordingSettingsResponse.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = RawRecordingSettingsResponse.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RawRecordingSettingsResponse-objects as value to a dart map + static Map> mapListFromJson( + dynamic json, { + bool growable = false, + }) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = RawRecordingSettingsResponse.listFromJson( + entry.value, + growable: growable, + ); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'mode', + }; +} + +class RawRecordingSettingsResponseModeEnum { + /// Instantiate a new enum with the provided [value]. + const RawRecordingSettingsResponseModeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const available = RawRecordingSettingsResponseModeEnum._(r'available'); + static const disabled = RawRecordingSettingsResponseModeEnum._(r'disabled'); + static const autoOn = RawRecordingSettingsResponseModeEnum._(r'auto-on'); + + /// List of all possible values in this [enum][RawRecordingSettingsResponseModeEnum]. + static const values = [ + available, + disabled, + autoOn, + ]; + + static RawRecordingSettingsResponseModeEnum? fromJson(dynamic value) => + RawRecordingSettingsResponseModeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = RawRecordingSettingsResponseModeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [RawRecordingSettingsResponseModeEnum] to String, +/// and [decode] dynamic data back to [RawRecordingSettingsResponseModeEnum]. +class RawRecordingSettingsResponseModeEnumTypeTransformer { + factory RawRecordingSettingsResponseModeEnumTypeTransformer() => _instance ??= + const RawRecordingSettingsResponseModeEnumTypeTransformer._(); + + const RawRecordingSettingsResponseModeEnumTypeTransformer._(); + + String encode(RawRecordingSettingsResponseModeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a RawRecordingSettingsResponseModeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + RawRecordingSettingsResponseModeEnum? decode(dynamic data, + {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'available': + return RawRecordingSettingsResponseModeEnum.available; + case r'disabled': + return RawRecordingSettingsResponseModeEnum.disabled; + case r'auto-on': + return RawRecordingSettingsResponseModeEnum.autoOn; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [RawRecordingSettingsResponseModeEnumTypeTransformer] instance. + static RawRecordingSettingsResponseModeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/stop_live_request.dart b/packages/stream_video/lib/open_api/video/coordinator/model/stop_live_request.dart index 820469ff6..c96c220ee 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/stop_live_request.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/stop_live_request.dart @@ -14,7 +14,10 @@ class StopLiveRequest { /// Returns a new [StopLiveRequest] instance. StopLiveRequest({ this.continueClosedCaption, + this.continueCompositeRecording, this.continueHls, + this.continueIndividualRecording, + this.continueRawRecording, this.continueRecording, this.continueRtmpBroadcasts, this.continueTranscription, @@ -28,6 +31,14 @@ class StopLiveRequest { /// bool? continueClosedCaption; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? continueCompositeRecording; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -36,6 +47,22 @@ class StopLiveRequest { /// bool? continueHls; + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? continueIndividualRecording; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? continueRawRecording; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -65,7 +92,10 @@ class StopLiveRequest { identical(this, other) || other is StopLiveRequest && other.continueClosedCaption == continueClosedCaption && + other.continueCompositeRecording == continueCompositeRecording && other.continueHls == continueHls && + other.continueIndividualRecording == continueIndividualRecording && + other.continueRawRecording == continueRawRecording && other.continueRecording == continueRecording && other.continueRtmpBroadcasts == continueRtmpBroadcasts && other.continueTranscription == continueTranscription; @@ -74,14 +104,21 @@ class StopLiveRequest { int get hashCode => // ignore: unnecessary_parenthesis (continueClosedCaption == null ? 0 : continueClosedCaption!.hashCode) + + (continueCompositeRecording == null + ? 0 + : continueCompositeRecording!.hashCode) + (continueHls == null ? 0 : continueHls!.hashCode) + + (continueIndividualRecording == null + ? 0 + : continueIndividualRecording!.hashCode) + + (continueRawRecording == null ? 0 : continueRawRecording!.hashCode) + (continueRecording == null ? 0 : continueRecording!.hashCode) + (continueRtmpBroadcasts == null ? 0 : continueRtmpBroadcasts!.hashCode) + (continueTranscription == null ? 0 : continueTranscription!.hashCode); @override String toString() => - 'StopLiveRequest[continueClosedCaption=$continueClosedCaption, continueHls=$continueHls, continueRecording=$continueRecording, continueRtmpBroadcasts=$continueRtmpBroadcasts, continueTranscription=$continueTranscription]'; + 'StopLiveRequest[continueClosedCaption=$continueClosedCaption, continueCompositeRecording=$continueCompositeRecording, continueHls=$continueHls, continueIndividualRecording=$continueIndividualRecording, continueRawRecording=$continueRawRecording, continueRecording=$continueRecording, continueRtmpBroadcasts=$continueRtmpBroadcasts, continueTranscription=$continueTranscription]'; Map toJson() { final json = {}; @@ -90,11 +127,26 @@ class StopLiveRequest { } else { json[r'continue_closed_caption'] = null; } + if (this.continueCompositeRecording != null) { + json[r'continue_composite_recording'] = this.continueCompositeRecording; + } else { + json[r'continue_composite_recording'] = null; + } if (this.continueHls != null) { json[r'continue_hls'] = this.continueHls; } else { json[r'continue_hls'] = null; } + if (this.continueIndividualRecording != null) { + json[r'continue_individual_recording'] = this.continueIndividualRecording; + } else { + json[r'continue_individual_recording'] = null; + } + if (this.continueRawRecording != null) { + json[r'continue_raw_recording'] = this.continueRawRecording; + } else { + json[r'continue_raw_recording'] = null; + } if (this.continueRecording != null) { json[r'continue_recording'] = this.continueRecording; } else { @@ -136,7 +188,13 @@ class StopLiveRequest { return StopLiveRequest( continueClosedCaption: mapValueOfType(json, r'continue_closed_caption'), + continueCompositeRecording: + mapValueOfType(json, r'continue_composite_recording'), continueHls: mapValueOfType(json, r'continue_hls'), + continueIndividualRecording: + mapValueOfType(json, r'continue_individual_recording'), + continueRawRecording: + mapValueOfType(json, r'continue_raw_recording'), continueRecording: mapValueOfType(json, r'continue_recording'), continueRtmpBroadcasts: mapValueOfType(json, r'continue_rtmp_broadcasts'), diff --git a/packages/stream_video/lib/open_api/video/coordinator/model/video_event.dart b/packages/stream_video/lib/open_api/video/coordinator/model/video_event.dart index dda9c8bd7..2e8f30306 100644 --- a/packages/stream_video/lib/open_api/video/coordinator/model/video_event.dart +++ b/packages/stream_video/lib/open_api/video/coordinator/model/video_event.dart @@ -23,6 +23,10 @@ class VideoEvent { required this.user, required this.call, this.members = const [], + required this.digit, + required this.durationMs, + required this.seqNumber, + required this.timestamp, required this.reason, required this.egressId, required this.capturedAt, @@ -36,6 +40,7 @@ class VideoEvent { required this.userId, required this.message, required this.reaction, + required this.recordingType, required this.callRecording, required this.video, required this.name, @@ -54,6 +59,12 @@ class VideoEvent { required this.connectionId, required this.me, required this.cid, + this.code, + required this.ingressStreamId, + this.clientIp, + this.clientName, + required this.publisherType, + this.version, this.kickedByUser, this.permissions = const [], this.ownCapabilities = const [], @@ -102,6 +113,18 @@ class VideoEvent { /// Call members List members; + /// The DTMF digit (0-9, *, #, A-D) + String digit; + + /// Duration of the digit press in milliseconds + int durationMs; + + /// Monotonically increasing sequence number for ordering DTMF events within a session + int seqNumber; + + /// When the digit press ended and was detected + DateTime timestamp; + String reason; String egressId; @@ -128,7 +151,7 @@ class VideoEvent { bool notifyUser; - /// The user ID who is receiving the warning + /// User who was streaming String userId; /// The warning message @@ -136,6 +159,9 @@ class VideoEvent { ReactionResponse reaction; + /// The type of recording + VideoEventRecordingTypeEnum recordingType; + CallRecording callRecording; bool video; @@ -152,7 +178,8 @@ class VideoEvent { /// The duration participant was in the session in seconds int durationSeconds; - APIError error; + /// Human-readable error message + String error; CallTranscription callTranscription; @@ -187,6 +214,48 @@ class VideoEvent { String cid; + /// Error code + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? code; + + /// Unique identifier for the stream + String ingressStreamId; + + /// Client IP address + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? clientIp; + + /// Streaming client software name (e.g., 'OBS Studio') + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? clientName; + + /// Streaming protocol (e.g., 'rtmps', 'srt', 'rtmp', 'rtsp') + String publisherType; + + /// Client software version + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + String? version; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -249,6 +318,10 @@ class VideoEvent { other.user == user && other.call == call && _deepEquality.equals(other.members, members) && + other.digit == digit && + other.durationMs == durationMs && + other.seqNumber == seqNumber && + other.timestamp == timestamp && other.reason == reason && other.egressId == egressId && other.capturedAt == capturedAt && @@ -262,6 +335,7 @@ class VideoEvent { other.userId == userId && other.message == message && other.reaction == reaction && + other.recordingType == recordingType && other.callRecording == callRecording && other.video == video && other.name == name && @@ -281,6 +355,12 @@ class VideoEvent { other.connectionId == connectionId && other.me == me && other.cid == cid && + other.code == code && + other.ingressStreamId == ingressStreamId && + other.clientIp == clientIp && + other.clientName == clientName && + other.publisherType == publisherType && + other.version == version && other.kickedByUser == kickedByUser && _deepEquality.equals(other.permissions, permissions) && _deepEquality.equals(other.ownCapabilities, ownCapabilities) && @@ -306,6 +386,10 @@ class VideoEvent { (user.hashCode) + (call.hashCode) + (members.hashCode) + + (digit.hashCode) + + (durationMs.hashCode) + + (seqNumber.hashCode) + + (timestamp.hashCode) + (reason.hashCode) + (egressId.hashCode) + (capturedAt.hashCode) + @@ -319,6 +403,7 @@ class VideoEvent { (userId.hashCode) + (message.hashCode) + (reaction.hashCode) + + (recordingType.hashCode) + (callRecording.hashCode) + (video.hashCode) + (name.hashCode) + @@ -337,6 +422,12 @@ class VideoEvent { (connectionId.hashCode) + (me.hashCode) + (cid.hashCode) + + (code == null ? 0 : code!.hashCode) + + (ingressStreamId.hashCode) + + (clientIp == null ? 0 : clientIp!.hashCode) + + (clientName == null ? 0 : clientName!.hashCode) + + (publisherType.hashCode) + + (version == null ? 0 : version!.hashCode) + (kickedByUser == null ? 0 : kickedByUser!.hashCode) + (permissions.hashCode) + (ownCapabilities.hashCode) + @@ -351,7 +442,7 @@ class VideoEvent { @override String toString() => - 'VideoEvent[app=$app, createdAt=$createdAt, custom=$custom, receivedAt=$receivedAt, type=$type, blockedByUser=$blockedByUser, callCid=$callCid, user=$user, call=$call, members=$members, reason=$reason, egressId=$egressId, capturedAt=$capturedAt, sessionId=$sessionId, trackType=$trackType, url=$url, users=$users, hlsPlaylistUrl=$hlsPlaylistUrl, capabilitiesByRole=$capabilitiesByRole, notifyUser=$notifyUser, userId=$userId, message=$message, reaction=$reaction, callRecording=$callRecording, video=$video, name=$name, anonymousParticipantCount=$anonymousParticipantCount, participantsCountByRole=$participantsCountByRole, participant=$participant, durationSeconds=$durationSeconds, error=$error, callTranscription=$callTranscription, rating=$rating, sdk=$sdk, sdkVersion=$sdkVersion, fromUserId=$fromUserId, mutedUserIds=$mutedUserIds, closedCaption=$closedCaption, connectionId=$connectionId, me=$me, cid=$cid, kickedByUser=$kickedByUser, permissions=$permissions, ownCapabilities=$ownCapabilities, channelId=$channelId, channelType=$channelType, createdBy=$createdBy, expiration=$expiration, shadow=$shadow, team=$team, targetUser=$targetUser, targetUsers=$targetUsers]'; + 'VideoEvent[app=$app, createdAt=$createdAt, custom=$custom, receivedAt=$receivedAt, type=$type, blockedByUser=$blockedByUser, callCid=$callCid, user=$user, call=$call, members=$members, digit=$digit, durationMs=$durationMs, seqNumber=$seqNumber, timestamp=$timestamp, reason=$reason, egressId=$egressId, capturedAt=$capturedAt, sessionId=$sessionId, trackType=$trackType, url=$url, users=$users, hlsPlaylistUrl=$hlsPlaylistUrl, capabilitiesByRole=$capabilitiesByRole, notifyUser=$notifyUser, userId=$userId, message=$message, reaction=$reaction, recordingType=$recordingType, callRecording=$callRecording, video=$video, name=$name, anonymousParticipantCount=$anonymousParticipantCount, participantsCountByRole=$participantsCountByRole, participant=$participant, durationSeconds=$durationSeconds, error=$error, callTranscription=$callTranscription, rating=$rating, sdk=$sdk, sdkVersion=$sdkVersion, fromUserId=$fromUserId, mutedUserIds=$mutedUserIds, closedCaption=$closedCaption, connectionId=$connectionId, me=$me, cid=$cid, code=$code, ingressStreamId=$ingressStreamId, clientIp=$clientIp, clientName=$clientName, publisherType=$publisherType, version=$version, kickedByUser=$kickedByUser, permissions=$permissions, ownCapabilities=$ownCapabilities, channelId=$channelId, channelType=$channelType, createdBy=$createdBy, expiration=$expiration, shadow=$shadow, team=$team, targetUser=$targetUser, targetUsers=$targetUsers]'; Map toJson() { final json = {}; @@ -373,6 +464,10 @@ class VideoEvent { json[r'user'] = this.user; json[r'call'] = this.call; json[r'members'] = this.members; + json[r'digit'] = this.digit; + json[r'duration_ms'] = this.durationMs; + json[r'seq_number'] = this.seqNumber; + json[r'timestamp'] = this.timestamp.toUtc().toIso8601String(); json[r'reason'] = this.reason; json[r'egress_id'] = this.egressId; json[r'captured_at'] = this.capturedAt.toUtc().toIso8601String(); @@ -386,6 +481,7 @@ class VideoEvent { json[r'user_id'] = this.userId; json[r'message'] = this.message; json[r'reaction'] = this.reaction; + json[r'recording_type'] = this.recordingType; json[r'call_recording'] = this.callRecording; json[r'video'] = this.video; json[r'name'] = this.name; @@ -412,6 +508,28 @@ class VideoEvent { json[r'connection_id'] = this.connectionId; json[r'me'] = this.me; json[r'cid'] = this.cid; + if (this.code != null) { + json[r'code'] = this.code; + } else { + json[r'code'] = null; + } + json[r'ingress_stream_id'] = this.ingressStreamId; + if (this.clientIp != null) { + json[r'client_ip'] = this.clientIp; + } else { + json[r'client_ip'] = null; + } + if (this.clientName != null) { + json[r'client_name'] = this.clientName; + } else { + json[r'client_name'] = null; + } + json[r'publisher_type'] = this.publisherType; + if (this.version != null) { + json[r'version'] = this.version; + } else { + json[r'version'] = null; + } if (this.kickedByUser != null) { json[r'kicked_by_user'] = this.kickedByUser; } else { @@ -473,6 +591,10 @@ class VideoEvent { user: UserResponsePrivacyFields.fromJson(json[r'user'])!, call: CallResponse.fromJson(json[r'call'])!, members: MemberResponse.listFromJson(json[r'members']), + digit: mapValueOfType(json, r'digit')!, + durationMs: mapValueOfType(json, r'duration_ms')!, + seqNumber: mapValueOfType(json, r'seq_number')!, + timestamp: mapDateTime(json, r'timestamp', r'')!, reason: mapValueOfType(json, r'reason')!, egressId: mapValueOfType(json, r'egress_id')!, capturedAt: mapDateTime(json, r'captured_at', r'')!, @@ -489,6 +611,8 @@ class VideoEvent { userId: mapValueOfType(json, r'user_id')!, message: mapValueOfType(json, r'message')!, reaction: ReactionResponse.fromJson(json[r'reaction'])!, + recordingType: + VideoEventRecordingTypeEnum.fromJson(json[r'recording_type'])!, callRecording: CallRecording.fromJson(json[r'call_recording'])!, video: mapValueOfType(json, r'video')!, name: mapValueOfType(json, r'name')!, @@ -498,7 +622,7 @@ class VideoEvent { mapCastOfType(json, r'participants_count_by_role')!, participant: CallParticipantResponse.fromJson(json[r'participant'])!, durationSeconds: mapValueOfType(json, r'duration_seconds')!, - error: APIError.fromJson(json[r'error'])!, + error: mapValueOfType(json, r'error')!, callTranscription: CallTranscription.fromJson(json[r'call_transcription'])!, rating: mapValueOfType(json, r'rating')!, @@ -514,6 +638,12 @@ class VideoEvent { connectionId: mapValueOfType(json, r'connection_id')!, me: OwnUserResponse.fromJson(json[r'me'])!, cid: mapValueOfType(json, r'cid')!, + code: mapValueOfType(json, r'code'), + ingressStreamId: mapValueOfType(json, r'ingress_stream_id')!, + clientIp: mapValueOfType(json, r'client_ip'), + clientName: mapValueOfType(json, r'client_name'), + publisherType: mapValueOfType(json, r'publisher_type')!, + version: mapValueOfType(json, r'version'), kickedByUser: UserResponse.fromJson(json[r'kicked_by_user']), permissions: json[r'permissions'] is Iterable ? (json[r'permissions'] as Iterable) @@ -615,6 +745,10 @@ class VideoEvent { 'user', 'call', 'members', + 'digit', + 'duration_ms', + 'seq_number', + 'timestamp', 'reason', 'egress_id', 'captured_at', @@ -628,6 +762,7 @@ class VideoEvent { 'user_id', 'message', 'reaction', + 'recording_type', 'call_recording', 'video', 'name', @@ -644,6 +779,8 @@ class VideoEvent { 'connection_id', 'me', 'cid', + 'ingress_stream_id', + 'publisher_type', 'permissions', 'own_capabilities', 'channel_id', @@ -652,3 +789,87 @@ class VideoEvent { 'shadow', }; } + +/// The type of recording +class VideoEventRecordingTypeEnum { + /// Instantiate a new enum with the provided [value]. + const VideoEventRecordingTypeEnum._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const composite = VideoEventRecordingTypeEnum._(r'composite'); + static const individual = VideoEventRecordingTypeEnum._(r'individual'); + static const raw = VideoEventRecordingTypeEnum._(r'raw'); + + /// List of all possible values in this [enum][VideoEventRecordingTypeEnum]. + static const values = [ + composite, + individual, + raw, + ]; + + static VideoEventRecordingTypeEnum? fromJson(dynamic value) => + VideoEventRecordingTypeEnumTypeTransformer().decode(value); + + static List listFromJson( + dynamic json, { + bool growable = false, + }) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = VideoEventRecordingTypeEnum.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [VideoEventRecordingTypeEnum] to String, +/// and [decode] dynamic data back to [VideoEventRecordingTypeEnum]. +class VideoEventRecordingTypeEnumTypeTransformer { + factory VideoEventRecordingTypeEnumTypeTransformer() => + _instance ??= const VideoEventRecordingTypeEnumTypeTransformer._(); + + const VideoEventRecordingTypeEnumTypeTransformer._(); + + String encode(VideoEventRecordingTypeEnum data) => data.value; + + /// Decodes a [dynamic value][data] to a VideoEventRecordingTypeEnum. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + VideoEventRecordingTypeEnum? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'composite': + return VideoEventRecordingTypeEnum.composite; + case r'individual': + return VideoEventRecordingTypeEnum.individual; + case r'raw': + return VideoEventRecordingTypeEnum.raw; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [VideoEventRecordingTypeEnumTypeTransformer] instance. + static VideoEventRecordingTypeEnumTypeTransformer? _instance; +} diff --git a/packages/stream_video/lib/src/call/call.dart b/packages/stream_video/lib/src/call/call.dart index 15074c5b1..5638d1350 100644 --- a/packages/stream_video/lib/src/call/call.dart +++ b/packages/stream_video/lib/src/call/call.dart @@ -1246,6 +1246,8 @@ class Call { /// - [broadcasting]: Broadcasting settings for the call. /// - [session]: Session settings for the call. /// - [frameRecording]: Frame recording settings for the call. + /// - [individualRecording]: Individual recording settings for the call. + /// - [rawRecording]: Raw recording settings for the call. Future> update({ Map? custom, DateTime? startsAt, @@ -1261,6 +1263,8 @@ class Call { StreamBroadcastingSettings? broadcasting, StreamSessionSettings? session, StreamFrameRecordingSettings? frameRecording, + StreamIndividualRecordingSettings? individualRecording, + StreamRawRecordingSettings? rawRecording, StreamIngressSettings? ingress, }) { return _coordinatorClient.updateCall( @@ -1279,6 +1283,8 @@ class Call { broadcasting: broadcasting, session: session, frameRecording: frameRecording, + individualRecording: individualRecording, + rawRecording: rawRecording, ingress: ingress, ); } @@ -2392,6 +2398,8 @@ class Call { /// - [broadcasting]: Broadcasting settings for the call. /// - [session]: Session settings for the call. /// - [frameRecording]: Frame recording settings for the call. + /// - [individualRecording]: Individual recording settings for the call. + /// - [rawRecording]: Raw recording settings for the call. Future> getOrCreate({ List memberIds = const [], List members = const [], @@ -2415,6 +2423,8 @@ class Call { StreamSessionSettings? session, StreamIngressSettings? ingress, StreamFrameRecordingSettings? frameRecording, + StreamIndividualRecordingSettings? individualRecording, + StreamRawRecordingSettings? rawRecording, Map custom = const {}, }) async { final settingsOverride = CallSettingsRequest( @@ -2431,6 +2441,8 @@ class Call { session: session?.toOpenDto(), ingress: ingress?.toOpenDto(), frameRecording: frameRecording?.toOpenDto(), + individualRecording: individualRecording?.toOpenDto(), + rawRecording: rawRecording?.toOpenDto(), ); final aggregatedMembers = [ @@ -2530,9 +2542,11 @@ class Call { } Future> startRecording({ + RecordingType recordingType = RecordingType.composite, String? recordingExternalStorage, }) async { final result = await _permissionsManager.startRecording( + recordingType: recordingType, recordingExternalStorage: recordingExternalStorage, ); @@ -2547,8 +2561,12 @@ class Call { return _permissionsManager.listRecordings(); } - Future> stopRecording() async { - final result = await _permissionsManager.stopRecording(); + Future> stopRecording({ + RecordingType recordingType = RecordingType.composite, + }) async { + final result = await _permissionsManager.stopRecording( + recordingType: recordingType, + ); if (result.isSuccess) { _stateManager.setCallRecording(isRecording: false); @@ -3212,16 +3230,24 @@ class Call { Future> goLive({ bool? startHls, bool? startRecording, + bool? startCompositeRecording, + bool? startIndividualRecording, + bool? startRawRecording, bool? startTranscription, bool? startClosedCaption, + String? recordingStorageName, String? transcriptionStorageName, }) async { final result = await _coordinatorClient.goLive( callCid: callCid, startHls: startHls, startRecording: startRecording, + startCompositeRecording: startCompositeRecording, + startIndividualRecording: startIndividualRecording, + startRawRecording: startRawRecording, startTranscription: startTranscription, startClosedCaption: startClosedCaption, + recordingStorageName: recordingStorageName, transcriptionStorageName: transcriptionStorageName, ); @@ -3233,8 +3259,27 @@ class Call { } /// Stops the livestreaming of the call. - Future> stopLive() async { - final result = await _coordinatorClient.stopLive(callCid); + Future> stopLive({ + bool? continueClosedCaption, + bool? continueCompositeRecording, + bool? continueHls, + bool? continueIndividualRecording, + bool? continueRawRecording, + bool? continueRecording, + bool? continueRtmpBroadcasts, + bool? continueTranscription, + }) async { + final result = await _coordinatorClient.stopLive( + callCid, + continueClosedCaption: continueClosedCaption, + continueCompositeRecording: continueCompositeRecording, + continueHls: continueHls, + continueIndividualRecording: continueIndividualRecording, + continueRawRecording: continueRawRecording, + continueRecording: continueRecording, + continueRtmpBroadcasts: continueRtmpBroadcasts, + continueTranscription: continueTranscription, + ); if (result.isSuccess) { _stateManager.setCallLive(isLive: false); diff --git a/packages/stream_video/lib/src/call/call_events.dart b/packages/stream_video/lib/src/call/call_events.dart index 4470c0e3d..0ed3921ca 100644 --- a/packages/stream_video/lib/src/call/call_events.dart +++ b/packages/stream_video/lib/src/call/call_events.dart @@ -959,6 +959,64 @@ class StreamCallClosedCaptionsEvent extends StreamCallEvent { ]; } +/// Event that is triggered when a user's video stream is being blurred +/// by moderation. +class StreamCallModerationBlurEvent extends StreamCallEvent { + const StreamCallModerationBlurEvent( + super.callCid, { + required this.createdAt, + required this.userId, + this.custom = const {}, + }); + + final DateTime createdAt; + + /// The user ID whose video stream is being blurred + final String userId; + + /// Custom data associated with the moderation action + final Map custom; + + @override + List get props => [ + ...super.props, + createdAt, + userId, + custom, + ]; +} + +/// Event that is triggered when a user receives a moderation warning. +class StreamCallModerationWarningEvent extends StreamCallEvent { + const StreamCallModerationWarningEvent( + super.callCid, { + required this.createdAt, + required this.userId, + required this.message, + this.custom = const {}, + }); + + final DateTime createdAt; + + /// The user ID who is receiving the warning + final String userId; + + /// The warning message + final String message; + + /// Custom data associated with the moderation action + final Map custom; + + @override + List get props => [ + ...super.props, + createdAt, + userId, + message, + custom, + ]; +} + /// Event that is triggered when the broadcasting is started for a call. class StreamCallBroadcastingStartedEvent extends StreamCallEvent { const StreamCallBroadcastingStartedEvent( @@ -1639,6 +1697,21 @@ extension CoordinatorCallEventX on CoordinatorCallEvent { startTime: event.startTime, url: event.url, ), + final CoordinatorCallModerationBlurEvent event => + StreamCallModerationBlurEvent( + event.callCid, + createdAt: event.createdAt, + userId: event.userId, + custom: event.custom, + ), + final CoordinatorCallModerationWarningEvent event => + StreamCallModerationWarningEvent( + event.callCid, + createdAt: event.createdAt, + userId: event.userId, + message: event.message, + custom: event.custom, + ), // Ignore other events as they are internal to Coordinator logic _ => null, }; diff --git a/packages/stream_video/lib/src/call/permissions/permissions_manager.dart b/packages/stream_video/lib/src/call/permissions/permissions_manager.dart index 96722e907..644ff61fa 100644 --- a/packages/stream_video/lib/src/call/permissions/permissions_manager.dart +++ b/packages/stream_video/lib/src/call/permissions/permissions_manager.dart @@ -148,15 +148,18 @@ class PermissionsManager { } Future> startRecording({ + RecordingType recordingType = RecordingType.composite, String? recordingExternalStorage, }) async { - if (!hasPermission(CallPermission.startRecordCall)) { + final permission = _startRecordPermission(recordingType); + if (!hasPermission(permission)) { _logger.w(() => '[startRecording] rejected (no permission)'); return Result.error('Cannot start recording (no permission)'); } - _logger.d(() => '[startRecording] no args'); + _logger.d(() => '[startRecording] recordingType: $recordingType'); final result = await coordinatorClient.startRecording( callCid, + recordingType: recordingType, recordingExternalStorage: recordingExternalStorage, ); _logger.v(() => '[startRecording] result: $result'); @@ -170,13 +173,19 @@ class PermissionsManager { return result; } - Future> stopRecording() async { - if (!hasPermission(CallPermission.stopRecordCall)) { + Future> stopRecording({ + RecordingType recordingType = RecordingType.composite, + }) async { + final permission = _stopRecordPermission(recordingType); + if (!hasPermission(permission)) { _logger.w(() => '[stopRecording] rejected (no permission)'); return Result.error('Cannot stop recording (no permission)'); } - _logger.d(() => '[stopRecording] no args'); - final result = await coordinatorClient.stopRecording(callCid); + _logger.d(() => '[stopRecording] recordingType: $recordingType'); + final result = await coordinatorClient.stopRecording( + callCid, + recordingType: recordingType, + ); _logger.v(() => '[stopRecording] result: $result'); return result; } @@ -456,4 +465,26 @@ class PermissionsManager { } return capabilities.contains(permission); } + + CallPermission _startRecordPermission(RecordingType recordingType) { + switch (recordingType) { + case RecordingType.individual: + return CallPermission.startIndividualRecordCall; + case RecordingType.raw: + return CallPermission.startRawRecordCall; + case RecordingType.composite: + return CallPermission.startRecordCall; + } + } + + CallPermission _stopRecordPermission(RecordingType recordingType) { + switch (recordingType) { + case RecordingType.individual: + return CallPermission.stopIndividualRecordCall; + case RecordingType.raw: + return CallPermission.stopRawRecordCall; + case RecordingType.composite: + return CallPermission.stopRecordCall; + } + } } diff --git a/packages/stream_video/lib/src/coordinator/coordinator_client.dart b/packages/stream_video/lib/src/coordinator/coordinator_client.dart index db8576b8d..c4108925a 100644 --- a/packages/stream_video/lib/src/coordinator/coordinator_client.dart +++ b/packages/stream_video/lib/src/coordinator/coordinator_client.dart @@ -156,6 +156,7 @@ abstract class CoordinatorClient { /// Starts recording for the call described by the given [callCid]. Future> startRecording( StreamCallCid callCid, { + RecordingType recordingType = RecordingType.composite, String? recordingExternalStorage, }); @@ -165,7 +166,10 @@ abstract class CoordinatorClient { ); /// Stops recording for the call described by the given [callCid]. - Future> stopRecording(StreamCallCid callCid); + Future> stopRecording( + StreamCallCid callCid, { + RecordingType recordingType = RecordingType.composite, + }); /// Starts transcription for the call described by the given [callCid]. Future> startTranscription( @@ -252,12 +256,26 @@ abstract class CoordinatorClient { required StreamCallCid callCid, bool? startHls, bool? startRecording, + bool? startCompositeRecording, + bool? startIndividualRecording, + bool? startRawRecording, bool? startTranscription, bool? startClosedCaption, + String? recordingStorageName, String? transcriptionStorageName, }); - Future> stopLive(StreamCallCid callCid); + Future> stopLive( + StreamCallCid callCid, { + bool? continueClosedCaption, + bool? continueCompositeRecording, + bool? continueHls, + bool? continueIndividualRecording, + bool? continueRawRecording, + bool? continueRecording, + bool? continueRtmpBroadcasts, + bool? continueTranscription, + }); Future> muteUsers({ required StreamCallCid callCid, @@ -284,6 +302,8 @@ abstract class CoordinatorClient { StreamBroadcastingSettings? broadcasting, StreamSessionSettings? session, StreamFrameRecordingSettings? frameRecording, + StreamIndividualRecordingSettings? individualRecording, + StreamRawRecordingSettings? rawRecording, StreamIngressSettings? ingress, }); diff --git a/packages/stream_video/lib/src/coordinator/models/coordinator_events.dart b/packages/stream_video/lib/src/coordinator/models/coordinator_events.dart index b0e4d5874..63dd61494 100644 --- a/packages/stream_video/lib/src/coordinator/models/coordinator_events.dart +++ b/packages/stream_video/lib/src/coordinator/models/coordinator_events.dart @@ -7,6 +7,7 @@ import '../../models/call_metadata.dart'; import '../../models/call_permission.dart'; import '../../models/call_ringing_data.dart'; import '../../models/call_session_data.dart'; +import '../../models/call_settings.dart'; /// Represents the events coming in from the socket. @immutable @@ -335,16 +336,19 @@ class CoordinatorCallRecordingStartedEvent extends CoordinatorCallEvent { const CoordinatorCallRecordingStartedEvent({ required this.callCid, required this.createdAt, + required this.recordingType, }); @override final StreamCallCid callCid; final DateTime createdAt; + final RecordingType recordingType; @override List get props => [ ...super.props, createdAt, + recordingType, ]; } @@ -352,16 +356,19 @@ class CoordinatorCallRecordingStoppedEvent extends CoordinatorCallEvent { const CoordinatorCallRecordingStoppedEvent({ required this.callCid, required this.createdAt, + required this.recordingType, }); @override final StreamCallCid callCid; final DateTime createdAt; + final RecordingType recordingType; @override List get props => [ ...super.props, createdAt, + recordingType, ]; } @@ -369,16 +376,19 @@ class CoordinatorCallRecordingFailedEvent extends CoordinatorCallEvent { const CoordinatorCallRecordingFailedEvent({ required this.callCid, required this.createdAt, + required this.recordingType, }); @override final StreamCallCid callCid; final DateTime createdAt; + final RecordingType recordingType; @override List get props => [ ...super.props, createdAt, + recordingType, ]; } @@ -1085,6 +1095,7 @@ class CoordinatorCallRecordingReadyEvent extends CoordinatorCallEvent { required this.egressId, required this.endTime, required this.filename, + required this.recordingType, required this.sessionId, required this.startTime, required this.url, @@ -1096,6 +1107,7 @@ class CoordinatorCallRecordingReadyEvent extends CoordinatorCallEvent { final String egressId; final DateTime endTime; final String filename; + final RecordingType recordingType; final String sessionId; final DateTime startTime; final String url; @@ -1107,12 +1119,62 @@ class CoordinatorCallRecordingReadyEvent extends CoordinatorCallEvent { egressId, endTime, filename, + recordingType, sessionId, startTime, url, ]; } +class CoordinatorCallModerationBlurEvent extends CoordinatorCallEvent { + const CoordinatorCallModerationBlurEvent({ + required this.callCid, + required this.createdAt, + required this.userId, + this.custom = const {}, + }); + + @override + final StreamCallCid callCid; + final DateTime createdAt; + final String userId; + final Map custom; + + @override + List get props => [ + ...super.props, + createdAt, + userId, + custom, + ]; +} + +class CoordinatorCallModerationWarningEvent extends CoordinatorCallEvent { + const CoordinatorCallModerationWarningEvent({ + required this.callCid, + required this.createdAt, + required this.userId, + required this.message, + this.custom = const {}, + }); + + @override + final StreamCallCid callCid; + final DateTime createdAt; + final String userId; + final String message; + final Map custom; + + @override + List get props => [ + ...super.props, + createdAt, + userId, + message, + custom, + ]; +} + // Unknown event. class CoordinatorUnknownEvent extends CoordinatorEvent { const CoordinatorUnknownEvent(); diff --git a/packages/stream_video/lib/src/coordinator/open_api/coordinator_client_open_api.dart b/packages/stream_video/lib/src/coordinator/open_api/coordinator_client_open_api.dart index 671979180..16bf5d9bd 100644 --- a/packages/stream_video/lib/src/coordinator/open_api/coordinator_client_open_api.dart +++ b/packages/stream_video/lib/src/coordinator/open_api/coordinator_client_open_api.dart @@ -827,6 +827,7 @@ class CoordinatorClientOpenApi extends CoordinatorClient { @override Future> startRecording( StreamCallCid callCid, { + RecordingType recordingType = RecordingType.composite, String? recordingExternalStorage, }) async { try { @@ -838,6 +839,7 @@ class CoordinatorClientOpenApi extends CoordinatorClient { await _defaultApi.startRecording( callCid.type.value, callCid.id, + recordingType.toOpenDto(), open.StartRecordingRequest( recordingExternalStorage: recordingExternalStorage, ), @@ -869,14 +871,22 @@ class CoordinatorClientOpenApi extends CoordinatorClient { } @override - Future> stopRecording(StreamCallCid callCid) async { + Future> stopRecording( + StreamCallCid callCid, { + RecordingType recordingType = RecordingType.composite, + }) async { try { final connectionResult = await _waitUntilConnected(); if (connectionResult is Failure) { _logger.e(() => '[stopRecording] no connection established'); return connectionResult; } - await _defaultApi.stopRecording(callCid.type.value, callCid.id); + await _defaultApi.stopRecording( + callCid.type.value, + callCid.id, + recordingType.toOpenDto(), + Object(), + ); return const Result.success(none); } catch (e, stk) { return Result.failure(VideoErrors.compose(e, stk)); @@ -1248,8 +1258,12 @@ class CoordinatorClientOpenApi extends CoordinatorClient { required StreamCallCid callCid, bool? startHls, bool? startRecording, + bool? startCompositeRecording, + bool? startIndividualRecording, + bool? startRawRecording, bool? startTranscription, bool? startClosedCaption, + String? recordingStorageName, String? transcriptionStorageName, }) async { try { @@ -1264,8 +1278,12 @@ class CoordinatorClientOpenApi extends CoordinatorClient { open.GoLiveRequest( startHls: startHls, startRecording: startRecording, + startCompositeRecording: startCompositeRecording, + startIndividualRecording: startIndividualRecording, + startRawRecording: startRawRecording, startTranscription: startTranscription, startClosedCaption: startClosedCaption, + recordingStorageName: recordingStorageName, transcriptionStorageName: transcriptionStorageName, ), ); @@ -1283,7 +1301,10 @@ class CoordinatorClientOpenApi extends CoordinatorClient { Future> stopLive( StreamCallCid callCid, { bool? continueClosedCaption, + bool? continueCompositeRecording, bool? continueHls, + bool? continueIndividualRecording, + bool? continueRawRecording, bool? continueRecording, bool? continueRtmpBroadcasts, bool? continueTranscription, @@ -1299,7 +1320,10 @@ class CoordinatorClientOpenApi extends CoordinatorClient { callCid.id, open.StopLiveRequest( continueClosedCaption: continueClosedCaption, + continueCompositeRecording: continueCompositeRecording, continueHls: continueHls, + continueIndividualRecording: continueIndividualRecording, + continueRawRecording: continueRawRecording, continueRecording: continueRecording, continueRtmpBroadcasts: continueRtmpBroadcasts, continueTranscription: continueTranscription, @@ -1368,6 +1392,8 @@ class CoordinatorClientOpenApi extends CoordinatorClient { StreamBroadcastingSettings? broadcasting, StreamSessionSettings? session, StreamFrameRecordingSettings? frameRecording, + StreamIndividualRecordingSettings? individualRecording, + StreamRawRecordingSettings? rawRecording, StreamIngressSettings? ingress, }) async { try { @@ -1395,6 +1421,8 @@ class CoordinatorClientOpenApi extends CoordinatorClient { broadcasting: broadcasting?.toOpenDto(), session: session?.toOpenDto(), frameRecording: frameRecording?.toOpenDto(), + individualRecording: individualRecording?.toOpenDto(), + rawRecording: rawRecording?.toOpenDto(), ingress: ingress?.toOpenDto(), ), ), diff --git a/packages/stream_video/lib/src/coordinator/open_api/event/event_type.dart b/packages/stream_video/lib/src/coordinator/open_api/event/event_type.dart index 43a80a5f6..d4e3a3d8b 100644 --- a/packages/stream_video/lib/src/coordinator/open_api/event/event_type.dart +++ b/packages/stream_video/lib/src/coordinator/open_api/event/event_type.dart @@ -48,6 +48,8 @@ enum EventType { callFrameRecordingStopped('call.frame_recording_stopped'), callFrameRecordingFailed('call.frame_recording_failed'), callFrameRecordingReady('call.frame_recording_ready'), + callModerationBlur('call.moderation_blur'), + callModerationWarning('call.moderation_warning'), custom('custom'), unknown('unknown'); diff --git a/packages/stream_video/lib/src/coordinator/open_api/event/open_api_event.dart b/packages/stream_video/lib/src/coordinator/open_api/event/open_api_event.dart index 0bdc94e68..759b541b9 100644 --- a/packages/stream_video/lib/src/coordinator/open_api/event/open_api_event.dart +++ b/packages/stream_video/lib/src/coordinator/open_api/event/open_api_event.dart @@ -56,6 +56,8 @@ class OpenApiEvent with EquatableMixin { this.callFrameRecordingFailed, this.callFrameRecordingStopped, this.callFrameRecordingFrameReady, + this.callModerationBlur, + this.callModerationWarning, this.custom, this.unknown, }); @@ -213,6 +215,12 @@ class OpenApiEvent with EquatableMixin { case EventType.callFrameRecordingReady: final event = open.CallFrameRecordingFrameReadyEvent.fromJson(jsonObj); return result.copyWith(callFrameRecordingFrameReady: event); + case EventType.callModerationBlur: + final event = open.CallModerationBlurEvent.fromJson(jsonObj); + return result.copyWith(callModerationBlur: event); + case EventType.callModerationWarning: + final event = open.CallModerationWarningEvent.fromJson(jsonObj); + return result.copyWith(callModerationWarning: event); case EventType.unknown: streamLog.d(_tag, () => '[fromJson] unexpected event: $jsonObj'); return result.copyWith(unknown: jsonObj); @@ -267,6 +275,8 @@ class OpenApiEvent with EquatableMixin { final open.CallFrameRecordingFailedEvent? callFrameRecordingFailed; final open.CallFrameRecordingStoppedEvent? callFrameRecordingStopped; final open.CallFrameRecordingFrameReadyEvent? callFrameRecordingFrameReady; + final open.CallModerationBlurEvent? callModerationBlur; + final open.CallModerationWarningEvent? callModerationWarning; final Object? unknown; OpenApiEvent copyWith({ @@ -318,6 +328,8 @@ class OpenApiEvent with EquatableMixin { open.CallFrameRecordingFailedEvent? callFrameRecordingFailed, open.CallFrameRecordingStoppedEvent? callFrameRecordingStopped, open.CallFrameRecordingFrameReadyEvent? callFrameRecordingFrameReady, + open.CallModerationBlurEvent? callModerationBlur, + open.CallModerationWarningEvent? callModerationWarning, Object? unknown, }) { return OpenApiEvent( @@ -387,6 +399,9 @@ class OpenApiEvent with EquatableMixin { callFrameRecordingStopped ?? this.callFrameRecordingStopped, callFrameRecordingFrameReady: callFrameRecordingFrameReady ?? this.callFrameRecordingFrameReady, + callModerationBlur: callModerationBlur ?? this.callModerationBlur, + callModerationWarning: + callModerationWarning ?? this.callModerationWarning, custom: custom ?? this.custom, unknown: unknown ?? this.unknown, ); @@ -442,6 +457,8 @@ class OpenApiEvent with EquatableMixin { callFrameRecordingFailed, callFrameRecordingStopped, callFrameRecordingFrameReady, + callModerationBlur, + callModerationWarning, custom, unknown, ]; diff --git a/packages/stream_video/lib/src/coordinator/open_api/open_api_extensions.dart b/packages/stream_video/lib/src/coordinator/open_api/open_api_extensions.dart index 4fef5efa4..103eb01d6 100644 --- a/packages/stream_video/lib/src/coordinator/open_api/open_api_extensions.dart +++ b/packages/stream_video/lib/src/coordinator/open_api/open_api_extensions.dart @@ -212,6 +212,16 @@ extension CallSettingsExt on open.CallSettingsResponse { maxParticipantsExcludeOwner: limits.maxParticipantsExcludeOwner, maxParticipantsExcludeRoles: limits.maxParticipantsExcludeRoles, ), + individualRecording: StreamIndividualRecordingSettings( + mode: IndividualRecordingSettingsMode.fromString( + individualRecording.mode.value, + ), + ), + rawRecording: StreamRawRecordingSettings( + mode: RawRecordingSettingsMode.fromString( + rawRecording.mode.value, + ), + ), ingress: ingress?.toSettingsDomain(), ); } diff --git a/packages/stream_video/lib/src/coordinator/open_api/open_api_mapper_extensions.dart b/packages/stream_video/lib/src/coordinator/open_api/open_api_mapper_extensions.dart index 685cf4753..4fb388580 100644 --- a/packages/stream_video/lib/src/coordinator/open_api/open_api_mapper_extensions.dart +++ b/packages/stream_video/lib/src/coordinator/open_api/open_api_mapper_extensions.dart @@ -4,6 +4,7 @@ import '../../models/call_cid.dart'; import '../../models/call_created_data.dart'; import '../../models/call_permission.dart'; import '../../models/call_ringing_data.dart'; +import '../../models/call_settings.dart'; import '../models/coordinator_events.dart'; import 'event/event_type.dart'; import 'event/open_api_event.dart'; @@ -169,6 +170,7 @@ extension WebsocketEventMapperExt on OpenApiEvent { return CoordinatorCallRecordingStartedEvent( callCid: StreamCallCid(cid: event.callCid), createdAt: event.createdAt, + recordingType: RecordingType.fromString(event.recordingType.value), ); case EventType.callRecordingStopped: final event = callRecordingStopped!; @@ -176,6 +178,7 @@ extension WebsocketEventMapperExt on OpenApiEvent { return CoordinatorCallRecordingStoppedEvent( callCid: StreamCallCid(cid: event.callCid), createdAt: event.createdAt, + recordingType: RecordingType.fromString(event.recordingType.value), ); case EventType.callRecordingFailed: final event = callRecordingFailed!; @@ -183,6 +186,7 @@ extension WebsocketEventMapperExt on OpenApiEvent { return CoordinatorCallRecordingFailedEvent( callCid: StreamCallCid(cid: event.callCid), createdAt: event.createdAt, + recordingType: RecordingType.fromString(event.recordingType.value), ); case EventType.callBroadcastingStarted: final event = callBroadcastingStarted!; @@ -396,10 +400,28 @@ extension WebsocketEventMapperExt on OpenApiEvent { url: event.callRecording.url, endTime: event.callRecording.endTime, filename: event.callRecording.filename, + recordingType: RecordingType.fromString(event.recordingType.value), sessionId: event.callRecording.sessionId, startTime: event.callRecording.startTime, egressId: event.egressId, ); + case EventType.callModerationBlur: + final event = callModerationBlur!; + return CoordinatorCallModerationBlurEvent( + callCid: StreamCallCid(cid: event.callCid), + createdAt: event.createdAt, + userId: event.userId, + custom: event.custom, + ); + case EventType.callModerationWarning: + final event = callModerationWarning!; + return CoordinatorCallModerationWarningEvent( + callCid: StreamCallCid(cid: event.callCid), + createdAt: event.createdAt, + userId: event.userId, + message: event.message, + custom: event.custom, + ); case EventType.custom: final event = custom!; diff --git a/packages/stream_video/lib/src/coordinator/retry/coordinator_client_retry.dart b/packages/stream_video/lib/src/coordinator/retry/coordinator_client_retry.dart index 6dd8bf873..c0afb7918 100644 --- a/packages/stream_video/lib/src/coordinator/retry/coordinator_client_retry.dart +++ b/packages/stream_video/lib/src/coordinator/retry/coordinator_client_retry.dart @@ -191,8 +191,12 @@ class CoordinatorClientRetry extends CoordinatorClient { required StreamCallCid callCid, bool? startHls, bool? startRecording, + bool? startCompositeRecording, + bool? startIndividualRecording, + bool? startRawRecording, bool? startTranscription, bool? startClosedCaption, + String? recordingStorageName, String? transcriptionStorageName, }) { return _retryManager.execute( @@ -200,8 +204,12 @@ class CoordinatorClientRetry extends CoordinatorClient { callCid: callCid, startHls: startHls, startRecording: startRecording, + startCompositeRecording: startCompositeRecording, + startIndividualRecording: startIndividualRecording, + startRawRecording: startRawRecording, startTranscription: startTranscription, startClosedCaption: startClosedCaption, + recordingStorageName: recordingStorageName, transcriptionStorageName: transcriptionStorageName, ), (error, nextAttemptDelay) async { @@ -555,11 +563,13 @@ class CoordinatorClientRetry extends CoordinatorClient { @override Future> startRecording( StreamCallCid callCid, { + RecordingType recordingType = RecordingType.composite, String? recordingExternalStorage, }) { return _retryManager.execute( () => _delegate.startRecording( callCid, + recordingType: recordingType, recordingExternalStorage: recordingExternalStorage, ), (error, nextAttemptDelay) async { @@ -591,9 +601,29 @@ class CoordinatorClientRetry extends CoordinatorClient { } @override - Future> stopLive(StreamCallCid callCid) { + Future> stopLive( + StreamCallCid callCid, { + bool? continueClosedCaption, + bool? continueCompositeRecording, + bool? continueHls, + bool? continueIndividualRecording, + bool? continueRawRecording, + bool? continueRecording, + bool? continueRtmpBroadcasts, + bool? continueTranscription, + }) { return _retryManager.execute( - () => _delegate.stopLive(callCid), + () => _delegate.stopLive( + callCid, + continueClosedCaption: continueClosedCaption, + continueCompositeRecording: continueCompositeRecording, + continueHls: continueHls, + continueIndividualRecording: continueIndividualRecording, + continueRawRecording: continueRawRecording, + continueRecording: continueRecording, + continueRtmpBroadcasts: continueRtmpBroadcasts, + continueTranscription: continueTranscription, + ), (error, nextAttemptDelay) async { _logRetry('stopLive', error, nextAttemptDelay); }, @@ -601,9 +631,15 @@ class CoordinatorClientRetry extends CoordinatorClient { } @override - Future> stopRecording(StreamCallCid callCid) { + Future> stopRecording( + StreamCallCid callCid, { + RecordingType recordingType = RecordingType.composite, + }) { return _retryManager.execute( - () => _delegate.stopRecording(callCid), + () => _delegate.stopRecording( + callCid, + recordingType: recordingType, + ), (error, nextAttemptDelay) async { _logRetry('stopRecording', error, nextAttemptDelay); }, @@ -715,6 +751,8 @@ class CoordinatorClientRetry extends CoordinatorClient { StreamBroadcastingSettings? broadcasting, StreamSessionSettings? session, StreamFrameRecordingSettings? frameRecording, + StreamIndividualRecordingSettings? individualRecording, + StreamRawRecordingSettings? rawRecording, StreamIngressSettings? ingress, }) { return _retryManager.execute( @@ -733,6 +771,8 @@ class CoordinatorClientRetry extends CoordinatorClient { limits: limits, session: session, frameRecording: frameRecording, + individualRecording: individualRecording, + rawRecording: rawRecording, ingress: ingress, ), (error, nextAttemptDelay) async { diff --git a/packages/stream_video/lib/src/models/call_permission.dart b/packages/stream_video/lib/src/models/call_permission.dart index c4a13c227..2b1154e7f 100644 --- a/packages/stream_video/lib/src/models/call_permission.dart +++ b/packages/stream_video/lib/src/models/call_permission.dart @@ -34,6 +34,10 @@ enum CallPermission { changeMaxDuration('change-max-duration'), startFrameRecordCall('start-frame-record-call'), stopFrameRecordCall('stop-frame-record-call'), + startIndividualRecordCall('start-individual-record-call'), + stopIndividualRecordCall('stop-individual-record-call'), + startRawRecordCall('start-raw-record-call'), + stopRawRecordCall('stop-raw-record-call'), sendClosedCaptionsCall('send-closed-captions-call'), unknown('unknown'); diff --git a/packages/stream_video/lib/src/models/call_settings.dart b/packages/stream_video/lib/src/models/call_settings.dart index 931bcb0d4..99aefe6f0 100644 --- a/packages/stream_video/lib/src/models/call_settings.dart +++ b/packages/stream_video/lib/src/models/call_settings.dart @@ -19,6 +19,8 @@ class CallSettings with EquatableMixin { this.limits = const StreamLimitsSettings(), this.session = const StreamSessionSettings(), this.frameRecording = const StreamFrameRecordingSettings(), + this.individualRecording = const StreamIndividualRecordingSettings(), + this.rawRecording = const StreamRawRecordingSettings(), this.ingress, }); @@ -34,6 +36,8 @@ class CallSettings with EquatableMixin { final StreamLimitsSettings limits; final StreamSessionSettings session; final StreamFrameRecordingSettings frameRecording; + final StreamIndividualRecordingSettings individualRecording; + final StreamRawRecordingSettings rawRecording; final StreamIngressSettings? ingress; @override @@ -54,6 +58,8 @@ class CallSettings with EquatableMixin { StreamLimitsSettings? limits, StreamSessionSettings? session, StreamFrameRecordingSettings? frameRecording, + StreamIndividualRecordingSettings? individualRecording, + StreamRawRecordingSettings? rawRecording, StreamIngressSettings? ingress, }) { return CallSettings( @@ -69,6 +75,8 @@ class CallSettings with EquatableMixin { limits: limits ?? this.limits, session: session ?? this.session, frameRecording: frameRecording ?? this.frameRecording, + individualRecording: individualRecording ?? this.individualRecording, + rawRecording: rawRecording ?? this.rawRecording, ingress: ingress ?? this.ingress, ); } @@ -360,6 +368,40 @@ class StreamRecordingSettings extends AbstractSettings { } } +class StreamIndividualRecordingSettings extends AbstractSettings { + const StreamIndividualRecordingSettings({ + this.mode = IndividualRecordingSettingsMode.disabled, + }); + + final IndividualRecordingSettingsMode mode; + + @override + List get props => [mode]; + + IndividualRecordingSettingsRequest toOpenDto() { + return IndividualRecordingSettingsRequest( + mode: mode.toOpenDto(), + ); + } +} + +class StreamRawRecordingSettings extends AbstractSettings { + const StreamRawRecordingSettings({ + this.mode = RawRecordingSettingsMode.disabled, + }); + + final RawRecordingSettingsMode mode; + + @override + List get props => [mode]; + + RawRecordingSettingsRequest toOpenDto() { + return RawRecordingSettingsRequest( + mode: mode.toOpenDto(), + ); + } +} + class StreamRingSettings extends AbstractSettings { const StreamRingSettings({ this.autoCancelTimeout = const Duration(seconds: 30), @@ -709,6 +751,72 @@ enum RecordSettingsMode { } } +enum IndividualRecordingSettingsMode { + available, + disabled, + autoOn; + + @override + String toString() => name; + + IndividualRecordingSettingsRequestModeEnum toOpenDto() { + switch (this) { + case IndividualRecordingSettingsMode.available: + return IndividualRecordingSettingsRequestModeEnum.available; + case IndividualRecordingSettingsMode.disabled: + return IndividualRecordingSettingsRequestModeEnum.disabled; + case IndividualRecordingSettingsMode.autoOn: + return IndividualRecordingSettingsRequestModeEnum.autoOn; + } + } + + static IndividualRecordingSettingsMode fromString(String value) { + switch (value) { + case 'available': + return IndividualRecordingSettingsMode.available; + case 'disabled': + return IndividualRecordingSettingsMode.disabled; + case 'auto-on': + return IndividualRecordingSettingsMode.autoOn; + default: + return IndividualRecordingSettingsMode.disabled; + } + } +} + +enum RawRecordingSettingsMode { + available, + disabled, + autoOn; + + @override + String toString() => name; + + RawRecordingSettingsRequestModeEnum toOpenDto() { + switch (this) { + case RawRecordingSettingsMode.available: + return RawRecordingSettingsRequestModeEnum.available; + case RawRecordingSettingsMode.disabled: + return RawRecordingSettingsRequestModeEnum.disabled; + case RawRecordingSettingsMode.autoOn: + return RawRecordingSettingsRequestModeEnum.autoOn; + } + } + + static RawRecordingSettingsMode fromString(String value) { + switch (value) { + case 'available': + return RawRecordingSettingsMode.available; + case 'disabled': + return RawRecordingSettingsMode.disabled; + case 'auto-on': + return RawRecordingSettingsMode.autoOn; + default: + return RawRecordingSettingsMode.disabled; + } + } +} + enum FrameRecordingSettingsMode { available, disabled, @@ -1003,6 +1111,39 @@ enum ClosedCaptionSettingsMode { } } +enum RecordingType { + composite, + individual, + raw; + + @override + String toString() => name; + + String toOpenDto() { + switch (this) { + case RecordingType.composite: + return 'composite'; + case RecordingType.individual: + return 'individual'; + case RecordingType.raw: + return 'raw'; + } + } + + static RecordingType fromString(String value) { + switch (value) { + case 'composite': + return RecordingType.composite; + case 'individual': + return RecordingType.individual; + case 'raw': + return RecordingType.raw; + default: + return RecordingType.composite; + } + } +} + enum NoiceCancellationSettingsMode { available, disabled, diff --git a/packages/stream_video/test/src/call/call_coordinator_events_test.dart b/packages/stream_video/test/src/call/call_coordinator_events_test.dart index 147d570cf..5b05cfcfc 100644 --- a/packages/stream_video/test/src/call/call_coordinator_events_test.dart +++ b/packages/stream_video/test/src/call/call_coordinator_events_test.dart @@ -682,6 +682,7 @@ void main() { CoordinatorCallRecordingStartedEvent( callCid: setup.call.callCid, createdAt: DateTime.now(), + recordingType: RecordingType.composite, ), ); @@ -701,6 +702,7 @@ void main() { CoordinatorCallRecordingStartedEvent( callCid: setup.call.callCid, createdAt: DateTime.now(), + recordingType: RecordingType.composite, ), ); await Future.delayed(Duration.zero); @@ -711,6 +713,7 @@ void main() { CoordinatorCallRecordingStoppedEvent( callCid: setup.call.callCid, createdAt: DateTime.now(), + recordingType: RecordingType.composite, ), ); @@ -730,6 +733,7 @@ void main() { CoordinatorCallRecordingStartedEvent( callCid: setup.call.callCid, createdAt: DateTime.now(), + recordingType: RecordingType.composite, ), ); await Future.delayed(Duration.zero); @@ -740,6 +744,7 @@ void main() { CoordinatorCallRecordingFailedEvent( callCid: setup.call.callCid, createdAt: DateTime.now(), + recordingType: RecordingType.composite, ), );