chatapp3-flutter/lib/ui_kit/widgets/room/room_msg_item.dart
2026-04-09 21:32:23 +08:00

1385 lines
48 KiB
Dart

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<MsgItem> {
@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<InlineSpan> 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<InlineSpan> 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<InlineSpan> 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<InlineSpan> 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> 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<InlineSpan> 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<void>(
future: Future.delayed(
Duration(milliseconds: 2000),
),
// 传入Future
builder: (
BuildContext context,
AsyncSnapshot<void> 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<void>(
future: Future.delayed(
Duration(milliseconds: 2000),
),
// 传入Future
builder: (
BuildContext context,
AsyncSnapshot<void> 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<SocialChatUserProfile> 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<String, dynamic> toJson() {
final map = <String, dynamic>{};
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;
}
}