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