8 changed files with 205 additions and 5 deletions
Unified View
Diff Options
-
56lib/controller/discover/room_controller.dart
-
28lib/model/rtc/rtc_channel_data.dart
-
1lib/network/api_urls.dart
-
3lib/network/index.dart
-
6lib/network/network_service.dart
-
18lib/network/rtc_api.dart
-
81lib/network/rtc_api.g.dart
-
17lib/pages/discover/discover_page.dart
@ -0,0 +1,56 @@ |
|||||
|
import 'package:dating_touchme_app/model/rtc/rtc_channel_data.dart'; |
||||
|
import 'package:dating_touchme_app/network/network_service.dart'; |
||||
|
import 'package:dating_touchme_app/rtc/rtc_manager.dart'; |
||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
|
||||
|
import '../../pages/discover/live_room_page.dart'; |
||||
|
|
||||
|
/// 直播房间相关控制器 |
||||
|
class RoomController extends GetxController { |
||||
|
RoomController({NetworkService? networkService}) |
||||
|
: _networkService = networkService ?? Get.find<NetworkService>(); |
||||
|
|
||||
|
final NetworkService _networkService; |
||||
|
|
||||
|
/// 当前频道信息 |
||||
|
final Rxn<RtcChannelData> rtcChannel = Rxn<RtcChannelData>(); |
||||
|
|
||||
|
/// 是否正在创建 |
||||
|
final RxBool isLoading = false.obs; |
||||
|
|
||||
|
/// 调用接口创建 RTC 频道 |
||||
|
Future<void> createRtcChannel() async { |
||||
|
if (isLoading.value) return ; |
||||
|
|
||||
|
try { |
||||
|
isLoading.value = true; |
||||
|
final response = await _networkService.rtcApi.createRtcChannel(); |
||||
|
final base = response.data; |
||||
|
|
||||
|
if (base.isSuccess && base.data != null) { |
||||
|
rtcChannel.value = base.data; |
||||
|
await _joinRtcChannel(base.data!); |
||||
|
} else { |
||||
|
final message = base.message.isNotEmpty ? base.message : '创建频道失败'; |
||||
|
SmartDialog.showToast(message); |
||||
|
} |
||||
|
} catch (e) { |
||||
|
SmartDialog.showToast('创建频道异常:$e'); |
||||
|
} finally { |
||||
|
isLoading.value = false; |
||||
|
} |
||||
|
} |
||||
|
Future<void> _joinRtcChannel(RtcChannelData data) async { |
||||
|
try { |
||||
|
await RTCManager.instance.joinChannel( |
||||
|
token: data.token, |
||||
|
channelId: data.channelId, |
||||
|
); |
||||
|
Get.to(() => const LiveRoomPage(id: 0)); |
||||
|
} catch (e) { |
||||
|
SmartDialog.showToast('加入频道失败:$e'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,28 @@ |
|||||
|
/// RTC 频道创建返回数据 |
||||
|
class RtcChannelData { |
||||
|
final String channelId; |
||||
|
final String token; |
||||
|
|
||||
|
RtcChannelData({ |
||||
|
required this.channelId, |
||||
|
required this.token, |
||||
|
}); |
||||
|
|
||||
|
factory RtcChannelData.fromJson(Map<String, dynamic> json) { |
||||
|
return RtcChannelData( |
||||
|
channelId: json['channelId']?.toString() ?? '', |
||||
|
token: json['token']?.toString() ?? '', |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Map<String, dynamic> toJson() { |
||||
|
return { |
||||
|
'channelId': channelId, |
||||
|
'token': token, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
String toString() => 'RtcChannelData(channelId: $channelId)'; |
||||
|
} |
||||
|
|
||||
@ -1,4 +1,5 @@ |
|||||
export 'api_service.dart'; |
export 'api_service.dart'; |
||||
export 'network_config.dart'; |
export 'network_config.dart'; |
||||
export 'network_service.dart'; |
export 'network_service.dart'; |
||||
export 'response_model.dart'; |
|
||||
|
export 'response_model.dart'; |
||||
|
export 'rtc_api.dart'; |
||||
@ -0,0 +1,18 @@ |
|||||
|
import 'package:dating_touchme_app/model/rtc/rtc_channel_data.dart'; |
||||
|
import 'package:dating_touchme_app/network/api_urls.dart'; |
||||
|
import 'package:dating_touchme_app/network/response_model.dart'; |
||||
|
import 'package:dio/dio.dart'; |
||||
|
import 'package:retrofit/retrofit.dart'; |
||||
|
|
||||
|
part 'rtc_api.g.dart'; |
||||
|
|
||||
|
/// RTC 相关接口 |
||||
|
@RestApi(baseUrl: '') |
||||
|
abstract class RtcApi { |
||||
|
factory RtcApi(Dio dio) = _RtcApi; |
||||
|
|
||||
|
/// 创建实时音视频频道 |
||||
|
@POST(ApiUrls.createRtcChannel) |
||||
|
Future<HttpResponse<BaseResponse<RtcChannelData>>> createRtcChannel(); |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,81 @@ |
|||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||
|
|
||||
|
part of 'rtc_api.dart'; |
||||
|
|
||||
|
// dart format off |
||||
|
|
||||
|
// ************************************************************************** |
||||
|
// RetrofitGenerator |
||||
|
// ************************************************************************** |
||||
|
|
||||
|
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations,unused_element_parameter,avoid_unused_constructor_parameters,unreachable_from_main |
||||
|
|
||||
|
class _RtcApi implements RtcApi { |
||||
|
_RtcApi(this._dio, {this.baseUrl, this.errorLogger}); |
||||
|
|
||||
|
final Dio _dio; |
||||
|
|
||||
|
String? baseUrl; |
||||
|
|
||||
|
final ParseErrorLogger? errorLogger; |
||||
|
|
||||
|
@override |
||||
|
Future<HttpResponse<BaseResponse<RtcChannelData>>> createRtcChannel() async { |
||||
|
final _extra = <String, dynamic>{}; |
||||
|
final queryParameters = <String, dynamic>{}; |
||||
|
final _headers = <String, dynamic>{}; |
||||
|
const Map<String, dynamic>? _data = null; |
||||
|
final _options = _setStreamType<HttpResponse<BaseResponse<RtcChannelData>>>( |
||||
|
Options(method: 'POST', headers: _headers, extra: _extra) |
||||
|
.compose( |
||||
|
_dio.options, |
||||
|
'dating-agency-chat-audio/user/create/rtc-channel', |
||||
|
queryParameters: queryParameters, |
||||
|
data: _data, |
||||
|
) |
||||
|
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), |
||||
|
); |
||||
|
final _result = await _dio.fetch<Map<String, dynamic>>(_options); |
||||
|
late BaseResponse<RtcChannelData> _value; |
||||
|
try { |
||||
|
_value = BaseResponse<RtcChannelData>.fromJson( |
||||
|
_result.data!, |
||||
|
(json) => RtcChannelData.fromJson(json as Map<String, dynamic>), |
||||
|
); |
||||
|
} on Object catch (e, s) { |
||||
|
errorLogger?.logError(e, s, _options); |
||||
|
rethrow; |
||||
|
} |
||||
|
final httpResponse = HttpResponse(_value, _result); |
||||
|
return httpResponse; |
||||
|
} |
||||
|
|
||||
|
RequestOptions _setStreamType<T>(RequestOptions requestOptions) { |
||||
|
if (T != dynamic && |
||||
|
!(requestOptions.responseType == ResponseType.bytes || |
||||
|
requestOptions.responseType == ResponseType.stream)) { |
||||
|
if (T == String) { |
||||
|
requestOptions.responseType = ResponseType.plain; |
||||
|
} else { |
||||
|
requestOptions.responseType = ResponseType.json; |
||||
|
} |
||||
|
} |
||||
|
return requestOptions; |
||||
|
} |
||||
|
|
||||
|
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) { |
||||
|
if (baseUrl == null || baseUrl.trim().isEmpty) { |
||||
|
return dioBaseUrl; |
||||
|
} |
||||
|
|
||||
|
final url = Uri.parse(baseUrl); |
||||
|
|
||||
|
if (url.isAbsolute) { |
||||
|
return url.toString(); |
||||
|
} |
||||
|
|
||||
|
return Uri.parse(dioBaseUrl).resolveUri(url).toString(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// dart format on |
||||
Write
Preview
Loading…
Cancel
Save