Compare commits

..

No commits in common. "main" and "develop" have entirely different histories.

3 changed files with 187 additions and 194 deletions

View File

@ -276,7 +276,7 @@ class _MessagePageState extends State<SCMessagePage> {
Widget _headMenu(RtmProvider provider) { Widget _headMenu(RtmProvider provider) {
return Container( return Container(
margin: EdgeInsetsDirectional.symmetric( margin: EdgeInsetsDirectional.symmetric(
horizontal: 20.w, horizontal: 25.w,
).copyWith(top: 10.w), ).copyWith(top: 10.w),
child: Column( child: Column(
spacing: 15.w, spacing: 15.w,
@ -351,40 +351,61 @@ class _MessagePageState extends State<SCMessagePage> {
}, },
), ),
SCDebounceWidget( SCDebounceWidget(
child: Row( child: Stack(
children: [ children: [
SizedBox(height: 3.w), Row(
Image.asset( children: [
_strategy.getMessagePageSystemMessageIcon(), SizedBox(height: 3.w),
width: 45.w, Image.asset(
height: 45.w, _strategy.getMessagePageSystemMessageIcon(),
width: 45.w,
height: 45.w,
),
SizedBox(width: 5.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
text(
SCAppLocalizations.of(context)!.system,
textColor: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.bold,
),
SizedBox(height: 3.w),
text(
"[${SCAppLocalizations.of(context)!.newMessage}]",
fontSize: 12.sp,
textColor: Colors.white54,
),
],
),
],
), ),
SizedBox(width: 6.w), PositionedDirectional(
Expanded( bottom: 0,
child: Column( end: 10.w,
crossAxisAlignment: CrossAxisAlignment.start, child: Visibility(
children: [ visible: provider.systemUnReadCount > 0,
text( child: Container(
SCAppLocalizations.of(context)!.system, padding: EdgeInsets.symmetric(horizontal: 6.w),
textColor: Colors.white, alignment: Alignment.center,
fontSize: 14.sp, height: 16.w,
fontWeight: FontWeight.bold, decoration: BoxDecoration(
//gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]),
color: Colors.red,
shape: BoxShape.circle,
//borderRadius: BorderRadius.all(Radius.circular(7.w)),
), ),
SizedBox(height: 3.w), child: Text(
Row( "${provider.systemUnReadCount > 99 ? '99+' : provider.systemUnReadCount}",
children: [ style: TextStyle(
Expanded( fontSize: 10.sp,
child: text( color: Color(0xffffffff),
"[${SCAppLocalizations.of(context)!.newMessage}]", fontWeight: FontWeight.w400,
fontSize: 12.sp, decoration: TextDecoration.none,
textColor: Colors.white54, ),
),
),
SizedBox(width: 5.w),
_unreadBadge(provider.systemUnReadCount),
],
), ),
], ),
), ),
), ),
], ],
@ -402,42 +423,66 @@ class _MessagePageState extends State<SCMessagePage> {
}, },
), ),
SCDebounceWidget( SCDebounceWidget(
child: Row( child: Stack(
children: [ children: [
SizedBox(height: 3.w), Container(
Image.asset( alignment: Alignment.center,
_strategy.getMessagePageNotificationMessageIcon(), child: Row(
width: 45.w,
height: 45.w,
),
SizedBox(width: 6.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
text(
SCAppLocalizations.of(context)!.notifcation,
textColor: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.bold,
),
SizedBox(height: 3.w), SizedBox(height: 3.w),
Row( Image.asset(
_strategy.getMessagePageNotificationMessageIcon(),
width: 45.w,
height: 45.w,
),
SizedBox(width: 5.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( text(
child: text( SCAppLocalizations.of(context)!.notifcation,
"[${SCAppLocalizations.of(context)!.newMessage}]", textColor: Colors.white,
fontSize: 12.sp, fontSize: 14.sp,
textColor: Colors.white54, fontWeight: FontWeight.bold,
), ),
SizedBox(height: 3.w),
text(
"[${SCAppLocalizations.of(context)!.newMessage}]",
fontSize: 12.sp,
textColor: Colors.white54,
), ),
SizedBox(width: 5.w),
_unreadBadge(provider.notifcationUnReadCount),
], ],
), ),
], ],
), ),
), ),
PositionedDirectional(
bottom: 0,
end: 10.w,
child: Visibility(
visible: provider.notifcationUnReadCount > 0,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 6.w),
alignment: Alignment.center,
height: 16.w,
decoration: BoxDecoration(
//gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]),
color: Colors.red,
shape: BoxShape.circle,
//borderRadius: BorderRadius.all(Radius.circular(7.w)),
),
child: Text(
"${provider.notifcationUnReadCount > 99 ? '99+' : provider.notifcationUnReadCount}",
style: TextStyle(
fontSize: 10.sp,
color: Color(0xffffffff),
fontWeight: FontWeight.w400,
decoration: TextDecoration.none,
),
),
),
),
),
], ],
), ),
onTap: () { onTap: () {
@ -453,25 +498,4 @@ class _MessagePageState extends State<SCMessagePage> {
), ),
); );
} }
Widget _unreadBadge(int unreadCount) {
return Visibility(
visible: unreadCount > 0,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 6.w),
alignment: Alignment.center,
height: 16.w,
decoration: BoxDecoration(color: Colors.red, shape: BoxShape.circle),
child: Text(
"${unreadCount > 99 ? '99+' : unreadCount}",
style: TextStyle(
fontSize: 10.sp,
color: Color(0xffffffff),
fontWeight: FontWeight.w400,
decoration: TextDecoration.none,
),
),
),
);
}
} }

