import 'dart:convert'; import 'package:extended_image/extended_image.dart' show ExtendedNetworkImageProvider; import 'package:extended_text/extended_text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/app/constants/sc_global_config.dart'; import 'package:yumi/shared/tools/sc_room_utils.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/ui_kit/theme/socialchat_theme.dart'; import 'package:yumi/app/constants/sc_room_msg_type.dart'; import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; import 'package:yumi/shared/business_logic/models/res/gift_res.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/shared/business_logic/models/res/mic_res.dart'; import 'package:yumi/shared/business_logic/usecases/sc_case.dart'; import 'package:yumi/modules/index/main_route.dart'; import '../../../shared/data_sources/models/enum/sc_activity_reward_props_type.dart'; import '../../../shared/data_sources/models/enum/sc_room_roles_type.dart'; import '../../components/sc_compontent.dart'; import '../../components/sc_tts.dart'; import '../../components/text/sc_text.dart'; ///消息item class MsgItem extends StatefulWidget { final Function(SocialChatUserProfile? user) onClick; Msg msg; MsgItem({Key? key, required this.msg, required this.onClick}) : super(key: key); @override _MsgItemState createState() => _MsgItemState(); } class _MsgItemState extends State { @override Widget build(BuildContext context) { //gift // if (msg.type == Roomtype.gift.code) { // return _buildGiftMsg(context); // } ///系统提示 if (widget.msg.type == SCRoomMsgType.systemTips) { return _systemTipsRoomItem(context); } ///进入房间 if (widget.msg.type == SCRoomMsgType.joinRoom) { return _enterRoomItem(context); } ///礼物 if (widget.msg.type == SCRoomMsgType.gift) { return _buildGiftMsg(context); } ///火箭用户中奖 if (widget.msg.type == SCRoomMsgType.rocketRewardUser) { return _buildRocketRewardMsg(context); } ///幸运礼物 if (widget.msg.type == SCRoomMsgType.gameLuckyGift) { return _buildGameLuckyGiftMsg(context); } ///幸运礼物 if (widget.msg.type == SCRoomMsgType.gameLuckyGift_5) { return _buildGameLuckyGiftMsg_5(context); } ///房间身份变动 if (widget.msg.type == SCRoomMsgType.roomRoleChange) { return _buildRoleChangeMsg(context); } ///踢出房间 if (widget.msg.type == SCRoomMsgType.qcfj) { widget.msg.msg = SCAppLocalizations.of(context)!.kickRoomTips; } ///图片消息 if (widget.msg.type == SCRoomMsgType.image) { return _buildImageMsg(context); } ///掷骰子 if (widget.msg.type == SCRoomMsgType.roomDice) { return _buildDiceMsg(context); } ///石头剪刀布 if (widget.msg.type == SCRoomMsgType.roomRPS) { return _buildRPSMsg(context); } ///幸运数字 if (widget.msg.type == SCRoomMsgType.roomLuckNumber) { return _buildLuckNumberMsg(context); } if (widget.msg.user != null) { PropsResources? chatBox = widget.msg.user?.getChatBox(); return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(5.w), vertical: width(4), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 6.w), child: Column( children: [ _buildUserInfoLine(context), SizedBox(height: 6.w), Row( children: [ Flexible( // 使用Flexible替代Expanded child: GestureDetector( child:Container( constraints: BoxConstraints( maxWidth: ScreenUtil().screenWidth * 0.7, // 最大宽度约束 ), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.only( topRight: Radius.circular(15.w), bottomLeft: Radius.circular(15.w), bottomRight: Radius.circular(15.w), ), ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 4.w, ), margin: EdgeInsetsDirectional.only( start: 54.w, ).copyWith(bottom: 8.w), child: ExtendedText( widget.msg?.msg ?? '', style: TextStyle( fontSize: sp(13), color: Color( _msgColor(widget.msg.type ?? ""), ), fontWeight: FontWeight.w500, ), softWrap: true, // 自动换行 specialTextSpanBuilder: AtTextSpanBuilder( onTapCall: (userId) {}, ), ), ), onLongPress: () { if (!(widget.msg?.msg ?? "").startsWith(AtText.flag)) { Clipboard.setData( ClipboardData(text: widget.msg?.msg ?? ''), ); SCTts.show("Copied"); } }, ), ), ], ), ], ), ), ); } else { return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(8.w), vertical: width(4), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 6.w), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.all(Radius.circular(15.w)), ), child: Text( widget.msg?.msg ?? '', style: TextStyle( fontSize: sp(13), color: Color(_msgColor(widget.msg.type ?? "")), fontWeight: FontWeight.w500, ), textAlign: TextAlign.left, ), ), ); } } ///系统提示 _systemTipsRoomItem(BuildContext context) { return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(8.w), vertical: width(8), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 8.w), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.all(Radius.circular(15.w)), ), child: Text( widget.msg?.msg ?? '', style: TextStyle( fontSize: sp(13), height: 1.5.w, color: Color(_msgColor(widget.msg.type ?? "")), fontWeight: FontWeight.w500, ), textAlign: TextAlign.left, ), ), ); } ///火箭用户中奖 _buildRocketRewardMsg(BuildContext context) { List spans = []; spans.add( TextSpan( text: "${widget.msg.user?.userNickname} ", style: TextStyle( fontSize: sp(12), color: SocialChatTheme.primaryColor, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( TextSpan( text: SCAppLocalizations.of(context)!.inRocket, style: TextStyle( fontSize: sp(12), color: Colors.white, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( WidgetSpan( alignment: PlaceholderAlignment.middle, child: Image.asset( "sc_images/room/sc_icon_room_rocket_lv${widget.msg.number}.png", width: 18.w, ), ), ); spans.add( TextSpan( text: SCAppLocalizations.of(context)!.obtain, style: TextStyle( fontSize: sp(12), color: Colors.white, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( WidgetSpan( alignment: PlaceholderAlignment.middle, child: widget.msg.role == SCActivityRewardATPropsType.GOLD.name ? Image.asset("sc_images/general/sc_icon_jb.png", width: 18.w) : netImage(url: widget.msg.msg ?? "", width: 18.w), ), ); Widget text = Text.rich( TextSpan(children: spans), textAlign: TextAlign.left, strutStyle: StrutStyle( height: 1.8, // 行高倍数 fontWeight: FontWeight.w500, forceStrutHeight: true, // 强制应用行高 ), ); return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.w), margin: EdgeInsets.only(left: 34.w).copyWith(bottom: 8.w), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.all(Radius.circular(15.w)), ), child: text, ), ); } ///幸运礼物 _buildGameLuckyGiftMsg(BuildContext context) { List spans = []; spans.add( TextSpan( text: "${widget.msg.user?.userNickname} ", style: TextStyle( fontSize: sp(12), color: SocialChatTheme.primaryColor, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer() ..onTap = () { widget.onClick(widget.msg.user); }, ), ); spans.add( TextSpan( text: SCAppLocalizations.of(context)!.sendTo, style: TextStyle( fontSize: sp(12), color: Colors.white, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( TextSpan( text: " ${widget.msg.toUser?.userNickname} ", style: TextStyle( fontSize: sp(12), color: SocialChatTheme.primaryColor, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer() ..onTap = () { widget.onClick(widget.msg.toUser); }, ), ); SCGlobalConfig.lang == "ar" ? spans.add( WidgetSpan( alignment: PlaceholderAlignment.middle, child: Image.asset("sc_images/general/sc_icon_jb.png", width: 18.w), ), ) : spans.add( WidgetSpan( alignment: PlaceholderAlignment.middle, child: netImage(url: widget.msg.gift?.giftPhoto ?? "", width: 18.w), ), ); spans.add( TextSpan( text: " ${SCAppLocalizations.of(context)!.obtain}", style: TextStyle( fontSize: sp(12), color: SocialChatTheme.primaryColor, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( TextSpan( text: " ${widget.msg.awardAmount}", style: TextStyle( fontSize: sp(12), color: SocialChatTheme.primaryColor, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); SCGlobalConfig.lang == "ar" ? spans.add( WidgetSpan( alignment: PlaceholderAlignment.middle, child: netImage(url: widget.msg.gift?.giftPhoto ?? "", width: 18.w), ), ) : spans.add( WidgetSpan( alignment: PlaceholderAlignment.middle, child: Image.asset("sc_images/general/sc_icon_jb.png", width: 18.w), ), ); Widget text = Text.rich( TextSpan(children: spans), textAlign: TextAlign.left, strutStyle: StrutStyle( height: 1.3, // 行高倍数 fontWeight: FontWeight.w500, forceStrutHeight: true, // 强制应用行高 ), ); return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.w), margin: EdgeInsets.only(left: 34.w).copyWith(bottom: 8.w), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.all(Radius.circular(15.w)), ), child: text, ), ); } ///幸运礼物中奖5倍以及以上 _buildGameLuckyGiftMsg_5(BuildContext context) { List spans = []; spans.add( TextSpan( text: "${widget.msg.user?.userNickname} ", style: TextStyle( fontSize: sp(12), color: Color(0xffFEF129), fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer() ..onTap = () { widget.onClick(widget.msg.user); }, ), ); spans.add( TextSpan( text: SCAppLocalizations.of(context)!.get, style: TextStyle( fontSize: sp(12), color: Colors.white, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( TextSpan( text: " ${widget.msg.awardAmount} ", style: TextStyle( fontSize: sp(12), color: Color(0xffFEF129), fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( TextSpan( text: SCAppLocalizations.of(context)!.coins3, style: TextStyle( fontSize: sp(12), color: Color(0xffFEF129), fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( TextSpan( text: " ${SCAppLocalizations.of(context)!.receivedFromALuckyGift}", style: TextStyle( fontSize: sp(12), color: Colors.white, fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); Widget text = Text.rich( TextSpan(children: spans), textAlign: TextAlign.left, strutStyle: StrutStyle( height: 1.2, // 行高倍数 fontWeight: FontWeight.w500, forceStrutHeight: true, // 强制应用行高 ), ); return Container( alignment: AlignmentDirectional.topStart, child: Container( constraints: BoxConstraints(minHeight: 68.w), padding: EdgeInsets.symmetric(vertical: 5.w), margin: EdgeInsets.only(left: 34.w).copyWith(bottom: 8.w), decoration: BoxDecoration( image: DecorationImage( image: AssetImage("sc_images/room/sc_icon_luck_gift_msg_n_bg.png"), fit: BoxFit.fill, ), ), child: Row( children: [ SizedBox(width: 10.w), Expanded(child: text), Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage( "sc_images/room/sc_icon_luck_gift_msg_n_ball.png", ), fit: BoxFit.fill, ), ), alignment: AlignmentDirectional.center, width: 55.w, height: 60.w, child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 10.w), buildNumForGame(widget.msg.msg ?? "0", size: 18.w), SizedBox(height: 3.w), SCGlobalConfig.lang == "ar" ? Image.asset( "sc_images/room/sc_icon_times_text_ar.png", height: 12.w, ) : Image.asset( "sc_images/room/sc_icon_times_text_en.png", height: 10.w, ), ], ), ), SizedBox(width: 15.w), ], ), ), ); } Widget _buildGiftMsg(BuildContext context) { return Container( alignment: AlignmentDirectional.topStart, padding: EdgeInsets.symmetric(horizontal: width(5.w), vertical: width(4)), margin: EdgeInsets.symmetric(horizontal: width(10)).copyWith(bottom: 8.w), child: Column( children: [ _buildUserInfoLine(context), SizedBox(height: 6.w), Row( children: [ Flexible( // 使用Flexible替代Expanded child:Container( constraints: BoxConstraints( maxWidth: ScreenUtil().screenWidth * 0.7, // 最大宽度约束 ), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.only( topRight: Radius.circular(15.w), bottomLeft: Radius.circular(15.w), bottomRight: Radius.circular(15.w), ), ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 4.w, ), margin: EdgeInsetsDirectional.only( start: 54.w, ).copyWith(bottom: 8.w), child: Text.rich( TextSpan( children: [ TextSpan( text: SCAppLocalizations.of(context)!.sendTo, style: TextStyle( fontSize: 13.sp, color: Colors.white, ), ), TextSpan(text: " "), TextSpan( text: widget.msg.toUser?.userNickname ?? "", style: TextStyle( fontSize: 13.sp, color: SocialChatTheme.primaryColor, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), TextSpan(text: " "), WidgetSpan( child: netImage( url: widget.msg.gift?.giftPhoto ?? "", width: 22.w, height: 22.w, ), ), TextSpan(text: " "), TextSpan( text: "x${widget.msg.number}", style: TextStyle( fontSize: 13.sp, color: Colors.white, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ], ), textAlign: TextAlign.left, ), ), ), ], ), ], ), ); } ///进入房间 _enterRoomItem(BuildContext context) { List spans = []; if (widget.msg.role != null && widget.msg.role != 0) { spans.add( WidgetSpan( alignment: PlaceholderAlignment.middle, child: Padding( padding: EdgeInsets.only(right: 3.w), child: msgRoleTag(widget.msg.role ?? "", width: 18.w), ), ), ); } spans.add( TextSpan( text: "${widget.msg?.user?.userNickname ?? ''} ", style: TextStyle( fontSize: sp(13), color: _roleNameColor(widget.msg.role ?? ""), fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); spans.add( TextSpan( text: SCAppLocalizations.of(context)!.joinRoomTips, style: TextStyle( fontSize: sp(13), color: Color(_msgColor(widget.msg.type ?? "")), fontWeight: FontWeight.w500, ), ), ); Widget text = Text.rich( TextSpan(children: spans), textAlign: TextAlign.left, ); return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(8.w), vertical: width(4), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 8.w), child: text, ), ); } Widget _buildMedals(List wearBadge) { return wearBadge.isNotEmpty ? Expanded( child: SingleChildScrollView( child: SizedBox( height: 25.w, child: ListView.separated( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: wearBadge.length ?? 0, itemBuilder: (context, index) { return netImage( width: 25.w, height: 25.w, url: wearBadge[index].selectUrl ?? "", ); }, separatorBuilder: (BuildContext context, int index) { return SizedBox(width: 5.w); }, ), ), ), ) : Container(); } int _msgColor(String type) { switch (type) { case SCRoomMsgType.joinRoom: case SCRoomMsgType.systemTips: case SCRoomMsgType.welcome: return 0xFFFFFFFF; case SCRoomMsgType.gift: return 0xFFFFFFFF; case SCRoomMsgType.shangMai: case SCRoomMsgType.xiaMai: case SCRoomMsgType.qcfj: case SCRoomMsgType.killXiaMai: return 0xFFFFFFFF; break; // case type.text: // return _mapTextColor(); // break; default: return 0xFFFFFFFF; } } _roleNameColor(String role) { if (SCRoomRolesType.HOMEOWNER.name == role) { return Color(0xff2AC0F2); } else if (SCRoomRolesType.ADMIN.name == role) { return Color(0xffF9A024); } else if (SCRoomRolesType.MEMBER.name == role) { return Color(0xff28ED77); } else { return Colors.white; } } Widget _buildRoleChangeMsg(BuildContext context) { var text = ""; if (SCRoomRolesType.ADMIN.name == widget.msg.msg) { text = SCAppLocalizations.of(context)!.adminByHomeowner; } else if (SCRoomRolesType.MEMBER.name == widget.msg.msg) { text = SCAppLocalizations.of(context)!.memberByHomeowner; } else { text = SCAppLocalizations.of(context)!.touristByHomeowner; } List spans = []; if (widget.msg.toUser != null) { spans.add( TextSpan( text: "${widget.msg.toUser?.userNickname ?? ''} ", style: TextStyle( fontSize: sp(13), color: Color(0xff2AC0F2), fontWeight: FontWeight.w500, ), recognizer: TapGestureRecognizer()..onTap = () {}, ), ); } spans.add( TextSpan( text: text, style: TextStyle( fontSize: sp(13), color: Colors.white, fontWeight: FontWeight.w500, ), ), ); Widget textView = Text.rich( TextSpan(children: spans), textAlign: TextAlign.left, ); return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(8.w), vertical: width(8), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 8.w), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.all(Radius.circular(15.w)), ), child: textView, ), ); } Widget _buildImageMsg(BuildContext context) { return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(5.w), vertical: width(4), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 6.w), child: Column( children: [ _buildUserInfoLine(context), SizedBox(height: 6.w), Row( children: [ Flexible( // 使用Flexible替代Expanded child: GestureDetector( child:Container( constraints: BoxConstraints( maxWidth: ScreenUtil().screenWidth * 0.5, // 最大宽度约束 ), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.only( topRight: Radius.circular(15.w), bottomLeft: Radius.circular(15.w), bottomRight: Radius.circular(15.w), ), ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 4.w, ), margin: EdgeInsetsDirectional.only( start: 54.w, ).copyWith(bottom: 8.w), child: netImage(url: widget.msg.msg ?? ""), ), onTap: () { String encodedUrls = Uri.encodeComponent( jsonEncode([widget.msg.msg]), ); SCNavigatorUtils.push( context, "${SCMainRoute.imagePreview}?imageUrls=$encodedUrls&initialIndex=0", ); }, ), ), ], ), ], ), ), ); } Widget _buildDiceMsg(BuildContext context) { return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(5.w), vertical: width(4), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 6.w), child: Column( children: [ _buildUserInfoLine(context), SizedBox(height: 6.w), Row( children: [ Flexible( // 使用Flexible替代Expanded child: GestureDetector( child:Container( constraints: BoxConstraints( maxWidth: ScreenUtil().screenWidth * 0.5, // 最大宽度约束 ), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.only( topRight: Radius.circular(15.w), bottomLeft: Radius.circular(15.w), bottomRight: Radius.circular(15.w), ), ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 4.w, ), margin: EdgeInsetsDirectional.only( start: 54.w, ).copyWith(bottom: 8.w), child: (widget.msg.hasPlayedAnimation ?? false) ? Image.asset( "sc_images/room/sc_icon_dice_${widget.msg.msg}.png", height: 35.w, ) : FutureBuilder( future: Future.delayed( Duration(milliseconds: 2000), ), // 传入Future builder: ( BuildContext context, AsyncSnapshot snapshot, ) { // 根据snapshot的状态来构建UI if (snapshot.connectionState == ConnectionState.done) { widget.msg.hasPlayedAnimation = true; return Image.asset( "sc_images/room/sc_icon_dice_${widget.msg.msg}.png", height: 35.w, ); } else { return Image.asset( "sc_images/room/sc_icon_dice_animl.webp", height: 35.w, ); } }, ), ), onTap: () {}, ), ), ], ), ], ), ), ); } Widget _buildRPSMsg(BuildContext context) { return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(5.w), vertical: width(4), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 6.w), child: Column( children: [ _buildUserInfoLine(context), SizedBox(height: 6.w), Row( children: [ Flexible( // 使用Flexible替代Expanded child: GestureDetector( child:Container( constraints: BoxConstraints( maxWidth: ScreenUtil().screenWidth * 0.5, // 最大宽度约束 ), decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.only( topRight: Radius.circular(15.w), bottomLeft: Radius.circular(15.w), bottomRight: Radius.circular(15.w), ), ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 4.w, ), margin: EdgeInsetsDirectional.only( start: 54.w, ).copyWith(bottom: 8.w), child: (widget.msg.hasPlayedAnimation ?? false) ? Image.asset( "sc_images/room/sc_icon_rps_${widget.msg.msg}.png", height: 35.w, ) : FutureBuilder( future: Future.delayed( Duration(milliseconds: 2000), ), // 传入Future builder: ( BuildContext context, AsyncSnapshot snapshot, ) { // 根据snapshot的状态来构建UI if (snapshot.connectionState == ConnectionState.done) { widget.msg.hasPlayedAnimation = true; return Image.asset( "sc_images/room/sc_icon_rps_${widget.msg.msg}.png", height: 35.w, ); } else { return Image.asset( "sc_images/room/sc_icon_rps_animal.webp", height: 35.w, ); } }, ), ), onTap: () {}, ), ), ], ), ], ), ), ); } Widget _buildLuckNumberMsg(BuildContext context) { return Container( alignment: AlignmentDirectional.topStart, child: Container( padding: EdgeInsets.symmetric( horizontal: width(5.w), vertical: width(4), ), margin: EdgeInsets.symmetric( horizontal: width(10), ).copyWith(bottom: 6.w), child: Column( children: [ _buildUserInfoLine(context), SizedBox(height: 6.w), Row( children: [ Flexible( // 使用Flexible替代Expanded child: GestureDetector( child:Container( constraints: BoxConstraints( maxWidth: ScreenUtil().screenWidth * 0.7, // 最大宽度约束 ), decoration: BoxDecoration( color:Colors.black38, borderRadius: BorderRadius.only( topRight: Radius.circular(15.w), bottomLeft: Radius.circular(15.w), bottomRight: Radius.circular(15.w), ), ), padding: EdgeInsets.symmetric( horizontal: 10.w, vertical: 4.w, ), margin: EdgeInsetsDirectional.only( start: 54.w, ).copyWith(bottom: 8.w), child: Row( mainAxisSize: MainAxisSize.min, children: [ SCGlobalConfig.lang == "ar" ? Image.asset( "sc_images/room/sc_icon_luck_num_text_ar.png", height: 20.w, ) : Image.asset( "sc_images/room/sc_icon_luck_num_text_en.png", height: 20.w, ), buildNumForRoomLuckNum( widget.msg.msg ?? "", size: 20.w, ), ], ), ), onTap: () {}, ), ), ], ), ], ), ), ); } _buildUserInfoLine(BuildContext context) { if ((widget.msg.needUpDataUserInfo) ?? false) { SCRoomUtils.roomUsersMap[widget.msg.user?.id ?? ""] == null; } return SCRoomUtils.roomUsersMap[widget.msg.user?.id ?? ""] == null ? FutureBuilder( future: SCAccountRepository().loadUserInfo(widget.msg.user?.id ?? ""), builder: (ct, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasData) { SocialChatUserProfile user = snapshot.data!; SCRoomUtils.roomUsersMap[user.id ?? ""] = user; return _buildNewUserInfoLine(context, user); } } return Row( children: [ GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { widget.onClick(widget.msg.user); }, child: Stack( alignment: AlignmentDirectional.bottomEnd, children: [ head( url: widget.msg.user?.userAvatar ?? "", width: 48.w, // headdress: msg.user?.getHeaddress()?.sourceUrl, ), Positioned( child: msgRoleTag(widget.msg.role ?? "", width: 14.w), bottom: 2.w, right: 2.w, ), ], ), ), SizedBox(width: 3.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ getWealthLevel( widget.msg.user?.wealthLevel ?? 0, width: 48.w, height: 23.w, fontSize: 10.sp, ), getUserLevel( widget.msg.user?.charmLevel ?? 0, width: 48.w, height: 23.w, fontSize: 10.sp, ), SizedBox(width: 3.w), socialchatNickNameText( maxWidth: 120.w, fontWeight: FontWeight.w500, widget.msg.user?.userNickname ?? "", fontSize: 13.sp, type: widget.msg.user?.getVIP()?.name ?? "", needScroll: (widget .msg .user ?.userNickname ?.characters .length ?? 0) > 10, ), ], ), Row( mainAxisSize: MainAxisSize.min, children: [ widget.msg.user?.getVIP() != null ? netImage( url: widget.msg.user?.getVIP()?.cover ?? "", width: 25.w, height: 25.w, ) : Container(), _buildMedals( (widget.msg.user?.wearBadge?.where((item) { return item.use ?? false; }).toList() ?? []), ), ], ), ], ), ), ], ); }, ) : _buildNewUserInfoLine( context, SCRoomUtils.roomUsersMap[widget.msg.user?.id ?? ""]!, ); } _buildNewUserInfoLine(BuildContext context, SocialChatUserProfile user) { return Row( children: [ GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { widget.onClick(user); }, child: Stack( alignment: AlignmentDirectional.bottomEnd, children: [ head( url: user.userAvatar ?? "", width: 48.w, // headdress: msg.user?.getHeaddress()?.sourceUrl, ), Positioned( child: msgRoleTag(widget.msg.role ?? "", width: 14.w), bottom: 2.w, right: 2.w, ), ], ), ), SizedBox(width: 3.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ getWealthLevel( user.wealthLevel ?? 0, width: 48.w, height: 23.w, fontSize: 10.sp, ), getUserLevel( user.charmLevel ?? 0, width: 48.w, height: 23.w, fontSize: 10.sp, ), SizedBox(width: 3.w), socialchatNickNameText( maxWidth: 120.w, fontWeight: FontWeight.w500, user.userNickname ?? "", fontSize: 13.sp, type: user.getVIP()?.name ?? "", needScroll: (user.userNickname?.characters.length ?? 0) > 10, ), ], ), Row( mainAxisSize: MainAxisSize.min, children: [ user.getVIP() != null ? netImage( url: user.getVIP()?.cover ?? "", width: 25.w, height: 25.w, ) : Container(), _buildMedals( user.wearBadge?.where((item) { return item.use ?? false; }).toList() ?? [], ), ], ), ], ), ), ], ); } } ///消息 class Msg { String? groupId; String? msg; MicRes? userWheat; String? type; SocialChatUserProfile? user; String? role = ""; SocialChatGiftRes? gift; //礼物个数 num? number; num? awardAmount; // 送礼给谁 SocialChatUserProfile? toUser; int? time = 0; //动画是否已经播放(骰子、石头剪刀布、随机数字) bool? hasPlayedAnimation = false; bool? needUpDataUserInfo = false; Msg({ required this.groupId, required this.msg, required this.type, this.user, this.toUser, this.userWheat, this.role = "", this.gift, this.number, this.awardAmount, this.hasPlayedAnimation, this.needUpDataUserInfo, }) { time = DateTime.now().millisecondsSinceEpoch; } Msg.fromJson(dynamic json) { groupId = json['groupId']; msg = json['msg']; type = json['type']; role = json['role']; time = json['time']; number = json['number']; awardAmount = json['awardAmount']; hasPlayedAnimation = json['hasPlayedAnimation']; needUpDataUserInfo = json['needUpDataUserInfo']; userWheat = json['userWheat'] != null ? MicRes.fromJson(json['userWheat']) : null; user = json['user'] != null ? SocialChatUserProfile.fromJson(json['user']) : null; toUser = json['toUser'] != null ? SocialChatUserProfile.fromJson(json['toUser']) : null; gift = json['gift'] != null ? SocialChatGiftRes.fromJson(json['gift']) : null; } Map toJson() { final map = {}; map['groupId'] = groupId; map['msg'] = msg; map['type'] = type; map['role'] = role; map['time'] = time; map['awardAmount'] = awardAmount; map['number'] = number; map['hasPlayedAnimation'] = hasPlayedAnimation; map['needUpDataUserInfo'] = needUpDataUserInfo; if (userWheat != null) { map['userWheat'] = userWheat?.toJson(); } if (user != null) { map['user'] = user?.toJson(); } if (toUser != null) { map['toUser'] = toUser?.toJson(); } if (gift != null) { map['gift'] = gift?.toJson(); } return map; } }