import 'dart:convert'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/main.dart'; import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; import 'package:yumi/ui_kit/components/text/sc_text.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/modules/index/main_route.dart'; import 'package:yumi/services/audio/rtm_manager.dart'; import 'package:yumi/ui_kit/widgets/room/room_msg_input.dart'; import 'package:yumi/ui_kit/widgets/room/room_user_card_setting.dart'; import 'package:marquee/marquee.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'; import 'package:tencent_cloud_chat_sdk/enum/conversation_type.dart'; import 'package:yumi/ui_kit/components/sc_compontent.dart'; import 'package:yumi/ui_kit/components/sc_tts.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; import 'package:yumi/shared/tools/sc_lk_dialog_util.dart'; import 'package:yumi/shared/tools/sc_room_utils.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/shared/business_logic/models/res/user_count_guard_res.dart'; import 'package:yumi/services/general/sc_app_general_manager.dart'; import 'package:yumi/services/audio/rtc_manager.dart'; import 'package:yumi/services/auth/user_profile_manager.dart'; import 'package:yumi/modules/gift/gift_page.dart'; import '../../../shared/data_sources/models/enum/sc_room_roles_type.dart'; import '../../../shared/business_logic/models/res/sc_user_identity_res.dart'; import '../../../modules/chat/chat_route.dart'; class RoomUserInfoCard extends StatefulWidget { String? userId; RoomUserInfoCard({super.key, this.userId}); @override _RoomUserInfoCardState createState() => _RoomUserInfoCardState(); } class _RoomUserInfoCardState extends State { SocialChatUserProfileManager? userProvider; String roomId = ""; SCUserIdentityRes? userIdentity; @override void initState() { super.initState(); userProvider = Provider.of( context, listen: false, ); roomId = Provider.of( context, listen: false, ).currenRoom?.roomProfile?.roomProfile?.id ?? ""; userProvider?.roomUserCard(roomId, widget.userId ?? ""); SCAccountRepository().userIdentity(userId: widget.userId).then((v) { userIdentity = v; setState(() {}); }); } @override void dispose() { super.dispose(); userProvider?.userCardInfo = null; } @override Widget build(BuildContext context) { return SafeArea( top: false, child: Consumer( builder: (context, ref, child) { if (ref.userCardInfo == null) { return SizedBox( height: ScreenUtil().screenHeight * 0.7, child: Center( child: Container( decoration: BoxDecoration( color: Colors.black26, borderRadius: BorderRadius.circular(8), ), width: 55.w, height: 55.w, child: CupertinoActivityIndicator(color: Colors.white24), ), ), ); } return Container( constraints: BoxConstraints( maxHeight: ScreenUtil().screenHeight * 0.7, ), margin: EdgeInsets.symmetric(horizontal: 15.w), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ Stack( alignment: Alignment.center, children: [ Container( margin: EdgeInsets.only( top: ref.userCardInfo?.userProfile ?.getDataCard() ?.sourceUrl != null ? 45.w : 55.w, ), child: Stack( children: [ Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: ref.userCardInfo?.userProfile ?.getDataCard() ?.sourceUrl != null ? [ Colors.transparent, Colors.transparent, ] : [ Color(0xff18F2B1), Color(0xffE4FFF6), Color(0xffE4FFF6), Color(0xffE4FFF6), Color(0xffE4FFF6), Color(0xffE4FFF6), Color(0xffE4FFF6), Color(0xffFFFFFF), ], ), borderRadius: BorderRadius.all( Radius.circular(12.w), ), ), child: Stack( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 25.w), Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox(width: 20.w), GestureDetector( child: head( url: ref .userCardInfo ?.userProfile ?.userAvatar ?? "", width: 55.w, border: Border.all( color: Colors.white, width: 2, ), headdress: ref.userCardInfo?.userProfile ?.getHeaddress() ?.sourceUrl, ), onTap: () { SCNavigatorUtils.push( context, "${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == widget.userId}&tageId=${widget.userId}", ); }, ), SizedBox(width: 3.w), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ msgRoleTag( ref .userCardInfo ?.roomRole ?? "", width: 16.w, height: 16.w, ), SizedBox(width: 2.w), socialchatNickNameText( maxWidth: 115.w, ref .userCardInfo ?.userProfile ?.userNickname ?? "", fontSize: 14.sp, textColor: Colors.black, fontWeight: FontWeight.bold, type: "", needScroll: (ref .userCardInfo ?.userProfile ?.userNickname ?.characters .length ?? 0) > 10, ), ], ), SizedBox(height: 2.w), text( "ID:${ref.userCardInfo?.userProfile?.getID() ?? 0}", fontSize: 12.sp, textColor: Colors.black, fontWeight: FontWeight.bold, ), ], ), ], ), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15.w), color: Colors.transparent, ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 5.w, ), child: Row( children: [ SizedBox(width: 20.w,), netImage( url: Provider.of< SCAppGeneralManager >( context, listen: false, ) .findCountryByName( ref .userCardInfo ?.userProfile ?.countryName ?? "", ) ?.nationalFlag ?? "", borderRadius: BorderRadius.all( Radius.circular(3.w), ), width: 19.w, height: 14.w, ), SizedBox(width: 5.w), Container( constraints: BoxConstraints( maxWidth: 110.w, ), child: text( ref .userCardInfo ?.userProfile ?.countryName ?? "", textColor: Colors.black, fontSize: 12.sp, fontWeight: FontWeight.bold, ), ), ], ), ), SizedBox(width: 5.w), Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage( ref .userCardInfo ?.userProfile ?.userSex == 0 ? "sc_images/login/sc_icon_sex_woman_bg.png" : "sc_images/login/sc_icon_sex_man_bg.png", ), ), ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 5.w, ), child: Row( children: [ xb( ref .userCardInfo ?.userProfile ?.userSex, ), SizedBox(width: 3.w), text( "${ref.userCardInfo?.userProfile?.age ?? 0}", textColor: Colors.white, fontSize: 12.sp, fontWeight: FontWeight.bold, ), ], ), ), ], ), SizedBox(height: 15.w), Container( margin: EdgeInsets.symmetric( horizontal: 25.w, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ widget.userId != AccountStorage() .getCurrentUser() ?.userProfile ?.id ? SCDebounceWidget( child: Column( children: [ Image.asset( "sc_images/room/sc_icon_send_user_message.png", width: 32.w, height: 32.w, ), SizedBox(height: 5.w), Container( alignment: Alignment.center, width: 70.w, child: text( SCAppLocalizations.of( context, )!.sayHi2, textColor: Color( 0xff808080, ), fontWeight: FontWeight.w600, fontSize: 14.sp, ), ), ], ), onTap: () async { Navigator.of(context).pop(); var conversation = V2TimConversation( type: ConversationType .V2TIM_C2C, userID: widget.userId, conversationID: '', ); var bool = await Provider.of< RtmProvider >( context, listen: false, ).startConversation( conversation, ); if (!bool) return; var json = jsonEncode( conversation.toJson(), ); SCNavigatorUtils.push( navigatorKey.currentState!.context, "${SCChatRouter.chat}?conversation=${Uri.encodeComponent(json)}", ); }, ) : Container(), widget.userId != AccountStorage() .getCurrentUser() ?.userProfile ?.id ? SCDebounceWidget( child: Selector< SocialChatUserProfileManager, bool >( selector: (context, provider) => provider .userCardInfo ?.follow ?? false, shouldRebuild: (prev, next) => prev != next, builder: ( context, follow, _, ) { return Column( children: [ Image.asset( follow ? "sc_images/room/sc_icon_user_un_follow.png" : "sc_images/room/sc_icon_user_follow.png", width: 32.w, height: 32.w, ), SizedBox(height: 5.w), Container( alignment: Alignment .center, width: 70.w, child: text( // 使用 Flutter 内置 Text follow ? SCAppLocalizations.of( context, )!.followed : SCAppLocalizations.of( context, )!.follow, // fontSize: 14.sp, textColor: Color( 0xff808080, ), fontWeight: FontWeight .bold, ), ), ], ); }, ), onTap: () { // ✅ 使用正确的 Provider 访问方式 final provider = Provider.of< SocialChatUserProfileManager >(context, listen: false); provider.followUser( widget.userId ?? "", ); }, ) : Container(), widget.userId != AccountStorage() .getCurrentUser() ?.userProfile ?.id ? SCDebounceWidget( child: Column( children: [ Image.asset( "sc_images/room/sc_icon_at_tag_user.png", width: 32.w, height: 32.w, ), SizedBox(height: 5.w), Container( alignment: Alignment.center, width: 70.w, child: text( SCAppLocalizations.of( context, )!.atTag, textColor: Color( 0xff808080, ), fontWeight: FontWeight.w600, fontSize: 14.sp, ), ), ], ), onTap: () async { if (SCRoomUtils.touristCanMsg( context, )) { if ((ref .userCardInfo ?.userProfile ?.userNickname ?? "") .isEmpty) { return; } Navigator.of( context, ).pop(); Navigator.push( context, PopRoute( child: RoomMsgInput( atTextContent: "${ref.userCardInfo?.userProfile?.userNickname}", ), ), ); } }, ) : Container(), widget.userId != AccountStorage() .getCurrentUser() ?.userProfile ?.id ? SCDebounceWidget( child: Column( children: [ Image.asset( "sc_images/room/sc_icon_send_user_gift.png", width: 32.w, height: 32.w, ), SizedBox(height: 5.w), Container( alignment: Alignment.center, width: 70.w, child: text( SCAppLocalizations.of( context, )!.send, textColor: Color( 0xff808080, ), fontWeight: FontWeight.w600, fontSize: 14.sp, ), ), ], ), onTap: () { Navigator.of(context).pop(); SmartDialog.show( tag: "showGiftControl", alignment: Alignment .bottomCenter, maskColor: Colors.transparent, animationType: SmartAnimationType .fade, clickMaskDismiss: true, builder: (_) { return GiftPage( toUser: ref .userCardInfo ?.userProfile, ); }, ); }, ) : Container(), ], ), ), SizedBox(height: 35.w), ], ), ], ), ), AccountStorage() .getCurrentUser() ?.userProfile ?.id != widget.userId ? Positioned( top:28.w, right: 15.w, child: GestureDetector( child: Image.asset( "sc_images/room/sc_icon_user_card_report.png", width: 24.w, height: 24.w, color: Colors.black, ), onTap: () { SCNavigatorUtils.push( context, "${SCMainRoute.report}?type=user&tageId=${widget.userId}", replace: false, ); }, ), ) : Container(), ref.userCardInfo?.roomRole == SCRoomRolesType.HOMEOWNER.name ? Container() : (AccountStorage() .getCurrentUser() ?.userProfile ?.id != widget.userId && Provider.of( context, listen: false, ).isFz() || AccountStorage() .getCurrentUser() ?.userProfile ?.id != widget.userId && Provider.of( context, listen: false, ).isGL()) ? Positioned( top:28.w, right: 45.w, child: GestureDetector( child: Image.asset( "sc_images/room/sc_icon_room_user_card_setting.png", width: 24.w, height: 24.w, color: Colors.black, ), onTap: () { if (userProvider?.userCardInfo != null) { Navigator.of(context).pop(); showBottomInBottomDialog( context!, RoomUserCardSetting( roomId: roomId, userCardInfo: userProvider?.userCardInfo ?.copyWith(), ), ); } }, ), ) : Container(), ], ), ), ], ), ], ), ), ); }, ), ); } String roleName(String role) { if (role == SCRoomRolesType.HOMEOWNER.name) { return SCAppLocalizations.of(context)!.owner; } else if (role == SCRoomRolesType.ADMIN.name) { return SCAppLocalizations.of(context)!.admin; } else if (role == SCRoomRolesType.MEMBER.name) { return SCAppLocalizations.of(context)!.member; } return SCAppLocalizations.of(context)!.guest; } _buildEmptyCpItem(bool canAdd) { return Container( width: ScreenUtil().screenWidth, margin: EdgeInsets.symmetric(horizontal: 12.w), height: 105.w, decoration: BoxDecoration( image: DecorationImage( image: AssetImage( canAdd ? "sc_images/person/sc_icon_no_cp_item_bg.png" : "sc_images/person/sc_icon_no_cp_item_bg4.png", ), fit: BoxFit.fill, ), ), child: Container( margin: EdgeInsets.only(bottom: 13.w), alignment: AlignmentDirectional.bottomCenter, child: text( SCAppLocalizations.of(context)!.noMatchedCP, fontWeight: FontWeight.w600, fontSize: 12.sp, textColor: canAdd ? Color(0xFFFF79A1) : Colors.white, ), ), ); } Widget _buildCpItem(CPRes item) { return Stack( alignment: AlignmentDirectional.center, children: [ Container( width: ScreenUtil().screenWidth, margin: EdgeInsets.symmetric(horizontal: 15.w), height: 135.w, decoration: BoxDecoration( image: DecorationImage( image: AssetImage("sc_images/person/sc_icon_no_cp_item_bg2.png"), fit: BoxFit.fill, ), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 68.w), Container( alignment: AlignmentDirectional.bottomCenter, child: Row( mainAxisSize: MainAxisSize.min, children: [ Image.asset( "sc_images/person/sc_icon_cp_value_tag.png", height: 18.w, ), SizedBox(width: 5.w), text( _cpVaFormat(item.cpValue ?? 0), fontWeight: FontWeight.w600, fontSize: 12.sp, textColor: Color(0xFFFF79A1), ), ], ), ), SizedBox(height: 8.w), Container( alignment: AlignmentDirectional.bottomCenter, child: text( SCAppLocalizations.of( context, )!.timeSpentTogether(item.days ?? ""), fontWeight: FontWeight.w600, fontSize: 12.sp, textColor: Color(0xFFFF79A1), ), ), Container( alignment: AlignmentDirectional.bottomCenter, child: text( SCAppLocalizations.of(context)!.firstDay(item.firstDay ?? ""), fontWeight: FontWeight.w600, fontSize: 11.sp, textColor: Colors.white, ), ), ], ), ), PositionedDirectional( top: 30.w, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( children: [ GestureDetector( child: SizedBox( height: 50.w, child: Stack( alignment: AlignmentDirectional.center, children: [ netImage( url: item.meUserAvatar ?? "", width: 48.w, shape: BoxShape.circle, defaultImg: "sc_images/general/sc_icon_avar_defalt.png", ), Image.asset( "sc_images/person/sc_icon_cp_head_ring.png", ), ], ), ), onTap: () { SCNavigatorUtils.push( context, replace: false, "${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == item.meUserId}&tageId=${item.meUserId}", ); }, ), Container( alignment: Alignment.center, width: 80.w, height: 15.w, child: (item.meUserNickname?.length ?? 0) > 8 ? Marquee( text: item.meUserNickname ?? "", style: TextStyle( fontSize: 10.sp, color: Colors.white, fontWeight: FontWeight.w600, decoration: TextDecoration.none, ), scrollAxis: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.start, blankSpace: 20.0, velocity: 40.0, pauseAfterRound: Duration(seconds: 1), accelerationDuration: Duration(seconds: 1), accelerationCurve: Curves.easeOut, decelerationDuration: Duration(milliseconds: 550), decelerationCurve: Curves.easeOut, ) : Text( item.meUserNickname ?? "", maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, color: Colors.white, fontWeight: FontWeight.w600, decoration: TextDecoration.none, ), ), ), ], ), SizedBox(width: 120.w), Column( children: [ GestureDetector( child: SizedBox( height: 50.w, child: Stack( alignment: AlignmentDirectional.center, children: [ netImage( url: item.cpUserAvatar ?? "", width: 48.w, shape: BoxShape.circle, defaultImg: "sc_images/general/sc_icon_avar_defalt.png", ), Image.asset( "sc_images/person/sc_icon_cp_head_ring.png", ), ], ), ), onTap: () { SCNavigatorUtils.push( context, replace: false, "${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == item.cpUserId}&tageId=${item.cpUserId}", ); }, ), Container( alignment: Alignment.center, width: 80.w, height: 15.w, child: (item.cpUserNickname?.length ?? 0) > 8 ? Marquee( text: item.cpUserNickname ?? "", style: TextStyle( fontSize: 10.sp, color: Colors.white, fontWeight: FontWeight.w600, decoration: TextDecoration.none, ), scrollAxis: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.start, blankSpace: 20.0, velocity: 40.0, pauseAfterRound: Duration(seconds: 1), accelerationDuration: Duration(seconds: 1), accelerationCurve: Curves.easeOut, decelerationDuration: Duration(milliseconds: 550), decelerationCurve: Curves.easeOut, ) : Text( item.cpUserNickname ?? "", maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, color: Colors.white, fontWeight: FontWeight.w600, decoration: TextDecoration.none, ), ), ), ], ), ], ), ), ], ); } String getUserCardBg() { return ""; } String _cpVaFormat(double cpValue) { int value = cpValue.toInt(); if (value > 99999) { return "${(value / 1000).toStringAsFixed(0)}k"; } return "$value"; } }