View File

@ -569,7 +569,7 @@ class _ConversationItemState extends State<ConversationItem> {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
head(url: _displayAvatar, width: 45.w), head(url: _displayAvatar, width: 55.w),
SizedBox(width: 6.w), SizedBox(width: 6.w),
Expanded( Expanded(
child: Column( child: Column(

View File

@ -157,7 +157,30 @@ class _MsgItemState extends State<MsgItem> {
margin: EdgeInsets.symmetric( margin: EdgeInsets.symmetric(
horizontal: width(10), horizontal: width(10),
).copyWith(bottom: 6.w), ).copyWith(bottom: 6.w),
child: _buildTextMessageItem(context), child: Column(
children: [
_buildUserInfoLine(context),
SizedBox(height: 6.w),
Row(
children: [
Flexible(
// 使Flexible替代Expanded
child: GestureDetector(
child: _buildTextMessageBubble(),
onLongPress: () {
if (!(widget.msg.msg ?? "").startsWith(AtText.flag)) {
Clipboard.setData(
ClipboardData(text: widget.msg.msg ?? ''),
);
SCTts.show("Copied");
}
},
),
),
],
),
],
),
), ),
); );
} else { } else {
@ -189,71 +212,10 @@ class _MsgItemState extends State<MsgItem> {
} }
} }
Widget _buildTextMessageItem(BuildContext context) { Widget _buildTextMessageBubble() {
final userId = widget.msg.user?.id;
_clearStaleUserInfoIfNeeded(userId);
if (userId == null || userId.isEmpty) {
return _buildTextMessageItemWithUser(context, widget.msg.user);
}
final cachedUser = SCRoomUtils.roomUsersMap[userId];
if (cachedUser != null) {
return _buildTextMessageItemWithUser(context, cachedUser);
}
return FutureBuilder<SocialChatUserProfile?>(
future: _loadRoomUserInfoSilently(userId),
builder: (ct, AsyncSnapshot<SocialChatUserProfile?> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
final user = snapshot.data!;
SCRoomUtils.roomUsersMap[user.id ?? ""] = user;
return _buildTextMessageItemWithUser(context, user);
}
return _buildTextMessageItemWithUser(context, widget.msg.user);
},
);
}
Widget _buildTextMessageItemWithUser(
BuildContext context,
SocialChatUserProfile? user,
) {
final badges = _activeWearBadges(user);
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildMessageUserAvatar(context, user),
SizedBox(width: 8.w),
Flexible(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildUserNameAndLevels(user),
_buildLongMedals(userId: user?.id, fallbackBadges: badges),
_buildMedals(userId: user?.id, fallbackBadges: badges),
SizedBox(height: 2.w),
GestureDetector(
child: _buildTextMessageBubble(startMargin: 0),
onLongPress: () {
if (!(widget.msg.msg ?? "").startsWith(AtText.flag)) {
Clipboard.setData(
ClipboardData(text: widget.msg.msg ?? ''),
);
SCTts.show("Copied");
}
},
),
],
),
),
],
);
}
Widget _buildTextMessageBubble({double? startMargin}) {
final chatBubble = widget.msg.user?.getChatBox(); final chatBubble = widget.msg.user?.getChatBox();
final hasChatBubble = _resolveRoomChatBubbleImageUrl(chatBubble).isNotEmpty; final hasChatBubble = _resolveRoomChatBubbleImageUrl(chatBubble).isNotEmpty;
final bubbleStartMargin = startMargin ?? 54.w; final bubbleStartMargin = 54.w;
return LayoutBuilder( return LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
final rowMaxWidth = final rowMaxWidth =
@ -1372,7 +1334,7 @@ class _MsgItemState extends State<MsgItem> {
}) { }) {
final hasUserId = (userId ?? "").trim().isNotEmpty; final hasUserId = (userId ?? "").trim().isNotEmpty;
if (!hasUserId && fallbackBadges.isEmpty) { if (!hasUserId && fallbackBadges.isEmpty) {
return const SizedBox.shrink(); return SizedBox(height: 16.w);
} }
return SizedBox( return SizedBox(
width: double.infinity, width: double.infinity,
@ -1384,7 +1346,7 @@ class _MsgItemState extends State<MsgItem> {
longBadgeWidth: 51.w, longBadgeWidth: 51.w,
spacing: 5.w, spacing: 5.w,
maxBadges: 8, maxBadges: 8,
reserveSpace: false, reserveSpace: true,
), ),
); );
} }
@ -1875,7 +1837,14 @@ class _MsgItemState extends State<MsgItem> {
_buildUserInfoLine(BuildContext context) { _buildUserInfoLine(BuildContext context) {
final userId = widget.msg.user?.id; final userId = widget.msg.user?.id;
_clearStaleUserInfoIfNeeded(userId); if ((widget.msg.needUpDataUserInfo) ?? false) {
SCRoomUtils.roomUsersMap.remove(userId ?? "");
if ((userId ?? "").isNotEmpty) {
_userInfoFutures.remove(userId);
_userInfoFailedAt.remove(userId);
}
widget.msg.needUpDataUserInfo = false;
}
if (userId == null || userId.isEmpty) { if (userId == null || userId.isEmpty) {
return _buildPendingUserInfoLine(context); return _buildPendingUserInfoLine(context);
} }
@ -1896,17 +1865,6 @@ class _MsgItemState extends State<MsgItem> {
: _buildNewUserInfoLine(context, SCRoomUtils.roomUsersMap[userId]!); : _buildNewUserInfoLine(context, SCRoomUtils.roomUsersMap[userId]!);
} }
void _clearStaleUserInfoIfNeeded(String? userId) {
if ((widget.msg.needUpDataUserInfo) ?? false) {
SCRoomUtils.roomUsersMap.remove(userId ?? "");
if ((userId ?? "").isNotEmpty) {
_userInfoFutures.remove(userId);
_userInfoFailedAt.remove(userId);
}
widget.msg.needUpDataUserInfo = false;
}
}
Future<SocialChatUserProfile?> _loadRoomUserInfoSilently(String userId) { Future<SocialChatUserProfile?> _loadRoomUserInfoSilently(String userId) {
final failedAt = _userInfoFailedAt[userId]; final failedAt = _userInfoFailedAt[userId];
if (failedAt != null && if (failedAt != null &&
@ -1930,44 +1888,36 @@ class _MsgItemState extends State<MsgItem> {
}); });
} }
Widget _buildMessageUserAvatar(
BuildContext context,
SocialChatUserProfile? user,
) {
return 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(
bottom: 2.w,
right: 2.w,
child: msgRoleTag(widget.msg.role ?? "", width: 14.w),
),
],
),
);
}
Widget _buildPendingUserInfoLine(BuildContext context) { Widget _buildPendingUserInfoLine(BuildContext context) {
return Row( return Row(
children: [ children: [
_buildMessageUserAvatar(context, widget.msg.user), 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: 8.w), SizedBox(width: 8.w),
Expanded( Expanded(
child: ConstrainedBox( child: SizedBox(
constraints: BoxConstraints(minHeight: 48.w), height: 76.w,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_buildUserNameAndLevels(widget.msg.user), _buildUserNameAndLevels(widget.msg.user),
@ -1992,14 +1942,33 @@ class _MsgItemState extends State<MsgItem> {
_buildNewUserInfoLine(BuildContext context, SocialChatUserProfile user) { _buildNewUserInfoLine(BuildContext context, SocialChatUserProfile user) {
return Row( return Row(
children: [ children: [
_buildMessageUserAvatar(context, user), 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: 8.w), SizedBox(width: 8.w),
Expanded( Expanded(
child: ConstrainedBox( child: SizedBox(
constraints: BoxConstraints(minHeight: 48.w), height: 76.w,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_buildUserNameAndLevels(user), _buildUserNameAndLevels(user),