Refactors interaction response handling for flexibility

Simplifies modal response creation by accepting both structured data objects and raw dictionaries, reducing unnecessary type casting and import dependencies.

Improves text input decorator by auto-generating custom IDs from function names when not explicitly provided.

Enhances example code by properly utilizing parsed Guild objects instead of raw data and fixes modal component registration.
This commit is contained in:
Slipstream 2025-06-10 17:33:54 -06:00
parent b20f1fd292
commit 534b5b3980
Signed by: slipstream
GPG Key ID: 13E498CE010AC6FD
4 changed files with 23 additions and 19 deletions

View File

@ -395,17 +395,14 @@ class Interaction:
async def respond_modal(self, modal: "Modal") -> None:
"""|coro| Send a modal in response to this interaction."""
from typing import Any, cast
payload = {
"type": InteractionCallbackType.MODAL.value,
"data": modal.to_dict(),
}
payload = InteractionResponsePayload(
type=InteractionCallbackType.MODAL,
data=modal.to_dict(),
)
await self._client._http.create_interaction_response(
interaction_id=self.id,
interaction_token=self.token,
payload=cast(Any, payload),
payload=payload,
)
async def edit(
@ -489,7 +486,7 @@ class InteractionResponse:
"""Sends a modal response."""
payload = InteractionResponsePayload(
type=InteractionCallbackType.MODAL,
data=InteractionCallbackData(modal.to_dict()),
data=modal.to_dict(),
)
await self._interaction._client._http.create_interaction_response(
self._interaction.id,
@ -506,11 +503,13 @@ class InteractionCallbackData:
self.tts: Optional[bool] = data.get("tts")
self.content: Optional[str] = data.get("content")
self.embeds: Optional[List[Embed]] = (
[Embed(e) for e in data.get("embeds", [])] if data.get("embeds") else None
[Embed(e) for e in data.get("embeds", [])]
if data.get("embeds")
else None
)
self.allowed_mentions: Optional[AllowedMentions] = (
AllowedMentions(data["allowed_mentions"])
if data.get("allowed_mentions")
if "allowed_mentions" in data
else None
)
self.flags: Optional[int] = data.get("flags") # MessageFlags enum could be used
@ -557,15 +556,18 @@ class InteractionResponsePayload:
def __init__(
self,
type: InteractionCallbackType,
data: Optional[InteractionCallbackData] = None,
data: Optional[Union[InteractionCallbackData, Dict[str, Any]]] = None,
):
self.type: InteractionCallbackType = type
self.data: Optional[InteractionCallbackData] = data
self.type = type
self.data = data
def to_dict(self) -> Dict[str, Any]:
payload: Dict[str, Any] = {"type": self.type.value}
if self.data:
payload["data"] = self.data.to_dict()
if isinstance(self.data, dict):
payload["data"] = self.data
else:
payload["data"] = self.data.to_dict()
return payload
def __repr__(self) -> str:

View File

@ -74,7 +74,7 @@ def text_input(
item = TextInput(
label=label,
custom_id=custom_id,
custom_id=custom_id or func.__name__,
style=style,
placeholder=placeholder,
required=required,

View File

@ -28,6 +28,7 @@ if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__fi
try:
import disagreement
from disagreement.models import Guild
from disagreement.ext import commands # Import the new commands extension
except ImportError:
print(
@ -190,9 +191,9 @@ async def on_message(message: disagreement.Message):
@client.on_event(
"GUILD_CREATE"
) # Example of listening to a specific event by its Discord name
async def on_guild_available(guild_data: dict): # Receives raw data for now
# In a real scenario, guild_data would be parsed into a Guild model
print(f"Guild available: {guild_data.get('name')} (ID: {guild_data.get('id')})")
async def on_guild_available(guild: Guild):
# The event now passes a Guild object directly
print(f"Guild available: {guild.name} (ID: {guild.id})")
# --- Main Execution ---

View File

@ -26,6 +26,7 @@ class NameModal(ui.Modal):
def __init__(self):
super().__init__(title="Your Name", custom_id="name_modal")
self.name = ui.TextInput(label="Name", custom_id="name")
self.add_item(self.name)
@slash_command(name="namemodal", description="Shows a modal")