Skip to content

Commit

Permalink
new select menu types (#205)
Browse files Browse the repository at this point in the history
* inital draft for new select menu types

* add missing methods to mesasge & component interaction

* fix wrong json tags

* readd missing SelectMenu with methods
  • Loading branch information
topi314 authored Nov 29, 2022
1 parent 376d97e commit 5e33848
Show file tree
Hide file tree
Showing 6 changed files with 1,023 additions and 213 deletions.
15 changes: 1 addition & 14 deletions _examples/test/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,7 @@ var commands = []discord.ApplicationCommandCreate{
},
discord.SlashCommandCreate{
Name: "test2",
Description: "test2",
Options: []discord.ApplicationCommandOption{
discord.ApplicationCommandOptionInt{
Name: "number",
Description: "some number",
Required: true,
},
discord.ApplicationCommandOptionInt{
Name: "message",
Description: "What to say",
Required: true,
Autocomplete: true,
},
},
Description: "test",
},
discord.SlashCommandCreate{
Name: "say",
Expand Down
25 changes: 24 additions & 1 deletion _examples/test/listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func componentListener(event *events.ComponentInteractionCreate) {
)
}

case discord.SelectMenuInteractionData:
case discord.StringSelectMenuInteractionData:
switch data.CustomID() {
case "test3":
if err := event.DeferUpdateMessage(); err != nil {
Expand All @@ -95,6 +95,19 @@ func componentListener(event *events.ComponentInteractionCreate) {
Build(),
)
}

case discord.MentionableSelectMenuInteractionData:
switch data.CustomID() {
case "test4":
if err := event.DeferUpdateMessage(); err != nil {
log.Errorf("error sending interaction response: %s", err)
}
_, _ = event.Client().Rest().CreateFollowupMessage(event.ApplicationID(), event.Token(), discord.NewMessageCreateBuilder().
SetEphemeral(true).
SetContentf("selected mentionable options: %s", data.Values).
Build(),
)
}
}
}

Expand Down Expand Up @@ -129,6 +142,16 @@ func applicationCommandListener(event *events.ApplicationCommandInteractionCreat
).
Build(),
)

case "test2":
selectMenu := discord.NewMentionableSelectMenu("test4", "select users/members/roles")
selectMenu.MaxValues = 3

_ = event.CreateMessage(discord.NewMessageCreateBuilder().
SetContent("test2").
AddActionRow(selectMenu).
Build(),
)
}
}

Expand Down
195 changes: 27 additions & 168 deletions discord/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ type ComponentType int
const (
ComponentTypeActionRow = iota + 1
ComponentTypeButton
ComponentTypeSelectMenu
ComponentTypeStringSelectMenu
ComponentTypeTextInput
ComponentTypeUserSelectMenu
ComponentTypeRoleSelectMenu
ComponentTypeMentionableSelectMenu
ComponentTypeChannelSelectMenu
)

