修复消息

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

View File

@ -1550,6 +1550,7 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
'roomId=${request.roomId} ' 'roomId=${request.roomId} '
'elapsedMs=${stopwatch.elapsedMilliseconds}', 'elapsedMs=${stopwatch.elapsedMilliseconds}',
); );
_showLocalCpInviteWaitingAfterGift(request, sentUsers);
if (sentUsers.isNotEmpty) { if (sentUsers.isNotEmpty) {
final giftBatchId = _createGiftBatchId(request); final giftBatchId = _createGiftBatchId(request);
sendGiftMsg( sendGiftMsg(
@ -1598,6 +1599,7 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
'balance=$result ' 'balance=$result '
'elapsedMs=${stopwatch.elapsedMilliseconds}', 'elapsedMs=${stopwatch.elapsedMilliseconds}',
); );
_showLocalCpInviteWaitingAfterGift(request, request.acceptUsers);
if (request.isLuckyGiftRequest) { if (request.isLuckyGiftRequest) {
final giftBatchId = _createGiftBatchId(request); final giftBatchId = _createGiftBatchId(request);
_showLocalLuckyGiftFeedback( _showLocalLuckyGiftFeedback(
@ -1668,6 +1670,61 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
unawaited(profileManager?.refreshLoadedCpProfiles()); 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( Future<List<MicRes>> _giveBackpackGiftToRecipients(
SCChatRoomRepository repository, SCChatRoomRepository repository,
_GiftSendRequest request, _GiftSendRequest request,

View File

@ -1013,6 +1013,128 @@ class RealTimeMessagingManager extends ChangeNotifier {
return faceUrl.isNotEmpty ? faceUrl : conversation.faceUrl; 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 { Future<void> _handleIncomingCpBuildMessage(V2TimMessage? message) async {
final data = _decodeCpSystemMessageData(message); final data = _decodeCpSystemMessageData(message);
if (data == null) { if (data == null) {