diff --git a/assets/images/avatar_pendant.png b/assets/images/avatar_pendant.png new file mode 100644 index 0000000..1d2d9e4 Binary files /dev/null and b/assets/images/avatar_pendant.png differ diff --git a/assets/images/join_room_icon.png b/assets/images/join_room_icon.png new file mode 100644 index 0000000..2273810 Binary files /dev/null and b/assets/images/join_room_icon.png differ diff --git a/assets/images/matchmaker_tag.png b/assets/images/matchmaker_tag.png new file mode 100644 index 0000000..3179927 Binary files /dev/null and b/assets/images/matchmaker_tag.png differ diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index bf53b7f..ecf6f99 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -77,6 +77,7 @@ class Assets { static const String imagesArrowForwardRight = 'assets/images/arrow_forward_right.png'; static const String imagesArrowR = 'assets/images/arrow_r.png'; static const String imagesAudio = 'assets/images/audio.png'; + static const String imagesAvatarPendant = 'assets/images/avatar_pendant.png'; static const String imagesAvatarsExample = 'assets/images/avatars_example.png'; static const String imagesBackIcon = 'assets/images/back_icon.png'; static const String imagesBankIcon = 'assets/images/bank_icon.png'; @@ -131,6 +132,7 @@ class Assets { static const String imagesHomePre = 'assets/images/home_pre.png'; static const String imagesImCoinIcon = 'assets/images/im_coin_icon.png'; static const String imagesInformationBg = 'assets/images/information_bg.png'; + static const String imagesJoinRoomIcon = 'assets/images/join_room_icon.png'; static const String imagesLastMsgIcon = 'assets/images/last_msg_icon.png'; static const String imagesLimitTime = 'assets/images/limit_time.png'; static const String imagesLiveIcon = 'assets/images/live_icon.png'; @@ -148,6 +150,7 @@ class Assets { static const String imagesMatchmakerIcon2 = 'assets/images/matchmaker_icon2.png'; static const String imagesMatchmakerIcon3 = 'assets/images/matchmaker_icon3.png'; static const String imagesMatchmakerIcon4 = 'assets/images/matchmaker_icon4.png'; + static const String imagesMatchmakerTag = 'assets/images/matchmaker_tag.png'; static const String imagesMessageNol = 'assets/images/message_nol.png'; static const String imagesMessagePre = 'assets/images/message_pre.png'; static const String imagesMicClose = 'assets/images/mic_close.png'; diff --git a/lib/im/im_manager.dart b/lib/im/im_manager.dart index 72d59c0..c266b31 100644 --- a/lib/im/im_manager.dart +++ b/lib/im/im_manager.dart @@ -4,6 +4,7 @@ import 'package:dating_touchme_app/rtc/rtm_manager.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:im_flutter_sdk/im_flutter_sdk.dart'; @@ -13,6 +14,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import '../controller/message/conversation_controller.dart'; import '../controller/message/chat_controller.dart'; import '../controller/global.dart'; +import '../generated/assets.dart'; import '../pages/mine/login_page.dart'; import '../pages/message/chat_page.dart'; import '../network/user_api.dart'; @@ -221,8 +223,231 @@ class IMManager { EMChatEventHandler( onMessagesReceived: (messages) { debugPrint('📩 收到消息数: ${messages.length}'); + debugPrint("受到的消息:$messages"); // 从消息扩展字段中解析用户信息并缓存 for (var message in messages) { + print("object"); + print(message.body.type == MessageType.CUSTOM); + print(message.body.type); + print(MessageType.CUSTOM); + print("object"); + if(message.body.type == MessageType.CUSTOM){ + final body = message.body as EMCustomMessageBody; + if(body.event == "live_room_invite"){ + print(23232323232); + SmartDialog.show( + alignment: Alignment.center, + maskColor: Colors.black.withOpacity(0.5), + onDismiss: () { + + }, + builder: (context) { + // return LiveRoomGuestListDialog( + // initialTab: isMaleSeat ? 1 : 0, // 0: 女嘉宾, 1: 男嘉宾 + // ); + return ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(16.w)), + child: Material( + child: Container( + width: 311.w, + height: 305.w, + color: Colors.white, + padding: EdgeInsets.only( + top: 28.w, + left: 23.w, + right: 23.w, + bottom: 20.w + ), + child: Column( + children: [ + Stack( + children: [ + Image.asset( + Assets.imagesAvatarPendant, + width: 174.w, + height: 103.w, + ), + Positioned( + left: 38.5.w, + top: 0, + child: Image.asset( + Assets.imagesUserAvatar, + width: 100.w, + height: 100.w, + ), + ), + Positioned( + left: 68.w, + bottom: 0, + child: Image.asset( + Assets.imagesMatchmakerTag, + width: 41.w, + ), + ) + ], + ), + SizedBox(height: 10.w,), + Text( + "开心的橘子", + style: TextStyle( + fontSize: 18.w, + ), + ), + SizedBox(height: 10.w,), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if(false) Container( + width: 33.w, + height: 13.w, + margin: EdgeInsets.only(right: 6.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(13.w)), + color: const Color.fromRGBO(255, 237, 255, 1) + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + Assets.imagesFemale, + width: 8.w, + height: 8.w, + ), + SizedBox(width: 2.w,), + Text( + "19", + style: TextStyle( + fontSize: 11.w, + color: const Color.fromRGBO(255, 66, 236, 1) + ), + ) + ], + ), + ), + Container( + width: 33.w, + height: 13.w, + margin: EdgeInsets.only(right: 6.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(13.w)), + color: const Color.fromRGBO(237, 245, 255, 1) + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + Assets.imagesMale, + width: 8.w, + height: 8.w, + ), + SizedBox(width: 2.w,), + Text( + "19", + style: TextStyle( + fontSize: 11.w, + color: const Color.fromRGBO(120, 140, 255, 1) + ), + ) + ], + ), + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 2.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(14.w)), + color: const Color.fromRGBO(245, 247, 255, 1) + ), + child: Text( + "北京", + style: TextStyle( + fontSize: 12.w, + fontWeight: FontWeight.w400 + ), + ), + ) + ], + ), + Container( + margin: EdgeInsets.symmetric(vertical: 10.w), + height: 27.w, + color: const Color.fromRGBO(247, 247, 247, 1), + child: Center( + child: Text( + "红娘帮你找适合的ta~来我直播间", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: 128.w, + height: 40.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(12.w)), + color: const Color.fromRGBO(237, 237, 237, 1) + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + Assets.imagesHangUpIcon, + width: 26.w, + height: 26.w, + ), + SizedBox(width: 5.w,), + Text( + "不去了", + style: TextStyle( + fontSize: 15.w + ), + ) + ], + ), + ), + Container( + width: 128.w, + height: 40.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(12.w)), + color: const Color.fromRGBO(117, 98, 249, 1) + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + Assets.imagesJoinRoomIcon, + width: 18.w, + height: 17.w, + ), + SizedBox(width: 5.w,), + Text( + "免费围观", + style: TextStyle( + fontSize: 15.w, + color: Colors.white + ), + ) + ], + ), + ), + ], + ) + ], + ), + ), + ), + ); + }, + ); + + return; + } + } if (message.direction == MessageDirection.RECEIVE && message.onlineState) { // 检查发送者是否是当前正在聊天的用户 diff --git a/lib/pages/discover/settlement_page.dart b/lib/pages/discover/settlement_page.dart index 9e68b2b..dabaf60 100644 --- a/lib/pages/discover/settlement_page.dart +++ b/lib/pages/discover/settlement_page.dart @@ -1,7 +1,14 @@ import 'package:dating_touchme_app/components/page_appbar.dart'; +import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:dating_touchme_app/generated/assets.dart'; +import 'package:dating_touchme_app/widget/live/today_task_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; + +import '../../controller/discover/room_controller.dart'; class SettlementPage extends StatefulWidget { const SettlementPage({super.key}); @@ -11,6 +18,19 @@ class SettlementPage extends StatefulWidget { } class _SettlementPageState extends State { + + + late final RoomController _roomController; + + @override + void initState() { + super.initState(); + + _roomController = Get.isRegistered() + ? Get.find() + : Get.put(RoomController()); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -42,7 +62,7 @@ class _SettlementPageState extends State { padding: EdgeInsets.only( top: 70.w, right: 26.w, - bottom: 47.w, + bottom: 38.w, left: 26.w, ), decoration: BoxDecoration( @@ -183,7 +203,27 @@ class _SettlementPageState extends State { Image.asset( Assets.imagesSettlementToday, width: 325.w, - ), + ).onTap(() async { + // 隐藏键盘 + FocusScope.of(context).unfocus(); + // 隐藏 overlay + SmartDialog.dismiss(); + _roomController.setDialogDismiss(true); + + await _roomController.getTaskData(); + + SmartDialog.show( + alignment: Alignment.bottomCenter, + maskColor: TDTheme.of(context).fontGyColor2, + onDismiss: (){ + _roomController.setDialogDismiss(false); + }, + + builder: (_) { + return TodayTaskDialog(); + }, + ); + }), SizedBox(height: 7.w,), Image.asset( Assets.imagesSettlementMonth, @@ -207,7 +247,10 @@ class _SettlementPageState extends State { ), ), ), - ) + ).onTap(() { + // Get.offAll(() => const MainPage()); + Get.back(); + }) ], ), ), diff --git a/lib/pages/mine/my_wallet_page.dart b/lib/pages/mine/my_wallet_page.dart index b59efba..f70e1e8 100644 --- a/lib/pages/mine/my_wallet_page.dart +++ b/lib/pages/mine/my_wallet_page.dart @@ -358,6 +358,7 @@ class _InfoItemState extends State { widget.item.tradeType == 114 ? "1V1语音" : widget.item.tradeType == 115 ? "1V1视频" : widget.item.tradeType == 116 ? "连麦收益" : + widget.item.tradeType == 117 ? "任务奖励" : widget.item.tradeType == 201 ? "平台服务费" : widget.item.tradeType == 202 ? "提现" : ""}", style: TextStyle( diff --git a/lib/widget/live/live_room_notice_chat_panel.dart b/lib/widget/live/live_room_notice_chat_panel.dart index 42629e1..b29cdde 100644 --- a/lib/widget/live/live_room_notice_chat_panel.dart +++ b/lib/widget/live/live_room_notice_chat_panel.dart @@ -7,6 +7,7 @@ import 'package:dating_touchme_app/model/discover/task_data.dart'; import 'package:dating_touchme_app/pages/discover/task_detail.dart'; import 'package:dating_touchme_app/widget/live/live_room_chat_item.dart'; import 'package:dating_touchme_app/widget/live/live_recharge_popup.dart'; +import 'package:dating_touchme_app/widget/live/today_task_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; @@ -234,90 +235,7 @@ class _LiveRoomNoticeChatPanelState extends State { }, builder: (_) { - return ClipRRect( - borderRadius: BorderRadius.vertical(top: Radius.circular(9.w)), - child: Material( - color: Colors.white, - child: Container( - width: 375.w, - height: 336.w, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color.fromRGBO(236, 224, 255, 1), // 0% - Color.fromRGBO(247, 247, 247, 1), // 100% - ], - ), - ), - child: Column( - children: [ - SizedBox( - height: 77.w, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: 68.w, - padding: EdgeInsets.only(left: 15.w), - alignment: Alignment.centerLeft, - child: Icon( - Icons.keyboard_arrow_left, - size: 26.w, - color: const Color.fromRGBO(144, 144, 144, 1), - ), - ), - Text( - "今日任务", - style: TextStyle( - fontSize: 21.w, - fontWeight: FontWeight.w700 - ), - ), - Container( - width: 68.w, - height: 22.w, - decoration: BoxDecoration( - borderRadius: BorderRadius.horizontal(left: Radius.circular(22.w)), - color: Colors.white - ), - child: Center( - child: Text( - "任务详情", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ), - ), - ).onTap(() async { - // 隐藏键盘 - FocusScope.of(context).unfocus(); - // 隐藏 overlay - await SmartDialog.dismiss(); - Get.to(() => TaskDetail()); - }) - ], - ), - ), - SingleChildScrollView( - child: Container( - padding: EdgeInsets.symmetric(horizontal: 12.w), - child: Column( - children: [ - ...roomController.taskData.value.subList!.map((e){ - return TaskItem(item: e,); - }) - ], - ), - ), - ) - ], - ), - ), - ), - ); + return TodayTaskDialog(); }, ); }) @@ -327,58 +245,4 @@ class _LiveRoomNoticeChatPanelState extends State { ), ); } -} - -class TaskItem extends StatefulWidget { - final SubList item; - const TaskItem({super.key, required this.item}); - - @override - State createState() => _TaskItemState(); -} - -class _TaskItemState extends State { - @override - Widget build(BuildContext context) { - return Container( - width: 350.w, - margin: EdgeInsets.only(bottom: 10.w), - padding: EdgeInsets.only( - top: 15.w, - right: 10.w, - bottom: 21.w, - left: 12.w - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.item.subTaskDesc ?? "", - style: TextStyle( - fontSize: 14.w - ), - ), - Text( - "${widget.item.completeCount ?? ""}/${widget.item.requiredCount ?? ""}${widget.item.sort == 1 ? "分钟" : widget.item.sort == 2 ? "对" : "人"}", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ) - ], - ), - SizedBox(height: 10.w,), - TDProgress( - type: TDProgressType.linear, - value: ((widget.item.completeCount ?? 0) / (widget.item.requiredCount ?? 0)), - strokeWidth: 6, - progressLabelPosition: TDProgressLabelPosition.inside, - showLabel: false, - ) - ], - ), - ); - } -} +} \ No newline at end of file diff --git a/lib/widget/live/live_room_user_header.dart b/lib/widget/live/live_room_user_header.dart index 19027d8..244677d 100644 --- a/lib/widget/live/live_room_user_header.dart +++ b/lib/widget/live/live_room_user_header.dart @@ -1,6 +1,8 @@ import 'package:dating_touchme_app/controller/discover/room_controller.dart'; import 'package:dating_touchme_app/controller/overlay_controller.dart'; import 'package:dating_touchme_app/generated/assets.dart'; +import 'package:dating_touchme_app/pages/discover/live_end_page.dart'; +import 'package:dating_touchme_app/pages/discover/settlement_page.dart'; import 'package:dating_touchme_app/widget/live/disconnect_mic_dialog.dart'; import 'package:dating_touchme_app/widget/live/kick_list.dart'; import 'package:easy_refresh/easy_refresh.dart'; @@ -203,7 +205,7 @@ class LiveRoomUserHeader extends StatelessWidget { roomController.chatMessages.clear(); } // 如果还没有执行 pop,手动调用 Get.back() - Get.back(); + Get.off(() => SettlementPage()); // 等待页面关闭后再显示小窗口,确保小窗口能正确显示 Future.delayed(const Duration(milliseconds: 200), () { overlayController.hide(); diff --git a/lib/widget/live/live_room_user_profile_dialog.dart b/lib/widget/live/live_room_user_profile_dialog.dart index 068a7ef..442fe32 100644 --- a/lib/widget/live/live_room_user_profile_dialog.dart +++ b/lib/widget/live/live_room_user_profile_dialog.dart @@ -1,5 +1,6 @@ import 'package:dating_touchme_app/controller/discover/room_controller.dart'; import 'package:dating_touchme_app/controller/overlay_controller.dart'; +import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/model/live/live_chat_message.dart'; import 'package:dating_touchme_app/pages/message/chat_page.dart'; @@ -44,12 +45,12 @@ void showUserProfileDialog( children: [ SizedBox(width: 110.w,), if(isHost) Container( - width: 90.w, + width: 111.w, height: 30.w, margin: EdgeInsets.only(right: 10.w), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(9.w)), - color: Colors.red, + color: const Color.fromRGBO(253, 43, 84, 1), ), child: Center( child: Text( @@ -59,25 +60,44 @@ void showUserProfileDialog( ), ), ), - ), + ).onTap(() async { + await roomController.inviteMic([message.userId]); + + // 隐藏键盘 + FocusScope.of(context).unfocus(); + // 隐藏 overlay + SmartDialog.dismiss(); + roomController.setDialogDismiss(false); + }), if(isHost) Container( - width: 90.w, + width: 81.w, height: 30.w, margin: EdgeInsets.only(right: 10.w), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(9.w)), - color: Colors.red, + color: const Color.fromRGBO(245, 245, 245, 1), ), child: Center( child: Text( "踢出房间", style: TextStyle( - color: Colors.white + color: const Color.fromRGBO(144, 144, 144, 1) ), ), ), - ), + ).onTap(() async { + // 解除连麦 + await roomController.kickingRtcChannelUser( + channelId: roomController.rtcChannelDetail.value!.channelId, + kickingUId: message.uid ?? 0); + + // 隐藏键盘 + FocusScope.of(context).unfocus(); + // 隐藏 overlay + SmartDialog.dismiss(); + roomController.setDialogDismiss(false); + }), GestureDetector( onTap: () => SmartDialog.dismiss(), child: Icon( diff --git a/lib/widget/live/today_task_dialog.dart b/lib/widget/live/today_task_dialog.dart new file mode 100644 index 0000000..1a42f5a --- /dev/null +++ b/lib/widget/live/today_task_dialog.dart @@ -0,0 +1,163 @@ +import 'package:dating_touchme_app/controller/discover/room_controller.dart'; +import 'package:dating_touchme_app/extension/ex_widget.dart'; +import 'package:dating_touchme_app/model/discover/task_data.dart'; +import 'package:dating_touchme_app/pages/discover/task_detail.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; + +class TodayTaskDialog extends StatefulWidget { + const TodayTaskDialog({super.key}); + + @override + State createState() => _TodayTaskDialogState(); +} + +class _TodayTaskDialogState extends State { + @override + Widget build(BuildContext context) { + + final roomController = Get.find(); + return ClipRRect( + borderRadius: BorderRadius.vertical(top: Radius.circular(9.w)), + child: Material( + color: Colors.white, + child: Container( + width: 375.w, + height: 336.w, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color.fromRGBO(236, 224, 255, 1), // 0% + Color.fromRGBO(247, 247, 247, 1), // 100% + ], + ), + ), + child: Column( + children: [ + SizedBox( + height: 77.w, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: 68.w, + padding: EdgeInsets.only(left: 15.w), + alignment: Alignment.centerLeft, + child: Icon( + Icons.keyboard_arrow_left, + size: 26.w, + color: const Color.fromRGBO(144, 144, 144, 1), + ), + ), + Text( + "今日任务", + style: TextStyle( + fontSize: 21.w, + fontWeight: FontWeight.w700 + ), + ), + Container( + width: 68.w, + height: 22.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.horizontal(left: Radius.circular(22.w)), + color: Colors.white + ), + child: Center( + child: Text( + "任务详情", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ), + ), + ).onTap(() async { + // 隐藏键盘 + FocusScope.of(context).unfocus(); + // 隐藏 overlay + await SmartDialog.dismiss(); + Get.to(() => TaskDetail()); + }) + ], + ), + ), + SingleChildScrollView( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 12.w), + child: Column( + children: [ + ...roomController.taskData.value.subList!.map((e){ + return TaskItem(item: e,); + }) + ], + ), + ), + ) + ], + ), + ), + ), + ); + } +} + + +class TaskItem extends StatefulWidget { + final SubList item; + const TaskItem({super.key, required this.item}); + + @override + State createState() => _TaskItemState(); +} + +class _TaskItemState extends State { + @override + Widget build(BuildContext context) { + return Container( + width: 350.w, + margin: EdgeInsets.only(bottom: 10.w), + padding: EdgeInsets.only( + top: 15.w, + right: 10.w, + bottom: 21.w, + left: 12.w + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.item.subTaskDesc ?? "", + style: TextStyle( + fontSize: 14.w + ), + ), + Text( + "${widget.item.completeCount ?? ""}/${widget.item.requiredCount ?? ""}${widget.item.sort == 1 ? "分钟" : widget.item.sort == 2 ? "对" : "人"}", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ) + ], + ), + SizedBox(height: 10.w,), + TDProgress( + type: TDProgressType.linear, + value: ((widget.item.completeCount ?? 0) / (widget.item.requiredCount ?? 0)), + strokeWidth: 6, + progressLabelPosition: TDProgressLabelPosition.inside, + showLabel: false, + ) + ], + ), + ); + } +}