修复消息

This commit is contained in:
zhx 2026-05-23 20:09:30 +08:00
parent 6eb7cb91df
commit f025c18211
3 changed files with 184 additions and 8 deletions

View File

@ -1226,7 +1226,7 @@ class _MessageItem extends StatelessWidget {
}
final customData = _customDataFromMessage(message);
if (customData != null &&
_isDuplicateCpResultMessageForConversation(customData)) {
_isDuplicateCpInviteMessageForConversation(customData)) {
return const SizedBox.shrink();
}
final cpRelationFormedCard = _cpRelationFormedMessageCard();
@ -2007,8 +2007,8 @@ class _MessageItem extends StatelessWidget {
return _CpInviteMessageState.pending;
}
bool _isDuplicateCpResultMessageForConversation(Map<String, dynamic> data) {
final currentKey = _cpResultMessageDedupKey(data);
bool _isDuplicateCpInviteMessageForConversation(Map<String, dynamic> data) {
final currentKey = _cpInviteMessageDedupKey(data);
if (currentKey.isEmpty) {
return false;
}
@ -2025,7 +2025,7 @@ class _MessageItem extends StatelessWidget {
if (otherData == null) {
continue;
}
if (_cpResultMessageDedupKey(otherData) == currentKey) {
if (_cpInviteMessageDedupKey(otherData) == currentKey) {
return true;
}
}
@ -2046,14 +2046,11 @@ class _MessageItem extends StatelessWidget {
return identical(item, message);
}
String _cpResultMessageDedupKey(Map<String, dynamic> data) {
String _cpInviteMessageDedupKey(Map<String, dynamic> data) {
if (!_isCpInvitePayload(data)) {
return "";
}
final state = _cpInviteStateFromData(data);
if (state == _CpInviteMessageState.pending) {
return "";
}
final applyId = _cpApplyIdFromData(data);
if (applyId.isEmpty) {
return "";

View File

@ -1550,6 +1550,7 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
'roomId=${request.roomId} '
'elapsedMs=${stopwatch.elapsedMilliseconds}',
);
_showLocalCpInviteWaitingAfterGift(request, sentUsers);
if (sentUsers.isNotEmpty) {
final giftBatchId = _createGiftBatchId(request);
sendGiftMsg(
@ -1598,6 +1599,7 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
'balance=$result '
'elapsedMs=${stopwatch.elapsedMilliseconds}',
);
_showLocalCpInviteWaitingAfterGift(request, request.acceptUsers);
if (request.isLuckyGiftRequest) {
final giftBatchId = _createGiftBatchId(request);
_showLocalLuckyGiftFeedback(
@ -1668,6 +1670,61 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
unawaited(profileManager?.refreshLoadedCpProfiles());
}
void _showLocalCpInviteWaitingAfterGift(
_GiftSendRequest request,
List<MicRes> sentUsers,
) {
if (!_isCpGift(request.gift)) {
return;
}
final relationType = request.cpRelationType;
if (relationType == null || relationType.trim().isEmpty) {
_giftFxLog(
'local cp waiting skipped reason=no_relation_type '
'giftId=${request.gift.id} acceptUserIds=${request.acceptUserIds}',
);
return;
}
if (sentUsers.isEmpty) {
_giftFxLog(
'local cp waiting skipped reason=no_sent_users '
'giftId=${request.gift.id} relationType=$relationType',
);
return;
}
final receiverProfile = sentUsers.first.user;
if (receiverProfile == null) {
_giftFxLog(
'local cp waiting skipped reason=no_receiver_profile '
'giftId=${request.gift.id} relationType=$relationType',
);
return;
}
final context = navigatorKey.currentState?.context;
if (context == null) {
_giftFxLog(
'local cp waiting skipped reason=no_context '
'giftId=${request.gift.id} relationType=$relationType',
);
return;
}
_giftFxLog(
'local cp waiting trigger '
'giftId=${request.gift.id} '
'relationType=$relationType '
'receiverId=${receiverProfile.id}',
);
unawaited(
Provider.of<RtmProvider>(
context,
listen: false,
).showLocalCpGiftInviteWaiting(
receiverProfile: receiverProfile,
relationType: relationType,
),
);
}
Future<List<MicRes>> _giveBackpackGiftToRecipients(
SCChatRoomRepository repository,
_GiftSendRequest request,

View File

@ -1013,6 +1013,128 @@ class RealTimeMessagingManager extends ChangeNotifier {
return faceUrl.isNotEmpty ? faceUrl : conversation.faceUrl;
}
Future<void> showLocalCpGiftInviteWaiting({
required SocialChatUserProfile? receiverProfile,
required String? relationType,
}) async {
final normalizedRelationType = scNormalizeCpRelationType(relationType);
final receiver = receiverProfile;
final receiverId = receiver?.id?.trim() ?? "";
if (receiver == null || receiverId.isEmpty) {
_cpInviteLog(
'skip local gift waiting reason=missing_receiver '
'relationType=$normalizedRelationType',
);
return;
}
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
if (currentProfile == null) {
_cpInviteLog(
'skip local gift waiting reason=no_current_user '
'receiverId=$receiverId relationType=$normalizedRelationType',
);
return;
}
final currentIds = _cpInviteProfileIdentityValues(currentProfile);
final receiverIds = _cpInviteProfileIdentityValues(receiver);
if (currentIds.any(receiverIds.contains)) {
_cpInviteLog(
'skip local gift waiting reason=self_recipient '
'receiverId=$receiverId relationType=$normalizedRelationType',
);
return;
}
final applyId = await _latestCpGiftApplyId(
receiverId,
relationType: normalizedRelationType,
);
if (applyId == null || applyId.isEmpty) {
_cpInviteLog(
'skip local gift waiting reason=no_waiting_apply '
'receiverId=$receiverId relationType=$normalizedRelationType',
);
return;
}
if (!await _isCpInviteApplyWaitingForAutoPopup(applyId)) {
return;
}
if (!_shownCpInviteMessageKeys.add(applyId)) {
_cpInviteLog(
'skip duplicated local gift waiting applyId=$applyId '
'receiverId=$receiverId relationType=$normalizedRelationType',
);
return;
}
final context = navigatorKey.currentState?.context;
if (context == null || !context.mounted) {
_cpInviteLog(
'skip local gift waiting reason=no_context '
'applyId=$applyId receiverId=$receiverId',
);
return;
}
final currentName = _cpInviteDisplayName(
nickname: currentProfile.userNickname,
account: currentProfile.account,
fallback: currentProfile.id,
);
final receiverName = _cpInviteDisplayName(
nickname: receiver.userNickname,
account: receiver.account,
fallback: receiverId,
);
_cpInviteLog(
'show local gift waiting applyId=$applyId '
'receiverId=$receiverId relationType=$normalizedRelationType',
);
await RoomCpInviteDialog.show(
context,
inviter: RoomCpInviteDialogUser(
name: currentName,
avatarUrl: currentProfile.userAvatar ?? "",
headdress: currentProfile.getHeaddress()?.sourceUrl ?? "",
headdressCover: currentProfile.getHeaddress()?.cover ?? "",
),
receiver: RoomCpInviteDialogUser(
name: receiverName,
avatarUrl: receiver.userAvatar ?? "",
headdress: receiver.getHeaddress()?.sourceUrl ?? "",
headdressCover: receiver.getHeaddress()?.cover ?? "",
),
style: RoomCpInviteDialogStyle.waiting,
countdownSeconds: 86399,
descriptionText: _cpInviteWaitingDescriptionText(normalizedRelationType),
onClose: () {
_cpInviteLog('close local gift waiting applyId=$applyId');
},
onTimeout: () {
_cpInviteLog('timeout local gift waiting applyId=$applyId');
},
);
}
Future<String?> _latestCpGiftApplyId(
String receiverId, {
required String relationType,
}) async {
try {
return await SCAccountRepository().cpRelationshipApplyId(
receiverId,
relationType: relationType,
);
} catch (error) {
_cpInviteLog(
'query local gift apply failed receiverId=$receiverId '
'relationType=$relationType error=$error',
);
return null;
}
}
Future<void> _handleIncomingCpBuildMessage(V2TimMessage? message) async {
final data = _decodeCpSystemMessageData(message);
if (data == null) {