(interactions): Basic support for modals.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
from . import enums
|
||||
from .interactions import _component_interaction_factory, Interaction, ComponentInteraction
|
||||
from .interactions import _component_interaction_factory, Interaction, ComponentInteraction, ModalResponse
|
||||
from .components import *
|
||||
from .modals import *
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
import asyncio
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from .enums import ButtonStyle, InteractionType
|
||||
|
||||
|
||||
class MessageComponent:
|
||||
_type = None
|
||||
interaction_type = InteractionType.MESSAGE_COMPONENT
|
||||
|
||||
def __init_(self, *args, **kwargs):
|
||||
self.message = None
|
||||
|
||||
def to_dict(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def to_json(self):
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
|
||||
class ActionRow(MessageComponent):
|
||||
_type = 1
|
||||
@@ -26,13 +34,15 @@ class ActionRow(MessageComponent):
|
||||
|
||||
|
||||
class AwaitableComponent:
|
||||
interaction_type: InteractionType = None
|
||||
|
||||
async def wait_for(self, timeout=None, check=None):
|
||||
from meta import client
|
||||
|
||||
def _check(interaction):
|
||||
valid = True
|
||||
print(interaction.custom_id)
|
||||
valid = valid and interaction.interaction_type == InteractionType.MESSAGE_COMPONENT
|
||||
valid = valid and interaction.interaction_type == self.interaction_type
|
||||
valid = valid and interaction.custom_id == self.custom_id
|
||||
valid = valid and (check is None or check(interaction))
|
||||
return valid
|
||||
|
||||
@@ -24,5 +24,17 @@ class ButtonStyle(IntEnum):
|
||||
LINK = 5
|
||||
|
||||
|
||||
class TextInputStyle(IntEnum):
|
||||
SHORT = 1
|
||||
PARAGRAPH = 2
|
||||
|
||||
|
||||
class InteractionCallback(IntEnum):
|
||||
PONG = 1
|
||||
CHANNEL_MESSAGE_WITH_SOURCE = 4
|
||||
DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE = 5
|
||||
DEFERRED_UPDATE_MESSAGE = 6
|
||||
UPDATE_MESSAGE = 7
|
||||
APPLICATION_COMMAND_AUTOCOMPLETE_RESULT = 8
|
||||
MODAL = 9
|
||||
|
||||
|
||||
@@ -9,11 +9,23 @@ class Interaction:
|
||||
'_state'
|
||||
)
|
||||
|
||||
async def callback_deferred(self):
|
||||
return await self._state.http.interaction_callback(self.id, self.token, InteractionCallback.DEFERRED_UPDATE_MESSAGE)
|
||||
async def response_deferred(self):
|
||||
return await self._state.http.interaction_callback(
|
||||
self.id,
|
||||
self.token,
|
||||
InteractionCallback.DEFERRED_UPDATE_MESSAGE
|
||||
)
|
||||
|
||||
async def response_modal(self, modal):
|
||||
return await self._state.http.interaction_callback(
|
||||
self.id,
|
||||
self.token,
|
||||
InteractionCallback.MODAL,
|
||||
modal.to_dict()
|
||||
)
|
||||
|
||||
def ack(self):
|
||||
asyncio.create_task(self.callback_deferred())
|
||||
asyncio.create_task(self.response_deferred())
|
||||
|
||||
|
||||
class ComponentInteraction(Interaction):
|
||||
@@ -51,6 +63,44 @@ class Selection(ComponentInteraction):
|
||||
self.values = data['data']['values']
|
||||
|
||||
|
||||
class ModalResponse(Interaction):
|
||||
__slots__ = (
|
||||
'message',
|
||||
'user',
|
||||
'_state'
|
||||
'id',
|
||||
'token',
|
||||
'application_id',
|
||||
'custom_id',
|
||||
'values'
|
||||
)
|
||||
|
||||
interaction_type = InteractionType.MODAL_SUBMIT
|
||||
|
||||
def __init__(self, message, user, data, state):
|
||||
self.message = message
|
||||
self.user = user
|
||||
|
||||
self._state = state
|
||||
|
||||
self._from_data(data)
|
||||
|
||||
def _from_data(self, data):
|
||||
self.id = data['id']
|
||||
self.token = data['token']
|
||||
self.application_id = data['application_id']
|
||||
|
||||
component_data = data['data']
|
||||
|
||||
self.custom_id = component_data.get('custom_id', None)
|
||||
|
||||
values = {}
|
||||
for row in component_data['components']:
|
||||
for component in row['components']:
|
||||
values[component['custom_id']] = component['value']
|
||||
self.values = values
|
||||
|
||||
|
||||
def _component_interaction_factory(data):
|
||||
component_type = data['data']['component_type']
|
||||
|
||||
|
||||
54
bot/meta/interactions/modals.py
Normal file
54
bot/meta/interactions/modals.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import uuid
|
||||
|
||||
from .enums import TextInputStyle, InteractionType
|
||||
from .components import AwaitableComponent
|
||||
|
||||
|
||||
class Modal(AwaitableComponent):
|
||||
interaction_type = InteractionType.MODAL_SUBMIT
|
||||
|
||||
def __init__(self, title, *components, custom_id=None):
|
||||
self.custom_id = custom_id or str(uuid.uuid4())
|
||||
|
||||
self.title = title
|
||||
self.components = components
|
||||
|
||||
def to_dict(self):
|
||||
data = {
|
||||
'title': self.title,
|
||||
'custom_id': self.custom_id,
|
||||
'components': [comp.to_dict() for comp in self.components]
|
||||
}
|
||||
return data
|
||||
|
||||
|
||||
class TextInput:
|
||||
_type = 4
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label, placeholder=None, value=None, required=False,
|
||||
style=TextInputStyle.SHORT, min_length=None, max_length=None,
|
||||
custom_id=None
|
||||
):
|
||||
self.custom_id = custom_id or str(uuid.uuid4())
|
||||
|
||||
self.label = label
|
||||
self.placeholder = placeholder
|
||||
self.value = value
|
||||
self.required = required
|
||||
self.style = style
|
||||
self.min_length = min_length
|
||||
self.max_length = max_length
|
||||
|
||||
def to_dict(self):
|
||||
data = {
|
||||
'type': self._type,
|
||||
'custom_id': self.custom_id,
|
||||
'style': int(self.style),
|
||||
'label': self.label,
|
||||
}
|
||||
for key in ('min_length', 'max_length', 'required', 'value', 'placeholder'):
|
||||
if (value := getattr(self, key)) is not None:
|
||||
data[key] = value
|
||||
return data
|
||||
Reference in New Issue
Block a user