diff --git a/discord/interactions.py b/discord/interactions.py index 3ff8d84f8..be2743e60 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -377,6 +377,9 @@ class InteractionResponse: return parent = self._parent + msg = parent.message + state = parent._state + message_id = msg.id if msg else None if parent.type is not InteractionType.component: return @@ -404,6 +407,7 @@ class InteractionResponse: payload['attachments'] = [a.to_dict() for a in attachments] if view is not MISSING: + state.prevent_view_updates_for(message_id) if view is None: payload['components'] = [] else: @@ -419,8 +423,6 @@ class InteractionResponse: ) if view is not MISSING and not view.is_finished(): - msg = self._parent.message - message_id = msg.id if msg else None - self._parent._state.store_view(view, message_id) + state.store_view(view, message_id) self._responded = True diff --git a/discord/message.py b/discord/message.py index 2af60bcfe..ca70c71ce 100644 --- a/discord/message.py +++ b/discord/message.py @@ -1216,6 +1216,7 @@ class Message(Hashable): # To check for the view afterwards view = None else: + self._state.prevent_view_updates_for(self.id) if view: fields['components'] = view.to_components() else: @@ -1687,6 +1688,7 @@ class PartialMessage(Hashable): # To check for the view afterwards view = None else: + self._state.prevent_view_updates_for(self.id) if view: fields['components'] = view.to_components() else: diff --git a/discord/state.py b/discord/state.py index 177c195c5..80272cd64 100644 --- a/discord/state.py +++ b/discord/state.py @@ -284,6 +284,9 @@ class ConnectionState: def store_view(self, view, message_id=None): self._view_store.add_view(view, message_id) + def prevent_view_updates_for(self, message_id): + return self._view_store.remove_message_tracking(message_id) + @property def guilds(self): return list(self._guilds.values()) diff --git a/discord/ui/view.py b/discord/ui/view.py index 13016a8e0..4df899ed3 100644 --- a/discord/ui/view.py +++ b/discord/ui/view.py @@ -409,6 +409,9 @@ class ViewStore: def is_message_tracked(self, message_id: int): return message_id in self._synced_message_views + def remove_message_tracking(self, message_id: int) -> Optional[View]: + return self._synced_message_views.pop(message_id, None) + def update_from_message(self, message_id: int, components: List[ComponentPayload]): # pre-req: is_message_tracked == true view = self._synced_message_views[message_id] diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index faea82a38..d73ab0eab 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -1437,8 +1437,11 @@ class Webhook(BaseWebhook): if self.token is None: raise InvalidArgument('This webhook does not have a token associated with it') - if view is not MISSING and isinstance(self._state, _WebhookState): - raise InvalidArgument('This webhook does not have state associated with it') + if view is not MISSING: + if isinstance(self._state, _WebhookState): + raise InvalidArgument('This webhook does not have state associated with it') + + self._state.prevent_view_updates_for(message_id) previous_mentions: Optional[AllowedMentions] = getattr(self._state, 'allowed_mentions', None) params = handle_message_parameters( @@ -1462,7 +1465,7 @@ class Webhook(BaseWebhook): files=params.files, ) - if view: + if view and not view.is_finished(): self._state.store_view(view, message_id) async def delete_message(self, message_id: int):