components.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package discordgo
  2. import (
  3. "encoding/json"
  4. )
  5. // ComponentType is type of component.
  6. type ComponentType uint
  7. // MessageComponent types.
  8. const (
  9. ActionsRowComponent ComponentType = 1
  10. ButtonComponent ComponentType = 2
  11. SelectMenuComponent ComponentType = 3
  12. )
  13. // MessageComponent is a base interface for all message components.
  14. type MessageComponent interface {
  15. json.Marshaler
  16. Type() ComponentType
  17. }
  18. type unmarshalableMessageComponent struct {
  19. MessageComponent
  20. }
  21. // UnmarshalJSON is a helper function to unmarshal MessageComponent object.
  22. func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error {
  23. var v struct {
  24. Type ComponentType `json:"type"`
  25. }
  26. err := json.Unmarshal(src, &v)
  27. if err != nil {
  28. return err
  29. }
  30. var data MessageComponent
  31. switch v.Type {
  32. case ActionsRowComponent:
  33. v := ActionsRow{}
  34. err = json.Unmarshal(src, &v)
  35. data = v
  36. case ButtonComponent:
  37. v := Button{}
  38. err = json.Unmarshal(src, &v)
  39. data = v
  40. }
  41. if err != nil {
  42. return err
  43. }
  44. umc.MessageComponent = data
  45. return err
  46. }
  47. // ActionsRow is a container for components within one row.
  48. type ActionsRow struct {
  49. Components []MessageComponent `json:"components"`
  50. }
  51. // MarshalJSON is a method for marshaling ActionsRow to a JSON object.
  52. func (r ActionsRow) MarshalJSON() ([]byte, error) {
  53. type actionsRow ActionsRow
  54. return json.Marshal(struct {
  55. actionsRow
  56. Type ComponentType `json:"type"`
  57. }{
  58. actionsRow: actionsRow(r),
  59. Type: r.Type(),
  60. })
  61. }
  62. // UnmarshalJSON is a helper function to unmarshal Actions Row.
  63. func (r *ActionsRow) UnmarshalJSON(data []byte) error {
  64. var v struct {
  65. RawComponents []unmarshalableMessageComponent `json:"components"`
  66. }
  67. err := json.Unmarshal(data, &v)
  68. if err != nil {
  69. return err
  70. }
  71. r.Components = make([]MessageComponent, len(v.RawComponents))
  72. for i, v := range v.RawComponents {
  73. r.Components[i] = v.MessageComponent
  74. }
  75. return err
  76. }
  77. // Type is a method to get the type of a component.
  78. func (r ActionsRow) Type() ComponentType {
  79. return ActionsRowComponent
  80. }
  81. // ButtonStyle is style of button.
  82. type ButtonStyle uint
  83. // Button styles.
  84. const (
  85. // PrimaryButton is a button with blurple color.
  86. PrimaryButton ButtonStyle = 1
  87. // SecondaryButton is a button with grey color.
  88. SecondaryButton ButtonStyle = 2
  89. // SuccessButton is a button with green color.
  90. SuccessButton ButtonStyle = 3
  91. // DangerButton is a button with red color.
  92. DangerButton ButtonStyle = 4
  93. // LinkButton is a special type of button which navigates to a URL. Has grey color.
  94. LinkButton ButtonStyle = 5
  95. )
  96. // ComponentEmoji represents button emoji, if it does have one.
  97. type ComponentEmoji struct {
  98. Name string `json:"name,omitempty"`
  99. ID string `json:"id,omitempty"`
  100. Animated bool `json:"animated,omitempty"`
  101. }
  102. // Button represents button component.
  103. type Button struct {
  104. Label string `json:"label"`
  105. Style ButtonStyle `json:"style"`
  106. Disabled bool `json:"disabled"`
  107. Emoji ComponentEmoji `json:"emoji"`
  108. // NOTE: Only button with LinkButton style can have link. Also, URL is mutually exclusive with CustomID.
  109. URL string `json:"url,omitempty"`
  110. CustomID string `json:"custom_id,omitempty"`
  111. }
  112. // MarshalJSON is a method for marshaling Button to a JSON object.
  113. func (b Button) MarshalJSON() ([]byte, error) {
  114. type button Button
  115. if b.Style == 0 {
  116. b.Style = PrimaryButton
  117. }
  118. return json.Marshal(struct {
  119. button
  120. Type ComponentType `json:"type"`
  121. }{
  122. button: button(b),
  123. Type: b.Type(),
  124. })
  125. }
  126. // Type is a method to get the type of a component.
  127. func (Button) Type() ComponentType {
  128. return ButtonComponent
  129. }
  130. // SelectMenuOption represents an option for a select menu.
  131. type SelectMenuOption struct {
  132. Label string `json:"label,omitempty"`
  133. Value string `json:"value"`
  134. Description string `json:"description"`
  135. Emoji ComponentEmoji `json:"emoji"`
  136. // Determines whenever option is selected by default or not.
  137. Default bool `json:"default"`
  138. }
  139. // SelectMenu represents select menu component.
  140. type SelectMenu struct {
  141. CustomID string `json:"custom_id,omitempty"`
  142. // The text which will be shown in the menu if there's no default options or all options was deselected and component was closed.
  143. Placeholder string `json:"placeholder"`
  144. // This value determines the minimal amount of selected items in the menu.
  145. MinValues int `json:"min_values,omitempty"`
  146. // This value determines the maximal amount of selected items in the menu.
  147. // If MaxValues or MinValues are greater than one then the user can select multiple items in the component.
  148. MaxValues int `json:"max_values,omitempty"`
  149. Options []SelectMenuOption `json:"options"`
  150. }
  151. // Type is a method to get the type of a component.
  152. func (SelectMenu) Type() ComponentType {
  153. return SelectMenuComponent
  154. }
  155. // MarshalJSON is a method for marshaling SelectMenu to a JSON object.
  156. func (m SelectMenu) MarshalJSON() ([]byte, error) {
  157. type selectMenu SelectMenu
  158. return json.Marshal(struct {
  159. selectMenu
  160. Type ComponentType `json:"type"`
  161. }{
  162. selectMenu: selectMenu(m),
  163. Type: m.Type(),
  164. })
  165. }