mirror of
https://github.com/diamondburned/arikawa.git
synced 2024-11-17 12:23:08 +00:00
discord: Modal interaction support (#310)
* Support modal interactions along with the TextInput component * Replace ModalInteraction with Modal to prevent confusion * Fix the required field from not being used correctly * PR Fixes
This commit is contained in:
parent
7727d140a0
commit
d6bc738e50
|
@ -25,6 +25,7 @@ const (
|
|||
DeferredMessageUpdate
|
||||
UpdateMessage
|
||||
AutocompleteResult
|
||||
ModalResponse
|
||||
)
|
||||
|
||||
// InteractionResponseFlags implements flags for an
|
||||
|
@ -78,6 +79,11 @@ type InteractionResponseData struct {
|
|||
//
|
||||
// During all other events, this should not be provided.
|
||||
Choices *[]AutocompleteChoice `json:"choices"`
|
||||
|
||||
// CustomID used with the modal
|
||||
CustomID option.NullableString `json:"custom_id,omitempty"`
|
||||
// Title is the heading of the modal window
|
||||
Title option.NullableString `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
// NeedsMultipart returns true if the InteractionResponseData has files.
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/diamondburned/arikawa/v3/utils/json"
|
||||
"github.com/diamondburned/arikawa/v3/utils/json/option"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -15,6 +16,7 @@ const (
|
|||
ActionRowComponentType
|
||||
ButtonComponentType
|
||||
SelectComponentType
|
||||
TextInputComponentType
|
||||
)
|
||||
|
||||
// String formats Type's name as a string.
|
||||
|
@ -26,6 +28,8 @@ func (t ComponentType) String() string {
|
|||
return "Button"
|
||||
case SelectComponentType:
|
||||
return "Select"
|
||||
case TextInputComponentType:
|
||||
return "TextInput"
|
||||
default:
|
||||
return fmt.Sprintf("ComponentType(%d)", int(t))
|
||||
}
|
||||
|
@ -126,6 +130,8 @@ func ParseComponent(b []byte) (Component, error) {
|
|||
c = &ButtonComponent{}
|
||||
case SelectComponentType:
|
||||
c = &SelectComponent{}
|
||||
case TextInputComponentType:
|
||||
c = &TextInputComponent{}
|
||||
default:
|
||||
c = &UnknownComponent{typ: t.Type}
|
||||
}
|
||||
|
@ -448,6 +454,69 @@ func (s *SelectComponent) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal(msg)
|
||||
}
|
||||
|
||||
type TextInputStyle uint8
|
||||
|
||||
const (
|
||||
_ TextInputStyle = iota
|
||||
TextInputShortStyle
|
||||
TextInputParagraphStyle
|
||||
)
|
||||
|
||||
// TextInputComponents provide a user-facing text box to be filled out. They can only
|
||||
// be used with modals.
|
||||
type TextInputComponent struct {
|
||||
// CustomID provides a developer-defined ID for the input (max 100 chars)
|
||||
CustomID ComponentID `json:"custom_id"`
|
||||
// Style determines if the component should use the short or paragraph style
|
||||
Style TextInputStyle `json:"style"`
|
||||
// Label is the title of this component, describing its use
|
||||
Label string `json:"label"`
|
||||
// ValueLimits is the minimum and maximum length for the input
|
||||
ValueLimits [2]int `json:"-"`
|
||||
// Required dictates whether or not the user must fill out the component
|
||||
Required bool `json:"required"`
|
||||
// Value is the pre-filled value of this component (max 4000 chars)
|
||||
Value option.NullableString `json:"value,omitempty"`
|
||||
// Placeholder is the text that appears when the input is empty (max 100 chars)
|
||||
Placeholder option.NullableString `json:"placeholder,omitempty"`
|
||||
}
|
||||
|
||||
func (s *TextInputComponent) _cmp() {}
|
||||
func (s *TextInputComponent) _icp() {}
|
||||
|
||||
func (i *TextInputComponent) ID() ComponentID {
|
||||
return i.CustomID
|
||||
}
|
||||
|
||||
func (i *TextInputComponent) Type() ComponentType {
|
||||
return TextInputComponentType
|
||||
}
|
||||
|
||||
func (i *TextInputComponent) MarshalJSON() ([]byte, error) {
|
||||
type text TextInputComponent
|
||||
|
||||
type Msg struct {
|
||||
Type ComponentType `json:"type"`
|
||||
*text
|
||||
MinValues *int `json:"max_values,omitempty"`
|
||||
MaxValues *int `json:"min_values,omitempty"`
|
||||
}
|
||||
|
||||
m := Msg{
|
||||
Type: i.Type(),
|
||||
text: (*text)(i),
|
||||
}
|
||||
|
||||
if i.ValueLimits != [2]int{0, 0} {
|
||||
m.MinValues = new(int)
|
||||
m.MaxValues = new(int)
|
||||
|
||||
*m.MinValues = i.ValueLimits[0]
|
||||
*m.MaxValues = i.ValueLimits[1]
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// Unknown is reserved for components with unknown or not yet implemented
|
||||
// components types. It can also be used in place of a ComponentInteraction.
|
||||
type UnknownComponent struct {
|
||||
|
|
|
@ -86,6 +86,8 @@ func (e *InteractionEvent) UnmarshalJSON(b []byte) error {
|
|||
return nil
|
||||
case AutocompleteInteractionType:
|
||||
e.Data = &AutocompleteInteraction{}
|
||||
case ModalInteractionType:
|
||||
e.Data = &ModalInteraction{}
|
||||
default:
|
||||
e.Data = &UnknownInteractionData{
|
||||
Raw: target.Data,
|
||||
|
@ -131,6 +133,7 @@ const (
|
|||
CommandInteractionType
|
||||
ComponentInteractionType
|
||||
AutocompleteInteractionType
|
||||
ModalInteractionType
|
||||
)
|
||||
|
||||
// InteractionData holds the respose data of an interaction, or more
|
||||
|
@ -365,6 +368,19 @@ func (o CommandInteractionOption) FloatValue() (float64, error) {
|
|||
return f, err
|
||||
}
|
||||
|
||||
// ModalInteraction is the submitted modal form
|
||||
type ModalInteraction struct {
|
||||
CustomID ComponentID `json:"custom_id"`
|
||||
Components ContainerComponents `json:"components"`
|
||||
}
|
||||
|
||||
// InteractionType implements InteractionData.
|
||||
func (m *ModalInteraction) InteractionType() InteractionDataType {
|
||||
return ModalInteractionType
|
||||
}
|
||||
|
||||
func (m *ModalInteraction) data() {}
|
||||
|
||||
// UnknownInteractionData describes an Interaction response with an unknown
|
||||
// type.
|
||||
type UnknownInteractionData struct {
|
||||
|
|
Loading…
Reference in a new issue