修复cp-邀请通知达到了24小时后,在消息页打开超时的关系卡片,卡片的状态未变为超时文案,依然有按钮,导致点击拒绝或同意报state error

This commit is contained in:
zhx 2026-05-25 13:12:49 +08:00
parent bb9b92230b
commit 06b21e0156
2 changed files with 121 additions and 21 deletions

View File

@ -1500,16 +1500,26 @@ class _MessageItem extends StatelessWidget {
} }
_isOpeningCpInviteDialog = true; _isOpeningCpInviteDialog = true;
try { try {
_showCpInviteDialogFromMessage(data, cpInvite, actionState); var latestState = _cpInviteStateForMessage(data);
if (actionState != RoomCpInviteActionState.pending) { if (actionState != RoomCpInviteActionState.pending ||
latestState != _CpInviteMessageState.pending) {
_showCpInviteDialogFromMessage(
data,
cpInvite,
actionState == RoomCpInviteActionState.pending
? _cpInviteActionState(latestState)
: actionState,
);
return; return;
} }
final latestState = await _latestCpInviteStateForMessage(data); latestState = await _latestCpInviteStateForMessage(data);
if (!context.mounted || if (!context.mounted) {
latestState == _CpInviteMessageState.pending ||
!SmartDialog.checkExist(tag: RoomCpInviteDialog.dialogTag)) {
return; return;
} }
if (latestState != _CpInviteMessageState.pending) {
_rememberCpInviteState(data, latestState);
updateCall();
}
_showCpInviteDialogFromMessage( _showCpInviteDialogFromMessage(
data, data,
cpInvite, cpInvite,
@ -1730,6 +1740,10 @@ class _MessageItem extends StatelessWidget {
SCSystemInvitMessageRes? cpInvite, SCSystemInvitMessageRes? cpInvite,
RoomCpInviteActionState actionState, RoomCpInviteActionState actionState,
) { ) {
final effectiveActionState =
actionState == RoomCpInviteActionState.pending
? _cpInviteActionState(_cpInviteStateForMessage(data))
: actionState;
final currentProfile = AccountStorage().getCurrentUser()?.userProfile; final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
final currentName = _cpDisplayName( final currentName = _cpDisplayName(
nickname: currentProfile?.userNickname, nickname: currentProfile?.userNickname,
@ -1868,20 +1882,20 @@ class _MessageItem extends StatelessWidget {
isInviter isInviter
? RoomCpInviteDialogStyle.waiting ? RoomCpInviteDialogStyle.waiting
: RoomCpInviteDialogStyle.incoming, : RoomCpInviteDialogStyle.incoming,
actionState: actionState, actionState: effectiveActionState,
countdownSeconds: _cpInviteSecondsLeft(data), countdownSeconds: _cpInviteSecondsLeft(data),
descriptionText: _cpInviteDescriptionText(relationType), descriptionText: _cpInviteDescriptionText(relationType),
onAccept: onAccept:
!isInviter && !isInviter &&
cpInvite != null && cpInvite != null &&
actionState == RoomCpInviteActionState.pending && effectiveActionState == RoomCpInviteActionState.pending &&
applyId.isNotEmpty applyId.isNotEmpty
? () => _processCpInviteFromMessage(applyId, cpInvite, true, data) ? () => _processCpInviteFromMessage(applyId, cpInvite, true, data)
: null, : null,
onReject: onReject:
!isInviter && !isInviter &&
cpInvite != null && cpInvite != null &&
actionState == RoomCpInviteActionState.pending && effectiveActionState == RoomCpInviteActionState.pending &&
applyId.isNotEmpty applyId.isNotEmpty
? () => ? () =>
_processCpInviteFromMessage(applyId, cpInvite, false, data) _processCpInviteFromMessage(applyId, cpInvite, false, data)
@ -1980,6 +1994,20 @@ class _MessageItem extends StatelessWidget {
: localState; : localState;
} }
void _rememberCpInviteState(
Map<String, dynamic> data,
_CpInviteMessageState state,
) {
if (state == _CpInviteMessageState.pending) {
return;
}
final applyId = _cpApplyIdFromData(data);
if (applyId.isEmpty) {
return;
}
onCpInviteStateChanged?.call(applyId, state);
}
_CpInviteMessageState? _cpInviteStateFromBackendStatus(String? status) { _CpInviteMessageState? _cpInviteStateFromBackendStatus(String? status) {
final text = status?.trim().toUpperCase() ?? ""; final text = status?.trim().toUpperCase() ?? "";
if (text.isEmpty || text == "WAIT" || text == "WAITING") { if (text.isEmpty || text == "WAIT" || text == "WAITING") {
@ -2338,6 +2366,7 @@ class _MessageItem extends StatelessWidget {
data["expiredAt"], data["expiredAt"],
data["timeoutAt"], data["timeoutAt"],
data["endTime"], data["endTime"],
data["dismissEndTime"],
content["expireTime"], content["expireTime"],
content["expiredTime"], content["expiredTime"],
content["expireAt"], content["expireAt"],
@ -2357,8 +2386,9 @@ class _MessageItem extends StatelessWidget {
content["createTime"], content["createTime"],
content["createdAt"], content["createdAt"],
content["sendTime"], content["sendTime"],
message.timestamp,
]) ?? ]) ??
(message.timestamp ?? now); now;
return (startAt + 86400 - now).clamp(0, 86400).toInt(); return (startAt + 86400 - now).clamp(0, 86400).toInt();
} }

View File

@ -72,6 +72,7 @@ class _MessageSystemPageState extends State<MessageSystemPage> {
RtmProvider? rtmProvider; RtmProvider? rtmProvider;
V2TimConversation? currentConversation; V2TimConversation? currentConversation;
List<V2TimMessage> currentConversationMessageList = []; List<V2TimMessage> currentConversationMessageList = [];
final Map<String, _CpInviteMessageState> _localCpInviteStates = {};
BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy; BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
@ -260,6 +261,8 @@ class _MessageSystemPageState extends State<MessageSystemPage> {
: null, : null,
currentConversationMessageList: currentConversationMessageList:
currentConversationMessageList, currentConversationMessageList,
localCpInviteStates: _localCpInviteStates,
onCpInviteStateChanged: _setLocalCpInviteState,
updateCall: () { updateCall: () {
setState(() {}); setState(() {});
}, },
@ -272,6 +275,17 @@ class _MessageSystemPageState extends State<MessageSystemPage> {
), ),
); );
} }
void _setLocalCpInviteState(String applyId, _CpInviteMessageState state) {
final normalizedApplyId = applyId.trim();
if (normalizedApplyId.isEmpty) {
return;
}
_localCpInviteStates[normalizedApplyId] = state;
if (mounted) {
setState(() {});
}
}
} }
class _MessageItem extends StatelessWidget { class _MessageItem extends StatelessWidget {
@ -280,6 +294,9 @@ class _MessageItem extends StatelessWidget {
final V2TimMessage message; final V2TimMessage message;
final V2TimMessage? preMessage; final V2TimMessage? preMessage;
List<V2TimMessage> currentConversationMessageList = []; List<V2TimMessage> currentConversationMessageList = [];
final Map<String, _CpInviteMessageState> localCpInviteStates;
final void Function(String applyId, _CpInviteMessageState state)?
onCpInviteStateChanged;
Function updateCall; Function updateCall;
/// ///
@ -289,6 +306,8 @@ class _MessageItem extends StatelessWidget {
required this.message, required this.message,
this.preMessage, this.preMessage,
required this.currentConversationMessageList, required this.currentConversationMessageList,
this.localCpInviteStates = const {},
this.onCpInviteStateChanged,
required this.updateCall, required this.updateCall,
}); });
@ -554,16 +573,26 @@ class _MessageItem extends StatelessWidget {
} }
_isOpeningCpInviteDialog = true; _isOpeningCpInviteDialog = true;
try { try {
_showCpInviteDialogFromMessage(data, cpInvite, actionState); var latestState = _cpInviteStateForMessage(data);
if (actionState != RoomCpInviteActionState.pending) { if (actionState != RoomCpInviteActionState.pending ||
latestState != _CpInviteMessageState.pending) {
_showCpInviteDialogFromMessage(
data,
cpInvite,
actionState == RoomCpInviteActionState.pending
? _cpInviteActionState(latestState)
: actionState,
);
return; return;
} }
final latestState = await _latestCpInviteStateForMessage(data); latestState = await _latestCpInviteStateForMessage(data);
if (!context.mounted || if (!context.mounted) {
latestState == _CpInviteMessageState.pending ||
!SmartDialog.checkExist(tag: RoomCpInviteDialog.dialogTag)) {
return; return;
} }
if (latestState != _CpInviteMessageState.pending) {
_rememberCpInviteState(data, latestState);
updateCall();
}
_showCpInviteDialogFromMessage( _showCpInviteDialogFromMessage(
data, data,
cpInvite, cpInvite,
@ -727,6 +756,10 @@ class _MessageItem extends StatelessWidget {
SCSystemInvitMessageRes? cpInvite, SCSystemInvitMessageRes? cpInvite,
RoomCpInviteActionState actionState, RoomCpInviteActionState actionState,
) { ) {
final effectiveActionState =
actionState == RoomCpInviteActionState.pending
? _cpInviteActionState(_cpInviteStateForMessage(data))
: actionState;
final currentProfile = AccountStorage().getCurrentUser()?.userProfile; final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
final currentName = _cpDisplayName( final currentName = _cpDisplayName(
nickname: currentProfile?.userNickname, nickname: currentProfile?.userNickname,
@ -822,12 +855,12 @@ class _MessageItem extends StatelessWidget {
isInviter isInviter
? RoomCpInviteDialogStyle.waiting ? RoomCpInviteDialogStyle.waiting
: RoomCpInviteDialogStyle.incoming, : RoomCpInviteDialogStyle.incoming,
actionState: actionState, actionState: effectiveActionState,
countdownSeconds: _cpInviteSecondsLeft(data), countdownSeconds: _cpInviteSecondsLeft(data),
descriptionText: _cpInviteDescriptionText(relationType), descriptionText: _cpInviteDescriptionText(relationType),
onAccept: onAccept:
!isInviter && !isInviter &&
actionState == RoomCpInviteActionState.pending && effectiveActionState == RoomCpInviteActionState.pending &&
applyId.isNotEmpty applyId.isNotEmpty
? () => acceptOpt( ? () => acceptOpt(
applyId, applyId,
@ -838,7 +871,7 @@ class _MessageItem extends StatelessWidget {
: null, : null,
onReject: onReject:
!isInviter && !isInviter &&
actionState == RoomCpInviteActionState.pending && effectiveActionState == RoomCpInviteActionState.pending &&
applyId.isNotEmpty applyId.isNotEmpty
? () => rejectOpt( ? () => rejectOpt(
applyId, applyId,
@ -855,7 +888,7 @@ class _MessageItem extends StatelessWidget {
if (data == null) { if (data == null) {
return null; return null;
} }
final state = _cpInviteStateFromData(data); final state = _cpInviteStateForMessage(data);
if (state == _CpInviteMessageState.pending || !_isCpInvitePayload(data)) { if (state == _CpInviteMessageState.pending || !_isCpInvitePayload(data)) {
return null; return null;
} }
@ -890,6 +923,10 @@ class _MessageItem extends StatelessWidget {
} }
_CpInviteMessageState _cpInviteStateForMessage(Map<String, dynamic> data) { _CpInviteMessageState _cpInviteStateForMessage(Map<String, dynamic> data) {
final localState = _localCpInviteStateForData(data);
if (localState != null) {
return localState;
}
final explicitState = _cpInviteStateFromConversation(data); final explicitState = _cpInviteStateFromConversation(data);
if (explicitState != _CpInviteMessageState.pending) { if (explicitState != _CpInviteMessageState.pending) {
return explicitState; return explicitState;
@ -953,6 +990,10 @@ class _MessageItem extends StatelessWidget {
Map<String, dynamic> currentData, Map<String, dynamic> currentData,
) { ) {
final applyId = _cpApplyIdFromData(currentData); final applyId = _cpApplyIdFromData(currentData);
final localState = _localCpInviteStateForApplyId(applyId);
if (localState != null) {
return localState;
}
final currentState = _cpInviteStateFromData(currentData); final currentState = _cpInviteStateFromData(currentData);
if (currentState != _CpInviteMessageState.pending || applyId.isEmpty) { if (currentState != _CpInviteMessageState.pending || applyId.isEmpty) {
return currentState; return currentState;
@ -974,6 +1015,32 @@ class _MessageItem extends StatelessWidget {
return _CpInviteMessageState.pending; return _CpInviteMessageState.pending;
} }
_CpInviteMessageState? _localCpInviteStateForData(Map<String, dynamic> data) {
return _localCpInviteStateForApplyId(_cpApplyIdFromData(data));
}
_CpInviteMessageState? _localCpInviteStateForApplyId(String applyId) {
final normalizedApplyId = applyId.trim();
if (normalizedApplyId.isEmpty) {
return null;
}
return localCpInviteStates[normalizedApplyId];
}
void _rememberCpInviteState(
Map<String, dynamic> data,
_CpInviteMessageState state,
) {
if (state == _CpInviteMessageState.pending) {
return;
}
final applyId = _cpApplyIdFromData(data);
if (applyId.isEmpty) {
return;
}
onCpInviteStateChanged?.call(applyId, state);
}
_CpInviteMessageState _cpInviteStateFromData(Map<String, dynamic> data) { _CpInviteMessageState _cpInviteStateFromData(Map<String, dynamic> data) {
final content = _cpContentMap(data); final content = _cpContentMap(data);
final values = <String>[ final values = <String>[
@ -1111,12 +1178,14 @@ class _MessageItem extends StatelessWidget {
data["expiredAt"], data["expiredAt"],
data["timeoutAt"], data["timeoutAt"],
data["endTime"], data["endTime"],
data["dismissEndTime"],
content["expireTime"], content["expireTime"],
content["expiredTime"], content["expiredTime"],
content["expireAt"], content["expireAt"],
content["expiredAt"], content["expiredAt"],
content["timeoutAt"], content["timeoutAt"],
content["endTime"], content["endTime"],
content["dismissEndTime"],
]); ]);
if (explicitExpireAt != null) { if (explicitExpireAt != null) {
return (explicitExpireAt - now).clamp(0, 86400).toInt(); return (explicitExpireAt - now).clamp(0, 86400).toInt();
@ -1129,8 +1198,9 @@ class _MessageItem extends StatelessWidget {
content["createTime"], content["createTime"],
content["createdAt"], content["createdAt"],
content["sendTime"], content["sendTime"],
message.timestamp,
]) ?? ]) ??
(message.timestamp ?? now); now;
return (startAt + 86400 - now).clamp(0, 86400).toInt(); return (startAt + 86400 - now).clamp(0, 86400).toInt();
} }