yumi-flutter/lib/ui_kit/widgets/room/room_user_info_card.dart
2026-05-16 04:39:07 +08:00

1109 lines
36 KiB
Dart

import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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:yumi/ui_kit/widgets/badge/sc_user_badge_strip.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/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/models/enum/sc_props_type.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/room_user_card_res.dart'
as room_card;
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 'package:yumi/ui_kit/widgets/id/sc_special_id_badge.dart';
import 'package:yumi/ui_kit/widgets/props/sc_data_card_resource_view.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 {
final String? userId;
const RoomUserInfoCard({super.key, this.userId});
@override
State<RoomUserInfoCard> createState() => _RoomUserInfoCardState();
}
class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
static const String _leaveMicActionIconAsset =
"sc_images/room/sc_icon_room_user_card_leave_mic.png";
static const String _defaultProfileCardBackgroundAsset =
"sc_images/room/sc_bg_room_user_profile_card_default.png";
static const double _profileSheetHeightFactor = 0.4;
static const double _dataCardTranslateDownFactor = 0.4;
static const double _defaultBackgroundImageFactor = 0.68;
SocialChatUserProfileManager? userProvider;
String roomId = "";
SCUserIdentityRes? userIdentity;
@override
void initState() {
super.initState();
userProvider = Provider.of<SocialChatUserProfileManager>(
context,
listen: false,
);
roomId =
Provider.of<RtcProvider>(
context,
listen: false,
).currenRoom?.roomProfile?.roomProfile?.id ??
"";
userProvider?.roomUserCard(roomId, widget.userId ?? "");
SCAccountRepository().userIdentity(userId: widget.userId).then((v) {
if (!mounted) {
return;
}
userIdentity = v;
setState(() {});
});
}
@override
void dispose() {
super.dispose();
userProvider?.userCardInfo = null;
}
@override
Widget build(BuildContext context) {
final sheetHeight =
MediaQuery.of(context).size.height * _profileSheetHeightFactor;
return Consumer<SocialChatUserProfileManager>(
builder: (context, ref, child) {
final currentUserId =
AccountStorage().getCurrentUser()?.userProfile?.id;
final isSelf = widget.userId == currentUserId;
final rtcProvider = Provider.of<RtcProvider>(context, listen: false);
final currentMicIndex =
isSelf && currentUserId != null
? rtcProvider.userOnMaiInIndex(currentUserId)
: -1;
final canLeaveMic = currentMicIndex > -1;
if (ref.userCardInfo == null) {
return _buildLoadingSheet(sheetHeight);
}
return _buildProfileSheet(
context: context,
ref: ref,
rtcProvider: rtcProvider,
sheetHeight: sheetHeight,
isSelf: isSelf,
currentMicIndex: currentMicIndex,
canLeaveMic: canLeaveMic,
currentUserId: currentUserId,
);
},
);
}
Widget _buildLoadingSheet(double sheetHeight) {
return SizedBox(
width: double.infinity,
height: sheetHeight,
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)),
child: Stack(
children: [
Positioned.fill(child: _buildDefaultSheetBackground()),
Center(
child: Container(
width: 55.w,
height: 55.w,
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(8.w),
),
child: CupertinoActivityIndicator(color: Colors.white24),
),
),
],
),
),
);
}
Widget _buildProfileSheet({
required BuildContext context,
required SocialChatUserProfileManager ref,
required RtcProvider rtcProvider,
required double sheetHeight,
required bool isSelf,
required num currentMicIndex,
required bool canLeaveMic,
required String? currentUserId,
}) {
final bottomPadding = MediaQuery.of(context).padding.bottom;
final profile = ref.userCardInfo?.userProfile;
final dataCard = _activeDataCard(ref.userCardInfo);
final canShowReport = currentUserId != widget.userId;
final canShowSetting =
canShowReport &&
ref.userCardInfo?.roomRole != SCRoomRolesType.HOMEOWNER.name &&
(rtcProvider.isFz() || rtcProvider.isGL());
final profileContent = _buildProfileContentLayer(
context: context,
ref: ref,
rtcProvider: rtcProvider,
profile: profile,
bottomPadding: bottomPadding,
isSelf: isSelf,
canLeaveMic: canLeaveMic,
currentMicIndex: currentMicIndex,
canShowReport: canShowReport,
canShowSetting: canShowSetting,
);
if (dataCard == null) {
return SizedBox(
width: double.infinity,
height: sheetHeight,
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)),
child: Stack(
children: [
Positioned.fill(child: _buildDefaultSheetBackground()),
Positioned.fill(child: profileContent),
],
),
),
);
}
return _buildDataCardFrame(
sheetHeight: sheetHeight,
dataCard: dataCard,
child: profileContent,
);
}
Widget _buildDataCardFrame({
required double sheetHeight,
required PropsResources dataCard,
required Widget child,
}) {
return SizedBox(
width: double.infinity,
height: sheetHeight,
child: Stack(
clipBehavior: Clip.none,
children: [
Positioned.fill(
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)),
child: DecoratedBox(decoration: _sheetDecoration()),
),
),
Positioned(
left: 0,
right: 0,
top: sheetHeight * _dataCardTranslateDownFactor,
height: sheetHeight,
child: IgnorePointer(child: _buildSheetBackground(dataCard)),
),
Positioned.fill(
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)),
child: child,
),
),
],
),
);
}
Widget _buildProfileContentLayer({
required BuildContext context,
required SocialChatUserProfileManager ref,
required RtcProvider rtcProvider,
required SocialChatUserProfile? profile,
required double bottomPadding,
required bool isSelf,
required bool canLeaveMic,
required num currentMicIndex,
required bool canShowReport,
required bool canShowSetting,
}) {
return Stack(
children: [
Positioned.fill(
child: LayoutBuilder(
builder: (context, constraints) {
return Align(
alignment: Alignment.topCenter,
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.topCenter,
child: SizedBox(
width: constraints.maxWidth,
child: Padding(
padding: EdgeInsets.fromLTRB(
18.w,
10.w,
18.w,
bottomPadding > 6.w ? bottomPadding : 6.w,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildProfileHeader(context, profile, ref),
SizedBox(height: 6.w),
_buildBadgeStrip(
profile?.id ?? widget.userId,
ref,
profile,
),
SizedBox(height: 8.w),
_buildActions(
context: context,
ref: ref,
rtcProvider: rtcProvider,
isSelf: isSelf,
canLeaveMic: canLeaveMic,
currentMicIndex: currentMicIndex,
),
],
),
),
),
),
);
},
),
),
if (canShowReport)
Positioned(
top: 14.w,
right: 16.w,
child: _buildHeaderIconButton(
iconAsset: "sc_images/room/sc_icon_user_card_report.png",
onTap: () {
final route =
"${SCMainRoute.report}?type=user&tageId=${widget.userId}";
Navigator.of(context).pop();
SCNavigatorUtils.push(
navigatorKey.currentState?.context ?? context,
route,
replace: false,
);
},
),
),
if (canShowSetting)
Positioned(
top: 14.w,
right: 52.w,
child: _buildHeaderIconButton(
iconAsset: "sc_images/room/sc_icon_room_user_card_setting.png",
onTap: () {
if (userProvider?.userCardInfo == null) {
return;
}
Navigator.of(context).pop();
showBottomInBottomDialog(
navigatorKey.currentState?.context ?? context,
RoomUserCardSetting(
roomId: roomId,
userCardInfo: userProvider?.userCardInfo?.copyWith(),
),
);
},
),
),
],
);
}
BoxDecoration _sheetDecoration() {
return const BoxDecoration(color: Color(0xff061F1E));
}
Widget _buildDefaultSheetBackground() {
return DecoratedBox(
decoration: _sheetDecoration(),
child: Center(
child: FractionallySizedBox(
widthFactor: _defaultBackgroundImageFactor,
heightFactor: _defaultBackgroundImageFactor,
child: Image.asset(
_defaultProfileCardBackgroundAsset,
fit: BoxFit.contain,
),
),
),
);
}
Widget _buildSheetBackground(PropsResources? dataCard) {
if (dataCard == null) {
return _buildDefaultSheetBackground();
}
return SCDataCardResourceView(
resource: dataCard,
fit: BoxFit.cover,
showCoverFallback: false,
allowCoverAsResource: false,
);
}
PropsResources? _activeDataCard(room_card.RoomUserCardRes? cardInfo) {
return _activeDataCardFromUseProps(cardInfo?.userProfile?.useProps) ??
_activeDataCardFromUseProps(cardInfo?.useProps);
}
PropsResources? _activeDataCardFromUseProps(List<UseProps>? useProps) {
final now = DateTime.now().millisecondsSinceEpoch;
for (final item in useProps ?? const <UseProps>[]) {
final resource = item.propsResources;
if (resource?.type != SCPropsType.DATA_CARD.name) {
continue;
}
final expireText = item.expireTime?.trim() ?? "";
final expireTime = int.tryParse(expireText);
if (expireText.isNotEmpty && (expireTime ?? 0) <= now) {
continue;
}
final source = resource?.sourceUrl?.trim() ?? "";
final cover = resource?.cover?.trim() ?? "";
if (source.isNotEmpty || cover.isNotEmpty) {
return resource;
}
}
return null;
}
Widget _buildProfileHeader(
BuildContext context,
SocialChatUserProfile? profile,
SocialChatUserProfileManager ref,
) {
return Column(
children: [
GestureDetector(
onTap: () => _openProfile(context),
child: head(
url: profile?.userAvatar ?? "",
width: 105.w,
border: Border.all(color: Colors.white, width: 3),
headdress: profile?.getHeaddress()?.sourceUrl,
headdressCover: profile?.getHeaddress()?.cover,
),
),
SizedBox(height: 5.w),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
msgRoleTag(
ref.userCardInfo?.roomRole ?? "",
width: 16.w,
height: 16.w,
),
SizedBox(width: 4.w),
socialchatNickNameText(
maxWidth: 116.w,
profile?.userNickname ?? "",
fontSize: 18.sp,
textColor: Colors.white,
fontWeight: FontWeight.bold,
type: "",
needScroll: (profile?.userNickname?.characters.length ?? 0) > 12,
),
SizedBox(width: 3.w),
getVIPBadge(
profile?.vipLevel ?? profile?.getVIP()?.name,
width: 45.w,
height: 25.w,
),
SizedBox(width: 3.w),
getWealthLevel(
profile?.wealthLevel ??
ref.userCardInfo?.userLevel?.wealthLevel ??
0,
width: 42.w,
height: 20.w,
fontSize: 9.sp,
),
SizedBox(width: 2.w),
getUserLevel(
profile?.charmLevel ??
ref.userCardInfo?.userLevel?.charmLevel ??
0,
width: 42.w,
height: 20.w,
fontSize: 9.sp,
),
],
),
SizedBox(height: 2.w),
_buildSpecialIdMetaRow(context, profile),
],
);
}
Widget _buildSpecialIdMetaRow(
BuildContext context,
SocialChatUserProfile? profile,
) {
final flagUrl = _countryFlagUrl(context, profile);
final hasSex = profile?.userSex != null;
return Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
SCSpecialIdBadge(
idText: profile?.getID() ?? "",
showAnimated: profile?.hasSpecialId() ?? false,
assetPath: SCSpecialIdAssets.userId,
animationWidth: 62.w,
animationHeight: 24.w,
showTextBesideAnimated: true,
animatedTextSpacing: 0,
showAnimatedGradientText:
profile?.shouldShowColoredSpecialIdText() ?? false,
animationTextStyle: TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: FontWeight.bold,
),
normalTextStyle: TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: FontWeight.bold,
),
animationFit: BoxFit.contain,
),
if (flagUrl.isNotEmpty) ...[
SizedBox(width: 8.w),
_buildCountryFlag(flagUrl),
],
if (hasSex) ...[SizedBox(width: 7.w), _buildSexIcon(profile)],
],
);
}
String _countryFlagUrl(BuildContext context, SocialChatUserProfile? profile) {
final countryName = profile?.countryName ?? "";
try {
return Provider.of<SCAppGeneralManager>(
context,
listen: false,
).findCountryByName(countryName)?.nationalFlag ??
"";
} catch (_) {
return "";
}
}
Widget _buildCountryFlag(String flagUrl) {
final trimmedUrl = flagUrl.trim();
if (trimmedUrl.isEmpty) {
return const SizedBox.shrink();
}
return ClipRRect(
borderRadius: BorderRadius.circular(2.w),
child: netImage(
url: trimmedUrl,
width: 22.w,
height: 15.w,
fit: BoxFit.cover,
noDefaultImg: true,
),
);
}
Widget _buildSexIcon(SocialChatUserProfile? profile) {
if (profile?.userSex == null) {
return const SizedBox.shrink();
}
return xb(profile?.userSex, height: 15.w, color: null);
}
Widget _buildBadgeStrip(
String? userId,
SocialChatUserProfileManager ref,
SocialChatUserProfile? profile,
) {
return SCUserBadgeStrip(
userId: userId,
fallbackBadges: _roomCardFallbackBadges(ref, profile),
height: 70.w,
badgeHeight: 57.5.w,
longBadgeWidth: 145.w,
spacing: 20.w,
maxBadges: 12,
wrap: false,
reserveSpace: true,
);
}
List<WearBadge> _roomCardFallbackBadges(
SocialChatUserProfileManager ref,
SocialChatUserProfile? profile,
) {
final wearBadges =
profile?.wearBadge
?.where((item) => item.use != false && _hasBadgeUrl(item))
.toList() ??
const <WearBadge>[];
if (wearBadges.isNotEmpty) {
return wearBadges;
}
return ref.userCardInfo?.useBadge
?.map<WearBadge>(_roomUseBadgeToWearBadge)
.where(_hasBadgeUrl)
.toList() ??
const <WearBadge>[];
}
WearBadge _roomUseBadgeToWearBadge(room_card.UseBadge badge) {
return WearBadge(
animationUrl: badge.animationUrl,
badgeKey: badge.badgeKey,
badgeLevel: badge.badgeLevel,
badgeName: badge.badgeName,
expireTime: badge.expireTime?.toInt(),
id: badge.id,
milestone: badge.milestone,
notSelectUrl: badge.notSelectUrl,
selectUrl: badge.selectUrl,
type: badge.type,
userId: badge.userId,
use: true,
);
}
bool _hasBadgeUrl(WearBadge badge) {
return (badge.selectUrl ?? "").trim().isNotEmpty;
}
Widget _buildActions({
required BuildContext context,
required SocialChatUserProfileManager ref,
required RtcProvider rtcProvider,
required bool isSelf,
required bool canLeaveMic,
required num currentMicIndex,
}) {
if (isSelf) {
if (!canLeaveMic) {
return SizedBox(height: 55.w);
}
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 92.w,
child: _buildSheetAction(
iconAsset: _leaveMicActionIconAsset,
label: SCAppLocalizations.of(context)!.leavelTheMic,
onTap: () {
Navigator.of(context).pop();
rtcProvider.xiaMai(currentMicIndex);
},
),
),
],
);
}
return Row(
children: [
Expanded(
child: _buildSheetAction(
iconAsset: "sc_images/room/sc_icon_send_user_message.png",
label: SCAppLocalizations.of(context)!.sayHi2,
onTap: () => _openChat(context),
),
),
Expanded(child: _buildFollowAction(context)),
Expanded(
child: _buildSheetAction(
iconAsset: "sc_images/room/sc_icon_at_tag_user.png",
label: SCAppLocalizations.of(context)!.atTag,
onTap: () => _openAtInput(context, ref),
),
),
Expanded(
child: _buildSheetAction(
iconAsset: "sc_images/room/sc_icon_send_user_gift.png",
label: SCAppLocalizations.of(context)!.send,
onTap: () => _openGift(context, ref),
),
),
],
);
}
Widget _buildSheetAction({
required String iconAsset,
required String label,
required VoidCallback onTap,
}) {
return SCDebounceWidget(
onTap: onTap,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 42.w,
height: 42.w,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.58),
shape: BoxShape.circle,
border: Border.all(
color: const Color(0xff18F2B1).withValues(alpha: 0.18),
),
),
alignment: Alignment.center,
child: Image.asset(iconAsset, width: 28.w, height: 28.w),
),
SizedBox(height: 5.w),
SizedBox(
height: 31.w,
child: text(
label,
maxLines: 2,
textAlign: TextAlign.center,
textColor: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 12.sp,
lineHeight: 1.1,
),
),
],
),
);
}
Widget _buildFollowAction(BuildContext context) {
return SCDebounceWidget(
onTap: () {
final provider = Provider.of<SocialChatUserProfileManager>(
context,
listen: false,
);
provider.followUser(widget.userId ?? "");
},
child: Selector<SocialChatUserProfileManager, bool>(
selector: (context, provider) => provider.userCardInfo?.follow ?? false,
shouldRebuild: (prev, next) => prev != next,
builder: (context, follow, _) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 42.w,
height: 42.w,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.58),
shape: BoxShape.circle,
border: Border.all(
color: const Color(0xff18F2B1).withValues(alpha: 0.18),
),
),
alignment: Alignment.center,
child: Image.asset(
follow
? "sc_images/room/sc_icon_user_un_follow.png"
: "sc_images/room/sc_icon_user_follow.png",
width: 28.w,
height: 28.w,
),
),
SizedBox(height: 5.w),
SizedBox(
height: 31.w,
child: text(
follow
? SCAppLocalizations.of(context)!.followed
: SCAppLocalizations.of(context)!.follow,
maxLines: 2,
textAlign: TextAlign.center,
textColor: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 12.sp,
lineHeight: 1.1,
),
),
],
);
},
),
);
}
Widget _buildHeaderIconButton({
required String iconAsset,
required VoidCallback onTap,
}) {
return SCDebounceWidget(
onTap: onTap,
child: Container(
width: 28.w,
height: 28.w,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.45),
shape: BoxShape.circle,
),
alignment: Alignment.center,
child: Image.asset(
iconAsset,
width: 18.w,
height: 18.w,
color: Colors.black,
),
),
);
}
void _openProfile(BuildContext context) {
final route =
"${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == widget.userId}&tageId=${widget.userId}";
Navigator.of(context).pop();
SCNavigatorUtils.push(navigatorKey.currentState?.context ?? context, route);
}
Future<void> _openChat(BuildContext context) async {
final rtmProvider = Provider.of<RtmProvider>(context, listen: false);
Navigator.of(context).pop();
var conversation = V2TimConversation(
type: ConversationType.V2TIM_C2C,
userID: widget.userId,
conversationID: '',
);
final didStart = await rtmProvider.startConversation(conversation);
if (!didStart || !mounted) return;
var json = jsonEncode(conversation.toJson());
SCNavigatorUtils.push(
navigatorKey.currentState!.context,
"${SCChatRouter.chat}?conversation=${Uri.encodeComponent(json)}",
);
}
Future<void> _openAtInput(
BuildContext context,
SocialChatUserProfileManager ref,
) async {
if (!SCRoomUtils.touristCanMsg(context)) {
return;
}
final nickname = ref.userCardInfo?.userProfile?.userNickname ?? "";
if (nickname.isEmpty) {
return;
}
Navigator.of(context).pop();
Navigator.push(
navigatorKey.currentState?.context ?? context,
PopRoute(
child: RoomMsgInput(
atTextContent: "<user id=\"${widget.userId}\">$nickname</user>",
),
),
);
}
void _openGift(BuildContext context, SocialChatUserProfileManager ref) {
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);
},
);
}
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";
}
}