components.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. )
  12. // MessageComponent is a base interface for all message components.
  13. type MessageComponent interface {
  14. json.Marshaler
  15. Type() ComponentType
  16. }
  17. type unmarshalableMessageComponent struct {
  18. MessageComponent
  19. }
  20. // UnmarshalJSON is a helper function to unmarshal MessageComponent object.
  21. func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error {
  22. var v struct {
  23. Type ComponentType `json:"type"`
  24. }
  25. err := json.Unmarshal(src, &v)
  26. if err != nil {
  27. return err
  28. }
  29. var data MessageComponent
  30. switch v.Type {
  31. case ActionsRowComponent:
  32. v := ActionsRow{}
  33. err = json.Unmarshal(src, &v)
  34. data = v
  35. case ButtonComponent:
  36. v := Button{}
  37. err = json.Unmarshal(src, &v)
  38. data = v
  39. }
  40. if err != nil {
  41. return err
  42. }
  43. umc.MessageComponent = data
  44. return err
  45. }
  46. // ActionsRow is a container for components within one row.
  47. type ActionsRow struct {
  48. Components []MessageComponent `json:"components"`
  49. }
  50. // MarshalJSON is a method for marshaling ActionsRow to a JSON object.
  51. func (r ActionsRow) MarshalJSON() ([]byte, error) {
  52. type actionsRow ActionsRow
  53. return json.Marshal(struct {
  54. actionsRow
  55. Type ComponentType `json:"type"`
  56. }{
  57. actionsRow: actionsRow(r),
  58. Type: r.Type(),
  59. })
  60. }
  61. // UnmarshalJSON is a helper function to unmarshal Actions Row.
  62. func (r *ActionsRow) UnmarshalJSON(data []byte) error {
  63. var v struct {
  64. RawComponents []unmarshalableMessageComponent `json:"components"`
  65. }
  66. err := json.Unmarshal(data, &v)
  67. if err != nil {
  68. return err
  69. }
  70. r.Components = make([]MessageComponent, len(v.RawComponents))
  71. for i, v := range v.RawComponents {
  72. r.Components[i] = v.MessageComponent
  73. }
  74. return err
  75. }
  76. // Type is a method to get the type of a component.
  77. func (r ActionsRow) Type() ComponentType {
  78. return ActionsRowComponent
  79. }
  80. // ButtonStyle is style of button.
  81. type ButtonStyle uint
  82. // Button styles.
  83. const (
  84. // PrimaryButton is a button with blurple color.
  85. PrimaryButton ButtonStyle = 1
  86. // SecondaryButton is a button with grey color.
  87. SecondaryButton ButtonStyle = 2
  88. // SuccessButton is a button with green color.
  89. SuccessButton ButtonStyle = 3
  90. // DangerButton is a button with red color.
  91. DangerButton ButtonStyle = 4
  92. // LinkButton is a special type of button which navigates to a URL. Has grey color.
  93. LinkButton ButtonStyle = 5
  94. )
  95. // ButtonEmoji represents button emoji, if it does have one.
  96. type ButtonEmoji struct {
  97. Name string `json:"name,omitempty"`
  98. ID string `json:"id,omitempty"`
  99. Animated bool `json:"animated,omitempty"`
  100. }
  101. // Button represents button component.
  102. type Button struct {
  103. Label string `json:"label"`
  104. Style ButtonStyle `json:"style"`
  105. Disabled bool `json:"disabled"`
  106. Emoji ButtonEmoji `json:"emoji"`
  107. // NOTE: Only button with LinkButton style can have link. Also, URL is mutually exclusive with CustomID.
  108. URL string `json:"url,omitempty"`
  109. CustomID string `json:"custom_id,omitempty"`
  110. }
  111. // MarshalJSON is a method for marshaling Button to a JSON object.
  112. func (b Button) MarshalJSON() ([]byte, error) {
  113. type button Button
  114. if b.Style == 0 {
  115. b.Style = PrimaryButton
  116. }
  117. return json.Marshal(struct {
  118. button
  119. Type ComponentType `json:"type"`
  120. }{
  121. button: button(b),
  122. Type: b.Type(),
  123. })
  124. }
  125. // Type is a method to get the type of a component.
  126. func (b Button) Type() ComponentType {
  127. return ButtonComponent
  128. }