mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-22 18:52:02 -08:00
242 lines
6.6 KiB
Go
242 lines
6.6 KiB
Go
|
package discordgo
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
// ComponentType is type of component.
|
||
|
type ComponentType uint
|
||
|
|
||
|
// MessageComponent types.
|
||
|
const (
|
||
|
ActionsRowComponent ComponentType = 1
|
||
|
ButtonComponent ComponentType = 2
|
||
|
SelectMenuComponent ComponentType = 3
|
||
|
TextInputComponent ComponentType = 4
|
||
|
)
|
||
|
|
||
|
// MessageComponent is a base interface for all message components.
|
||
|
type MessageComponent interface {
|
||
|
json.Marshaler
|
||
|
Type() ComponentType
|
||
|
}
|
||
|
|
||
|
type unmarshalableMessageComponent struct {
|
||
|
MessageComponent
|
||
|
}
|
||
|
|
||
|
// UnmarshalJSON is a helper function to unmarshal MessageComponent object.
|
||
|
func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error {
|
||
|
var v struct {
|
||
|
Type ComponentType `json:"type"`
|
||
|
}
|
||
|
err := json.Unmarshal(src, &v)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
switch v.Type {
|
||
|
case ActionsRowComponent:
|
||
|
umc.MessageComponent = &ActionsRow{}
|
||
|
case ButtonComponent:
|
||
|
umc.MessageComponent = &Button{}
|
||
|
case SelectMenuComponent:
|
||
|
umc.MessageComponent = &SelectMenu{}
|
||
|
case TextInputComponent:
|
||
|
umc.MessageComponent = &TextInput{}
|
||
|
default:
|
||
|
return fmt.Errorf("unknown component type: %d", v.Type)
|
||
|
}
|
||
|
return json.Unmarshal(src, umc.MessageComponent)
|
||
|
}
|
||
|
|
||
|
// MessageComponentFromJSON is a helper function for unmarshaling message components
|
||
|
func MessageComponentFromJSON(b []byte) (MessageComponent, error) {
|
||
|
var u unmarshalableMessageComponent
|
||
|
err := u.UnmarshalJSON(b)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to unmarshal into MessageComponent: %w", err)
|
||
|
}
|
||
|
return u.MessageComponent, nil
|
||
|
}
|
||
|
|
||
|
// ActionsRow is a container for components within one row.
|
||
|
type ActionsRow struct {
|
||
|
Components []MessageComponent `json:"components"`
|
||
|
}
|
||
|
|
||
|
// MarshalJSON is a method for marshaling ActionsRow to a JSON object.
|
||
|
func (r ActionsRow) MarshalJSON() ([]byte, error) {
|
||
|
type actionsRow ActionsRow
|
||
|
|
||
|
return json.Marshal(struct {
|
||
|
actionsRow
|
||
|
Type ComponentType `json:"type"`
|
||
|
}{
|
||
|
actionsRow: actionsRow(r),
|
||
|
Type: r.Type(),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// UnmarshalJSON is a helper function to unmarshal Actions Row.
|
||
|
func (r *ActionsRow) UnmarshalJSON(data []byte) error {
|
||
|
var v struct {
|
||
|
RawComponents []unmarshalableMessageComponent `json:"components"`
|
||
|
}
|
||
|
err := json.Unmarshal(data, &v)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
r.Components = make([]MessageComponent, len(v.RawComponents))
|
||
|
for i, v := range v.RawComponents {
|
||
|
r.Components[i] = v.MessageComponent
|
||
|
}
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// Type is a method to get the type of a component.
|
||
|
func (r ActionsRow) Type() ComponentType {
|
||
|
return ActionsRowComponent
|
||
|
}
|
||
|
|
||
|
// ButtonStyle is style of button.
|
||
|
type ButtonStyle uint
|
||
|
|
||
|
// Button styles.
|
||
|
const (
|
||
|
// PrimaryButton is a button with blurple color.
|
||
|
PrimaryButton ButtonStyle = 1
|
||
|
// SecondaryButton is a button with grey color.
|
||
|
SecondaryButton ButtonStyle = 2
|
||
|
// SuccessButton is a button with green color.
|
||
|
SuccessButton ButtonStyle = 3
|
||
|
// DangerButton is a button with red color.
|
||
|
DangerButton ButtonStyle = 4
|
||
|
// LinkButton is a special type of button which navigates to a URL. Has grey color.
|
||
|
LinkButton ButtonStyle = 5
|
||
|
)
|
||
|
|
||
|
// ComponentEmoji represents button emoji, if it does have one.
|
||
|
type ComponentEmoji struct {
|
||
|
Name string `json:"name,omitempty"`
|
||
|
ID string `json:"id,omitempty"`
|
||
|
Animated bool `json:"animated,omitempty"`
|
||
|
}
|
||
|
|
||
|
// Button represents button component.
|
||
|
type Button struct {
|
||
|
Label string `json:"label"`
|
||
|
Style ButtonStyle `json:"style"`
|
||
|
Disabled bool `json:"disabled"`
|
||
|
Emoji ComponentEmoji `json:"emoji"`
|
||
|
|
||
|
// NOTE: Only button with LinkButton style can have link. Also, URL is mutually exclusive with CustomID.
|
||
|
URL string `json:"url,omitempty"`
|
||
|
CustomID string `json:"custom_id,omitempty"`
|
||
|
}
|
||
|
|
||
|
// MarshalJSON is a method for marshaling Button to a JSON object.
|
||
|
func (b Button) MarshalJSON() ([]byte, error) {
|
||
|
type button Button
|
||
|
|
||
|
if b.Style == 0 {
|
||
|
b.Style = PrimaryButton
|
||
|
}
|
||
|
|
||
|
return json.Marshal(struct {
|
||
|
button
|
||
|
Type ComponentType `json:"type"`
|
||
|
}{
|
||
|
button: button(b),
|
||
|
Type: b.Type(),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// Type is a method to get the type of a component.
|
||
|
func (Button) Type() ComponentType {
|
||
|
return ButtonComponent
|
||
|
}
|
||
|
|
||
|
// SelectMenuOption represents an option for a select menu.
|
||
|
type SelectMenuOption struct {
|
||
|
Label string `json:"label,omitempty"`
|
||
|
Value string `json:"value"`
|
||
|
Description string `json:"description"`
|
||
|
Emoji ComponentEmoji `json:"emoji"`
|
||
|
// Determines whenever option is selected by default or not.
|
||
|
Default bool `json:"default"`
|
||
|
}
|
||
|
|
||
|
// SelectMenu represents select menu component.
|
||
|
type SelectMenu struct {
|
||
|
CustomID string `json:"custom_id,omitempty"`
|
||
|
// The text which will be shown in the menu if there's no default options or all options was deselected and component was closed.
|
||
|
Placeholder string `json:"placeholder"`
|
||
|
// This value determines the minimal amount of selected items in the menu.
|
||
|
MinValues *int `json:"min_values,omitempty"`
|
||
|
// This value determines the maximal amount of selected items in the menu.
|
||
|
// If MaxValues or MinValues are greater than one then the user can select multiple items in the component.
|
||
|
MaxValues int `json:"max_values,omitempty"`
|
||
|
Options []SelectMenuOption `json:"options"`
|
||
|
Disabled bool `json:"disabled"`
|
||
|
}
|
||
|
|
||
|
// Type is a method to get the type of a component.
|
||
|
func (SelectMenu) Type() ComponentType {
|
||
|
return SelectMenuComponent
|
||
|
}
|
||
|
|
||
|
// MarshalJSON is a method for marshaling SelectMenu to a JSON object.
|
||
|
func (m SelectMenu) MarshalJSON() ([]byte, error) {
|
||
|
type selectMenu SelectMenu
|
||
|
|
||
|
return json.Marshal(struct {
|
||
|
selectMenu
|
||
|
Type ComponentType `json:"type"`
|
||
|
}{
|
||
|
selectMenu: selectMenu(m),
|
||
|
Type: m.Type(),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// TextInput represents text input component.
|
||
|
type TextInput struct {
|
||
|
CustomID string `json:"custom_id"`
|
||
|
Label string `json:"label"`
|
||
|
Style TextInputStyle `json:"style"`
|
||
|
Placeholder string `json:"placeholder,omitempty"`
|
||
|
Value string `json:"value,omitempty"`
|
||
|
Required bool `json:"required,omitempty"`
|
||
|
MinLength int `json:"min_length,omitempty"`
|
||
|
MaxLength int `json:"max_length,omitempty"`
|
||
|
}
|
||
|
|
||
|
// Type is a method to get the type of a component.
|
||
|
func (TextInput) Type() ComponentType {
|
||
|
return TextInputComponent
|
||
|
}
|
||
|
|
||
|
// MarshalJSON is a method for marshaling TextInput to a JSON object.
|
||
|
func (m TextInput) MarshalJSON() ([]byte, error) {
|
||
|
type inputText TextInput
|
||
|
|
||
|
return json.Marshal(struct {
|
||
|
inputText
|
||
|
Type ComponentType `json:"type"`
|
||
|
}{
|
||
|
inputText: inputText(m),
|
||
|
Type: m.Type(),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// TextInputStyle is style of text in TextInput component.
|
||
|
type TextInputStyle uint
|
||
|
|
||
|
// Text styles
|
||
|
const (
|
||
|
TextInputShort TextInputStyle = 1
|
||
|
TextInputParagraph TextInputStyle = 2
|
||
|
)
|