mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-07-23 11:26:51 +00:00
Remove view syncing before editing in views
This prevents a potential race condition when a MESSAGE_UPDATE is received syncing and refreshing the view components causing a desync.
This commit is contained in:
parent
4a3491cc0a
commit
d0097c4281
@ -377,6 +377,9 @@ class InteractionResponse:
|
|||||||
return
|
return
|
||||||
|
|
||||||
parent = self._parent
|
parent = self._parent
|
||||||
|
msg = parent.message
|
||||||
|
state = parent._state
|
||||||
|
message_id = msg.id if msg else None
|
||||||
if parent.type is not InteractionType.component:
|
if parent.type is not InteractionType.component:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -404,6 +407,7 @@ class InteractionResponse:
|
|||||||
payload['attachments'] = [a.to_dict() for a in attachments]
|
payload['attachments'] = [a.to_dict() for a in attachments]
|
||||||
|
|
||||||
if view is not MISSING:
|
if view is not MISSING:
|
||||||
|
state.prevent_view_updates_for(message_id)
|
||||||
if view is None:
|
if view is None:
|
||||||
payload['components'] = []
|
payload['components'] = []
|
||||||
else:
|
else:
|
||||||
@ -419,8 +423,6 @@ class InteractionResponse:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if view is not MISSING and not view.is_finished():
|
if view is not MISSING and not view.is_finished():
|
||||||
msg = self._parent.message
|
state.store_view(view, message_id)
|
||||||
message_id = msg.id if msg else None
|
|
||||||
self._parent._state.store_view(view, message_id)
|
|
||||||
|
|
||||||
self._responded = True
|
self._responded = True
|
||||||
|
@ -1216,6 +1216,7 @@ class Message(Hashable):
|
|||||||
# To check for the view afterwards
|
# To check for the view afterwards
|
||||||
view = None
|
view = None
|
||||||
else:
|
else:
|
||||||
|
self._state.prevent_view_updates_for(self.id)
|
||||||
if view:
|
if view:
|
||||||
fields['components'] = view.to_components()
|
fields['components'] = view.to_components()
|
||||||
else:
|
else:
|
||||||
@ -1687,6 +1688,7 @@ class PartialMessage(Hashable):
|
|||||||
# To check for the view afterwards
|
# To check for the view afterwards
|
||||||
view = None
|
view = None
|
||||||
else:
|
else:
|
||||||
|
self._state.prevent_view_updates_for(self.id)
|
||||||
if view:
|
if view:
|
||||||
fields['components'] = view.to_components()
|
fields['components'] = view.to_components()
|
||||||
else:
|
else:
|
||||||
|
@ -284,6 +284,9 @@ class ConnectionState:
|
|||||||
def store_view(self, view, message_id=None):
|
def store_view(self, view, message_id=None):
|
||||||
self._view_store.add_view(view, message_id)
|
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
|
@property
|
||||||
def guilds(self):
|
def guilds(self):
|
||||||
return list(self._guilds.values())
|
return list(self._guilds.values())
|
||||||
|
@ -409,6 +409,9 @@ class ViewStore:
|
|||||||
def is_message_tracked(self, message_id: int):
|
def is_message_tracked(self, message_id: int):
|
||||||
return message_id in self._synced_message_views
|
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]):
|
def update_from_message(self, message_id: int, components: List[ComponentPayload]):
|
||||||
# pre-req: is_message_tracked == true
|
# pre-req: is_message_tracked == true
|
||||||
view = self._synced_message_views[message_id]
|
view = self._synced_message_views[message_id]
|
||||||
|
@ -1437,8 +1437,11 @@ class Webhook(BaseWebhook):
|
|||||||
if self.token is None:
|
if self.token is None:
|
||||||
raise InvalidArgument('This webhook does not have a token associated with it')
|
raise InvalidArgument('This webhook does not have a token associated with it')
|
||||||
|
|
||||||
if view is not MISSING and isinstance(self._state, _WebhookState):
|
if view is not MISSING:
|
||||||
raise InvalidArgument('This webhook does not have state associated with it')
|
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)
|
previous_mentions: Optional[AllowedMentions] = getattr(self._state, 'allowed_mentions', None)
|
||||||
params = handle_message_parameters(
|
params = handle_message_parameters(
|
||||||
@ -1462,7 +1465,7 @@ class Webhook(BaseWebhook):
|
|||||||
files=params.files,
|
files=params.files,
|
||||||
)
|
)
|
||||||
|
|
||||||
if view:
|
if view and not view.is_finished():
|
||||||
self._state.store_view(view, message_id)
|
self._state.store_view(view, message_id)
|
||||||
|
|
||||||
async def delete_message(self, message_id: int):
|
async def delete_message(self, message_id: int):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user