Browse Source

feat(live): 完善直播房间退出和礼物弹窗功能

- 在登出时自动退出直播间并清理相关资源
- 添加小窗口隐藏功能确保登出时完全清理
- 实现礼物弹窗默认选中主持人逻辑
- 优化直播房间界面显示,根据好友关系控制加好友按钮
- 统一在多个控制器中添加登出时的资源清理逻辑
master
Jolie 3 months ago
parent
commit
26eb4a39a3
5 changed files with 149 additions and 27 deletions
  1. 23
      lib/controller/mine/deactivate_controller.dart
  2. 23
      lib/controller/setting/setting_controller.dart
  3. 26
      lib/network/network_config.dart
  4. 50
      lib/widget/live/live_gift_popup.dart
  5. 54
      lib/widget/live/live_room_anchor_showcase.dart

23
lib/controller/mine/deactivate_controller.dart

@ -1,5 +1,7 @@
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/controller/message/conversation_controller.dart';
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/controller/overlay_controller.dart';
import 'package:dating_touchme_app/im/im_manager.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
@ -12,6 +14,27 @@ class DeactivateController extends GetxController {
final s = "".obs;
void logout() async {
// 退
if (Get.isRegistered<RoomController>()) {
try {
final roomController = Get.find<RoomController>();
await roomController.leaveChannel();
} catch (e) {
print('退出直播间失败: $e');
}
}
//
if (Get.isRegistered<OverlayController>()) {
try {
final overlayController = Get.find<OverlayController>();
overlayController.hide(); //
overlayController.hideVideoCall(); //
} catch (e) {
print('取消小窗口失败: $e');
}
}
// 退 IM
await IMManager.instance.logout();
//

23
lib/controller/setting/setting_controller.dart

@ -1,6 +1,8 @@
import 'dart:async';
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/controller/message/conversation_controller.dart';
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/controller/overlay_controller.dart';
import 'package:dating_touchme_app/im/im_manager.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:flutter/material.dart';
@ -47,6 +49,27 @@ class SettingController extends GetxController {
}
void logout() async {
// 退
if (Get.isRegistered<RoomController>()) {
try {
final roomController = Get.find<RoomController>();
await roomController.leaveChannel();
} catch (e) {
print('退出直播间失败: $e');
}
}
//
if (Get.isRegistered<OverlayController>()) {
try {
final overlayController = Get.find<OverlayController>();
overlayController.hide(); //
overlayController.hideVideoCall(); //
} catch (e) {
print('取消小窗口失败: $e');
}
}
// 退 IM
await IMManager.instance.logout();
//

26
lib/network/network_config.dart

@ -1,8 +1,7 @@
import 'package:dating_touchme_app/controller/discover/discover_controller.dart';
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/controller/home/home_controller.dart';
import 'package:dating_touchme_app/controller/message/conversation_controller.dart';
import 'package:dating_touchme_app/controller/mine/mine_controller.dart';
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/controller/overlay_controller.dart';
import 'package:dating_touchme_app/im/im_manager.dart';
import 'package:dio/dio.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@ -163,6 +162,27 @@ class ResponseInterceptor extends Interceptor {
// token过期逻辑
// 使Get.offAllNamed('/login')
// 退 IM
// 退
if (Get.isRegistered<RoomController>()) {
try {
final roomController = Get.find<RoomController>();
await roomController.leaveChannel();
} catch (e) {
print('退出直播间失败: $e');
}
}
//
if (Get.isRegistered<OverlayController>()) {
try {
final overlayController = Get.find<OverlayController>();
overlayController.hide(); //
overlayController.hideVideoCall(); //
} catch (e) {
print('取消小窗口失败: $e');
}
}
await IMManager.instance.logout();
//
if (Get.isRegistered<ConversationController>()) {

50
lib/widget/live/live_gift_popup.dart

@ -37,6 +37,8 @@ class LiveGiftPopup extends StatefulWidget {
class _LiveGiftPopupState extends State<LiveGiftPopup> {
// ID
int? _selectedUserId;
//
bool _hasTriedSetDefault = false;
@override
void initState() {
@ -44,6 +46,9 @@ class _LiveGiftPopupState extends State<LiveGiftPopup> {
// ID
if (widget.targetUserId != null) {
_selectedUserId = widget.targetUserId;
} else if (widget.showHeader) {
// ID且显示头部
_initDefaultSelectedUser();
}
//
if (widget.giftList.isNotEmpty && widget.activeGift.value == null) {
@ -51,6 +56,36 @@ class _LiveGiftPopupState extends State<LiveGiftPopup> {
}
}
///
void _initDefaultSelectedUser() {
try {
final roomController = Get.isRegistered<RoomController>()
? Get.find<RoomController>()
: null;
if (roomController != null) {
final rtcChannelDetail = roomController.rtcChannelDetail.value;
// anchorInfo
if (rtcChannelDetail?.anchorInfo != null) {
final anchorInfo = rtcChannelDetail!.anchorInfo!;
// ID
final currentUserId = GlobalData().userId ?? GlobalData().userData?.id;
//
if (anchorInfo.userId != currentUserId && anchorInfo.miId != currentUserId) {
// 使 uid
if (anchorInfo.uid != null) {
setState(() {
_selectedUserId = anchorInfo.uid;
});
}
}
}
}
} catch (e) {
print('初始化默认选中用户失败: $e');
}
}
//
void _toggleUserSelection(int userId) {
setState(() {
@ -201,6 +236,21 @@ class _LiveGiftPopupState extends State<LiveGiftPopup> {
// 3
final displayUsers = filteredUserList.take(3).toList();
//
if (!_hasTriedSetDefault && _selectedUserId == null && rtcChannelDetail?.anchorInfo != null) {
final anchorInfo = rtcChannelDetail!.anchorInfo!;
if (anchorInfo.userId != currentUserId && anchorInfo.miId != currentUserId && anchorInfo.uid != null) {
_hasTriedSetDefault = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted && _selectedUserId == null) {
setState(() {
_selectedUserId = anchorInfo.uid;
});
}
});
}
}
return Container(
height: 53.w,
padding: EdgeInsets.symmetric(horizontal: 10.w),

54
lib/widget/live/live_room_anchor_showcase.dart

@ -89,35 +89,41 @@ class _LiveRoomAnchorShowcaseState extends State<LiveRoomAnchorShowcase> {
),
),
if(_roomController.currentRole != CurrentRole.broadcaster)
Positioned(
bottom: 5.w,
right: 5.w,
child: Container(
width: 47.w,
height: 20.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.w)),
color: Colors.white,
),
child: Center(
child: Text(
"加好友",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(117, 98, 249, 1),
Obx(() {
final anchorInfo = _roomController
.rtcChannelDetail
.value
?.anchorInfo;
//
if (anchorInfo?.isFriend == true) {
return const SizedBox.shrink();
}
return Positioned(
bottom: 5.w,
right: 5.w,
child: Container(
width: 47.w,
height: 20.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.w)),
color: Colors.white,
),
child: Center(
child: Text(
"加好友",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(117, 98, 249, 1),
),
),
),
),
).onTap((){
final anchorInfo = _roomController
.rtcChannelDetail
.value
?.anchorInfo;
if (anchorInfo != null) {
_showGiftPopupForUser(anchorInfo, 2);
}
}),
),
});
}),
],
),
SizedBox(height: 5.w),
@ -243,7 +249,7 @@ class _LiveRoomAnchorShowcaseState extends State<LiveRoomAnchorShowcase> {
),
),
),
if(!isCurrentUser)
if(!isCurrentUser && userInfo.isFriend != true)
Positioned(
top: 5.w,
right: 5.w,
@ -267,7 +273,7 @@ class _LiveRoomAnchorShowcaseState extends State<LiveRoomAnchorShowcase> {
),
),
),
if(!isCurrentUser)
if(!isCurrentUser && userInfo.isFriend != true)
Positioned(
bottom: 5.w,
right: 5.w,

Loading…
Cancel
Save