Source code for lightbulb.components.modals

# -*- coding: utf-8 -*-
#
# api_ref_gen::add_autodoc_option::inherited-members
#
# Copyright (c) 2023-present tandemdude
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import annotations

__all__ = ["Modal", "ModalContext", "TextInput"]

import abc
import asyncio
import typing as t
import uuid

import async_timeout
import hikari
from hikari.api import special_endpoints
from hikari.impl import special_endpoints as special_endpoints_impl

from lightbulb import context
from lightbulb.components import base

if t.TYPE_CHECKING:
    from lightbulb import client as client_

ModalComponentT = t.TypeVar("ModalComponentT", bound=base.BaseComponent[special_endpoints.ModalActionRowBuilder])


[docs] class TextInput(base.BaseComponent[special_endpoints.ModalActionRowBuilder]): """Class representing a text input.""" __slots__ = ("_custom_id", "label", "max_length", "min_length", "placeholder", "required", "style", "value") def __init__( self, custom_id: str, style: hikari.TextInputStyle, label: str, min_length: int, max_length: int, required: bool, value: hikari.UndefinedOr[str], placeholder: hikari.UndefinedOr[str], ) -> None: self._custom_id: str = custom_id self.style: hikari.TextInputStyle = style """The style of the text input.""" self.label: str = label """The label for the text input.""" self.min_length: int = min_length """The minimum length of the inputted text.""" self.max_length: int = max_length """The maximum length of the inputted text.""" self.required: bool = required """Whether the text input is required to be filled.""" self.value: hikari.UndefinedOr[str] = value """The default value of the text input.""" self.placeholder: hikari.UndefinedOr[str] = placeholder """The placeholder value for the text input.""" @property def custom_id(self) -> str: """The custom id of the text input.""" return self._custom_id
[docs] def add_to_row(self, row: special_endpoints.ModalActionRowBuilder) -> special_endpoints.ModalActionRowBuilder: return row.add_text_input( self.custom_id, self.label, style=self.style, placeholder=self.placeholder, value=self.value, required=self.required, min_length=self.min_length, max_length=self.max_length, )
[docs] class ModalContext(context.MessageResponseMixin[hikari.ModalInteraction]): """Class representing the context for a modal interaction.""" __slots__ = ("_interaction", "client", "modal") def __init__(self, client: client_.Client, modal: Modal, interaction: hikari.ModalInteraction) -> None: super().__init__() self.client: client_.Client = client """The client that is handling interactions for this context.""" self.modal: Modal = modal """The modal this context is for.""" self._interaction: hikari.ModalInteraction = interaction @property def interaction(self) -> hikari.ModalInteraction: """The interaction this context is for.""" return self._interaction @property def guild_id(self) -> hikari.Snowflake | None: """The ID of the guild that the interaction was created in. :obj:`None` if the interaction occurred in DM.""" return self.interaction.guild_id @property def channel_id(self) -> hikari.Snowflake: """The ID of the channel that the interaction was created in.""" return self.interaction.channel_id @property def user(self) -> hikari.User: """The user that created the interaction.""" return self.interaction.user @property def member(self) -> hikari.InteractionMember | None: """The member that created the interaction, if it was created in a guild.""" return self.interaction.member
[docs] def value_for(self, input: TextInput) -> str | None: """ Get the submitted value for the given text input component. Args: input: The text input component to get the value for. Returns: The value submitted for the given text input component, or :obj:`None` if no value was submitted. """ for row in self.interaction.components: for component in row: if component.custom_id == input.custom_id: return component.value return None