mirror of
https://github.com/bwmarrin/discordgo.git
synced 2025-12-23 15:07:45 -05:00
feat(components)!: implement label component (#1656)
* feat(components): add Label component * feat: update modals example * feat(MessageComponentInteractionData): add resolved property * chore(MessageComponentInteractionDataResolved)!: rename MessageComponentInteractionDataResolved to ComponentInteractionDataResolved
This commit is contained in:
@@ -25,6 +25,7 @@ const (
|
||||
FileComponentType ComponentType = 13
|
||||
SeparatorComponent ComponentType = 14
|
||||
ContainerComponent ComponentType = 17
|
||||
LabelComponent ComponentType = 18
|
||||
)
|
||||
|
||||
// MessageComponent is a base interface for all message components.
|
||||
@@ -71,6 +72,8 @@ func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error {
|
||||
umc.MessageComponent = &Separator{}
|
||||
case ContainerComponent:
|
||||
umc.MessageComponent = &Container{}
|
||||
case LabelComponent:
|
||||
umc.MessageComponent = &Label{}
|
||||
default:
|
||||
return fmt.Errorf("unknown component type: %d", v.Type)
|
||||
}
|
||||
@@ -264,6 +267,9 @@ type SelectMenu struct {
|
||||
|
||||
// Unique identifier for the component; auto populated through increment if not provided.
|
||||
ID int `json:"id,omitempty"`
|
||||
|
||||
// List of values that is only populated when receiving an interaction response; do not fill this manually.
|
||||
Values []string `json:"values,omitempty"`
|
||||
}
|
||||
|
||||
// Type is a method to get the type of a component.
|
||||
@@ -578,6 +584,54 @@ func (c Container) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// Label is a top-level layout component.
|
||||
// Labels wrap modal components with text as a label and optional description.
|
||||
type Label struct {
|
||||
// Unique identifier for the component; auto populated through increment if not provided.
|
||||
ID int `json:"id,omitempty"`
|
||||
Label string `json:"label"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Component MessageComponent `json:"component"`
|
||||
}
|
||||
|
||||
// Type is a method to get the type of a component.
|
||||
func (Label) Type() ComponentType {
|
||||
return LabelComponent
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a method for unmarshaling Label from JSON
|
||||
func (l *Label) UnmarshalJSON(data []byte) error {
|
||||
type label Label
|
||||
|
||||
var v struct {
|
||||
label
|
||||
RawComponent unmarshalableMessageComponent `json:"component"`
|
||||
}
|
||||
|
||||
err := json.Unmarshal(data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*l = Label(v.label)
|
||||
l.Component = v.RawComponent.MessageComponent
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON is a method for marshaling Label to a JSON object.
|
||||
func (l Label) MarshalJSON() ([]byte, error) {
|
||||
type label Label
|
||||
|
||||
return Marshal(struct {
|
||||
label
|
||||
Type ComponentType `json:"type"`
|
||||
}{
|
||||
label: label(l),
|
||||
Type: l.Type(),
|
||||
})
|
||||
}
|
||||
|
||||
// UnfurledMediaItem represents an unfurled media item.
|
||||
type UnfurledMediaItem struct {
|
||||
URL string `json:"url"`
|
||||
|
||||
@@ -48,29 +48,32 @@ var (
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
CustomID: "modals_survey_" + i.Interaction.Member.User.ID,
|
||||
Title: "Modals survey",
|
||||
Flags: discordgo.MessageFlagsIsComponentsV2,
|
||||
Components: []discordgo.MessageComponent{
|
||||
discordgo.ActionsRow{
|
||||
Components: []discordgo.MessageComponent{
|
||||
discordgo.TextInput{
|
||||
CustomID: "opinion",
|
||||
Label: "What is your opinion on them?",
|
||||
Style: discordgo.TextInputShort,
|
||||
Placeholder: "Don't be shy, share your opinion with us",
|
||||
Required: true,
|
||||
MaxLength: 300,
|
||||
MinLength: 10,
|
||||
discordgo.Label{
|
||||
Label: "How would you rate them?",
|
||||
Description: "On a scale from terrible to awesome",
|
||||
Component: discordgo.SelectMenu{
|
||||
MenuType: discordgo.StringSelectMenu,
|
||||
CustomID: "rating",
|
||||
Placeholder: "Your rating...",
|
||||
Options: []discordgo.SelectMenuOption{
|
||||
{Label: "Terrible", Value: "terrible"},
|
||||
{Label: "Bad", Value: "bad"},
|
||||
{Label: "Neutral", Value: "neutral", Default: true},
|
||||
{Label: "Good", Value: "good"},
|
||||
{Label: "Awesome", Value: "awesome"},
|
||||
},
|
||||
},
|
||||
},
|
||||
discordgo.ActionsRow{
|
||||
Components: []discordgo.MessageComponent{
|
||||
discordgo.TextInput{
|
||||
CustomID: "suggestions",
|
||||
Label: "What would you suggest to improve them?",
|
||||
Style: discordgo.TextInputParagraph,
|
||||
Required: false,
|
||||
MaxLength: 2000,
|
||||
},
|
||||
discordgo.Label{
|
||||
Label: "What would you suggest to improve them?",
|
||||
Description: "Please provide as much info as possible!",
|
||||
Component: discordgo.TextInput{
|
||||
CustomID: "suggestions",
|
||||
Style: discordgo.TextInputParagraph,
|
||||
Required: false,
|
||||
MaxLength: 2000,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -113,10 +116,10 @@ func main() {
|
||||
|
||||
userid := strings.Split(data.CustomID, "_")[2]
|
||||
_, err = s.ChannelMessageSend(*ResultsChannel, fmt.Sprintf(
|
||||
"Feedback received. From <@%s>\n\n**Opinion**:\n%s\n\n**Suggestions**:\n%s",
|
||||
"Feedback received. From <@%s>\n\n**Rating**:\n%s\n\n**Suggestions**:\n%s",
|
||||
userid,
|
||||
data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value,
|
||||
data.Components[1].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value,
|
||||
data.Components[0].(*discordgo.Label).Component.(*discordgo.SelectMenu).Values[0],
|
||||
data.Components[1].(*discordgo.Label).Component.(*discordgo.TextInput).Value,
|
||||
))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -381,16 +381,16 @@ func (ApplicationCommandInteractionData) Type() InteractionType {
|
||||
|
||||
// MessageComponentInteractionData contains the data of message component interaction.
|
||||
type MessageComponentInteractionData struct {
|
||||
CustomID string `json:"custom_id"`
|
||||
ComponentType ComponentType `json:"component_type"`
|
||||
Resolved MessageComponentInteractionDataResolved `json:"resolved"`
|
||||
CustomID string `json:"custom_id"`
|
||||
ComponentType ComponentType `json:"component_type"`
|
||||
Resolved ComponentInteractionDataResolved `json:"resolved"`
|
||||
|
||||
// NOTE: Only filled when ComponentType is SelectMenuComponent (3). Otherwise is nil.
|
||||
Values []string `json:"values"`
|
||||
}
|
||||
|
||||
// MessageComponentInteractionDataResolved contains the resolved data of selected option.
|
||||
type MessageComponentInteractionDataResolved struct {
|
||||
// ComponentInteractionDataResolved contains the resolved data of selected option.
|
||||
type ComponentInteractionDataResolved struct {
|
||||
Users map[string]*User `json:"users"`
|
||||
Members map[string]*Member `json:"members"`
|
||||
Roles map[string]*Role `json:"roles"`
|
||||
@@ -404,8 +404,9 @@ func (MessageComponentInteractionData) Type() InteractionType {
|
||||
|
||||
// ModalSubmitInteractionData contains the data of modal submit interaction.
|
||||
type ModalSubmitInteractionData struct {
|
||||
CustomID string `json:"custom_id"`
|
||||
Components []MessageComponent `json:"-"`
|
||||
CustomID string `json:"custom_id"`
|
||||
Components []MessageComponent `json:"-"`
|
||||
Resolved ComponentInteractionDataResolved `json:"resolved"`
|
||||
}
|
||||
|
||||
// Type returns the type of interaction data.
|
||||
|
||||
Reference in New Issue
Block a user