From e795d341e7315483fd30053ba96f69a8c72d4343 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Sat, 31 Jul 2021 23:08:05 -0400 Subject: [PATCH] Change View dispatch mechanism to be keyed by message_id as well If different persistent view instances are used within different message_ids their callbacks will get called without differentiating between them, leading to potential issues such as 404 errors. This change makes it so N views with custom IDs bound to N message_ids will no longer conflict with one another. --- discord/ui/view.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/discord/ui/view.py b/discord/ui/view.py index 462b6f83d..a190b5075 100644 --- a/discord/ui/view.py +++ b/discord/ui/view.py @@ -456,8 +456,8 @@ class View: class ViewStore: def __init__(self, state: ConnectionState): - # (component_type, custom_id): (View, Item) - self._views: Dict[Tuple[int, str], Tuple[View, Item]] = {} + # (component_type, message_id, custom_id): (View, Item) + self._views: Dict[Tuple[int, Optional[int], str], Tuple[View, Item]] = {} # message_id: View self._synced_message_views: Dict[int, View] = {} self._state: ConnectionState = state @@ -474,7 +474,7 @@ class ViewStore: return list(views.values()) def __verify_integrity(self): - to_remove: List[Tuple[int, str]] = [] + to_remove: List[Tuple[int, Optional[int], str]] = [] now = time.monotonic() for (k, (view, _)) in self._views.items(): if view.is_finished(): @@ -489,7 +489,7 @@ class ViewStore: view._start_listening_from_store(self) for item in view.children: if item.is_dispatchable(): - self._views[(item.type.value, item.custom_id)] = (view, item) # type: ignore + self._views[(item.type.value, message_id, item.custom_id)] = (view, item) # type: ignore if message_id is not None: self._synced_message_views[message_id] = view @@ -506,7 +506,8 @@ class ViewStore: def dispatch(self, component_type: int, custom_id: str, interaction: Interaction): self.__verify_integrity() - key = (component_type, custom_id) + message_id: Optional[int] = interaction.message and interaction.message.id + key = (component_type, message_id, custom_id) value = self._views.get(key) if value is None: return