type Component interface {
Expand Down Expand Up @@ -65,8 +69,8 @@ func (u *UnmarshalComponent) UnmarshalJSON(data []byte) error {
err = json.Unmarshal(data, &v)
component = v

case ComponentTypeSelectMenu:
v := SelectMenuComponent{}
case ComponentTypeStringSelectMenu:
v := StringSelectMenuComponent{}
err = json.Unmarshal(data, &v)
component = v

Expand All @@ -75,6 +79,26 @@ func (u *UnmarshalComponent) UnmarshalJSON(data []byte) error {
err = json.Unmarshal(data, &v)
component = v

case ComponentTypeUserSelectMenu:
v := UserSelectMenuComponent{}
err = json.Unmarshal(data, &v)
component = v

case ComponentTypeRoleSelectMenu:
v := RoleSelectMenuComponent{}
err = json.Unmarshal(data, &v)
component = v

case ComponentTypeMentionableSelectMenu:
v := MentionableSelectMenuComponent{}
err = json.Unmarshal(data, &v)
component = v

case ComponentTypeChannelSelectMenu:
v := ChannelSelectMenuComponent{}
err = json.Unmarshal(data, &v)
component = v

default:
err = fmt.Errorf("unknown component with type %d received", cType.Type)
}
Expand Down Expand Up @@ -336,171 +360,6 @@ func (c ButtonComponent) WithDisabled(disabled bool) ButtonComponent {
return c
}

// NewSelectMenu builds a new SelectMenuComponent from the provided values
func NewSelectMenu(customID string, placeholder string, options ...SelectMenuOption) SelectMenuComponent {
return SelectMenuComponent{
CustomID: customID,
Placeholder: placeholder,
Options: options,
}
}

var (
_ Component = (*SelectMenuComponent)(nil)
_ InteractiveComponent = (*SelectMenuComponent)(nil)
)

type SelectMenuComponent struct {
CustomID string `json:"custom_id"`
Placeholder string `json:"placeholder,omitempty"`
MinValues *int `json:"min_values,omitempty"`
MaxValues int `json:"max_values,omitempty"`
Disabled bool `json:"disabled,omitempty"`
Options []SelectMenuOption `json:"options,omitempty"`
}

func (c SelectMenuComponent) MarshalJSON() ([]byte, error) {
type selectMenuComponent SelectMenuComponent
return json.Marshal(struct {
Type ComponentType `json:"type"`
selectMenuComponent
}{
Type: c.Type(),
selectMenuComponent: selectMenuComponent(c),
})
}

func (SelectMenuComponent) Type() ComponentType {
return ComponentTypeSelectMenu
}

func (c SelectMenuComponent) ID() string {
return c.CustomID
}

func (SelectMenuComponent) component() {}
func (SelectMenuComponent) interactiveComponent() {}

// WithCustomID returns a new SelectMenuComponent with the provided customID
func (c SelectMenuComponent) WithCustomID(customID string) SelectMenuComponent {
c.CustomID = customID
return c
}

// WithPlaceholder returns a new SelectMenuComponent with the provided placeholder
func (c SelectMenuComponent) WithPlaceholder(placeholder string) SelectMenuComponent {
c.Placeholder = placeholder
return c
}

// WithMinValues returns a new SelectMenuComponent with the provided minValue
func (c SelectMenuComponent) WithMinValues(minValue int) SelectMenuComponent {
c.MinValues = &minValue
return c
}

// WithMaxValues returns a new SelectMenuComponent with the provided maxValue
func (c SelectMenuComponent) WithMaxValues(maxValue int) SelectMenuComponent {
c.MaxValues = maxValue
return c
}

// AsEnabled returns a new SelectMenuComponent but enabled
func (c SelectMenuComponent) AsEnabled() SelectMenuComponent {
c.Disabled = false
return c
}

// AsDisabled returns a new SelectMenuComponent but disabled
func (c SelectMenuComponent) AsDisabled() SelectMenuComponent {
c.Disabled = true
return c
}

// WithDisabled returns a new SelectMenuComponent with the provided disabled
func (c SelectMenuComponent) WithDisabled(disabled bool) SelectMenuComponent {
c.Disabled = disabled
return c
}

// SetOptions returns a new SelectMenuComponent with the provided SelectMenuOption(s)
func (c SelectMenuComponent) SetOptions(options ...SelectMenuOption) SelectMenuComponent {
c.Options = options
return c
}

// SetOption returns a new SelectMenuComponent with the SelectMenuOption which has the value replaced
func (c SelectMenuComponent) SetOption(value string, option SelectMenuOption) SelectMenuComponent {
for i, o := range c.Options {
if o.Value == value {
c.Options[i] = option
break
}
}
return c
}

// AddOptions returns a new SelectMenuComponent with the provided SelectMenuOption(s) added
func (c SelectMenuComponent) AddOptions(options ...SelectMenuOption) SelectMenuComponent {
c.Options = append(c.Options, options...)
return c
}

// RemoveOption returns a new SelectMenuComponent with the provided SelectMenuOption at the index removed
func (c SelectMenuComponent) RemoveOption(index int) SelectMenuComponent {
if len(c.Options) > index {
c.Options = append(c.Options[:index], c.Options[index+1:]...)
}
return c
}

// NewSelectMenuOption builds a new SelectMenuOption
func NewSelectMenuOption(label string, value string) SelectMenuOption {
return SelectMenuOption{
Label: label,
Value: value,
}
}

// SelectMenuOption represents an option in a SelectMenuComponent
type SelectMenuOption struct {
Label string `json:"label"`
Value string `json:"value"`
Description string `json:"description,omitempty"`
Emoji *ComponentEmoji `json:"emoji,omitempty"`
Default bool `json:"default,omitempty"`
}

// WithLabel returns a new SelectMenuOption with the provided label
func (o SelectMenuOption) WithLabel(label string) SelectMenuOption {
o.Label = label
return o
}

// WithValue returns a new SelectMenuOption with the provided value
func (o SelectMenuOption) WithValue(value string) SelectMenuOption {
o.Value = value
return o
}

// WithDescription returns a new SelectMenuOption with the provided description
func (o SelectMenuOption) WithDescription(description string) SelectMenuOption {
o.Description = description
return o
}

// WithEmoji returns a new SelectMenuOption with the provided Emoji
func (o SelectMenuOption) WithEmoji(emoji ComponentEmoji) SelectMenuOption {
o.Emoji = &emoji
return o
}

// WithDefault returns a new SelectMenuOption as default/non-default
func (o SelectMenuOption) WithDefault(defaultOption bool) SelectMenuOption {
o.Default = defaultOption
return o
}

var (
_ Component = (*TextInputComponent)(nil)
_ InteractiveComponent = (*TextInputComponent)(nil)
Expand Down
Loading

0 comments on commit 5e33848

Please sign in to comment.