Skip to content

Commit

Permalink
Adding support for view interactions as well as input, file, and mult…
Browse files Browse the repository at this point in the history
…i select block elements
  • Loading branch information
tsein-stripe committed Feb 19, 2020
1 parent 2813fc5 commit dea0811
Show file tree
Hide file tree
Showing 15 changed files with 810 additions and 171 deletions.
1 change: 1 addition & 0 deletions block.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (
MBTImage MessageBlockType = "image"
MBTAction MessageBlockType = "actions"
MBTContext MessageBlockType = "context"
MBTFile MessageBlockType = "file"
MBTInput MessageBlockType = "input"
)

Expand Down
189 changes: 114 additions & 75 deletions block_conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,17 @@ func (b *Blocks) UnmarshalJSON(data []byte) error {
block = &DividerBlock{}
case "image":
block = &ImageBlock{}
case "input":
block = &InputBlock{}
case "section":
block = &SectionBlock{}
case "file":
block = &FileBlock{}
case "input":
block = &InputBlock{}
case "rich_text":
// for now ignore the (complex) content of rich_text blocks until we can fully support it
continue
case "file":
// for now ignore the file blocks until we can fully support it
continue
default:
return errors.New("unsupported block type")
block = &UnknownBlock{}
}

err = json.Unmarshal(r, block)
Expand All @@ -84,61 +83,60 @@ func (b *Blocks) UnmarshalJSON(data []byte) error {
return nil
}

// UnmarshalJSON implements the Unmarshaller interface for InputBlock, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (b *InputBlock) UnmarshalJSON(data []byte) error {
type alias InputBlock
a := struct {
Element json.RawMessage `json:"element"`
*alias
}{
alias: (*alias)(b),
// MarshalJSON implements the Marshaller interface for BlockElements so that any JSON
// marshalling is delegated and proper type determination can be made before marshal
func (b *BlockElements) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(b.ElementSet)
if err != nil {
return nil, err
}

if err := json.Unmarshal(data, &a); err != nil {
return err
}
return bytes, nil
}

s := sumtype{}
if err := json.Unmarshal(a.Element, &s); err != nil {
// UnmarshalJSON implements the Unmarshaller interface for BlockElements, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (b *BlockElements) UnmarshalJSON(data []byte) error {
var raw []json.RawMessage

if string(data) == "{}" {
return nil
}

var e BlockElement
switch s.TypeVal {
case "datepicker":
e = &DatePickerBlockElement{}
case "plain_text_input":
e = &PlainTextInputBlockElement{}
case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
e = &SelectBlockElement{}
default:
return errors.New("unsupported block element type")
err := json.Unmarshal(data, &raw)
if err != nil {
return err
}

if err := json.Unmarshal(a.Element, e); err != nil {
return err
var blockElements BlockElements
for _, r := range raw {
blockElement, err := unmarshalAnyBlockElement(r)
if err != nil {
return err
}

blockElements.ElementSet = append(blockElements.ElementSet, blockElement)
}
b.Element = e

*b = blockElements
return nil
}

// MarshalJSON implements the Marshaller interface for BlockElements so that any JSON
// MarshalJSON implements the Marshaller interface for a SingularBlockElement so that any JSON
// marshalling is delegated and proper type determination can be made before marshal
func (b *BlockElements) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(b.ElementSet)
func (b *SingularBlockElement) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(b.Element)
if err != nil {
return nil, err
}

return bytes, nil
}

// UnmarshalJSON implements the Unmarshaller interface for BlockElements, so that any JSON
// UnmarshalJSON implements the Unmarshaller interface for a SingularBlockElement, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (b *BlockElements) UnmarshalJSON(data []byte) error {
var raw []json.RawMessage
func (b *SingularBlockElement) UnmarshalJSON(data []byte) error {
var raw json.RawMessage

if string(data) == "{}" {
return nil
Expand All @@ -149,47 +147,55 @@ func (b *BlockElements) UnmarshalJSON(data []byte) error {
return err
}

var blockElements BlockElements
for _, r := range raw {
s := sumtype{}
err := json.Unmarshal(r, &s)
if err != nil {
return err
}
blockElement, err := unmarshalAnyBlockElement(raw)
if err != nil {
return err
}

var blockElementType string
if s.TypeVal != "" {
blockElementType = s.TypeVal
}
*b = SingularBlockElement{blockElement}
return nil
}

var blockElement BlockElement
switch blockElementType {
case "image":
blockElement = &ImageBlockElement{}
case "button":
blockElement = &ButtonBlockElement{}
case "overflow":
blockElement = &OverflowBlockElement{}
case "datepicker":
blockElement = &DatePickerBlockElement{}
case "plain_text_input":
blockElement = &PlainTextInputBlockElement{}
case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
blockElement = &SelectBlockElement{}
default:
return errors.New("unsupported block element type")
}
func unmarshalAnyBlockElement(raw json.RawMessage) (BlockElement, error) {
var blockElement BlockElement
s := sumtype{}
err := json.Unmarshal(raw, &s)
if err != nil {
return nil, err
}

err = json.Unmarshal(r, blockElement)
if err != nil {
return err
}
var blockElementType string
if s.TypeVal != "" {
blockElementType = s.TypeVal
}

blockElements.ElementSet = append(blockElements.ElementSet, blockElement)
switch blockElementType {
case "image":
blockElement = &ImageBlockElement{}
case "button":
blockElement = &ButtonBlockElement{}
case "overflow":
blockElement = &OverflowBlockElement{}
case "datepicker":
blockElement = &DatePickerBlockElement{}
case "plain_text_input":
blockElement = &PlainTextInputBlockElement{}
case "radio_buttons":
blockElement = &RadioButtonsBlockElement{}
case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
blockElement = &SelectBlockElement{}
case "multi_static_select", "multi_external_select", "multi_users_select", "multi_conversations_select", "multi_channels_select":
blockElement = &MultiSelectBlockElement{}
default:
blockElement = &UnknownBlockElement{}
}

*b = blockElements
return nil
err = json.Unmarshal(raw, blockElement)
if err != nil {
return nil, err
}

return blockElement, nil
}

// MarshalJSON implements the Marshaller interface for Accessory so that any JSON
Expand Down Expand Up @@ -253,12 +259,36 @@ func (a *Accessory) UnmarshalJSON(data []byte) error {
return err
}
a.DatePickerElement = element.(*DatePickerBlockElement)
case "static_select":
case "plain_text_input":
element, err := unmarshalBlockElement(r, &PlainTextInputBlockElement{})
if err != nil {
return err
}
a.PlainTextInputElement = element.(*PlainTextInputBlockElement)
case "radio_buttons":
element, err := unmarshalBlockElement(r, &RadioButtonsBlockElement{})
if err != nil {
return err
}
a.RadioButtonsElement = element.(*RadioButtonsBlockElement)
case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
element, err := unmarshalBlockElement(r, &SelectBlockElement{})
if err != nil {
return err
}
a.SelectElement = element.(*SelectBlockElement)
case "multi_static_select", "multi_external_select", "multi_users_select", "multi_conversations_select", "multi_channels_select":
element, err := unmarshalBlockElement(r, &MultiSelectBlockElement{})
if err != nil {
return err
}
a.MultiSelectElement = element.(*MultiSelectBlockElement)
default:
element, err := unmarshalBlockElement(r, &UnknownBlockElement{})
if err != nil {
return err
}
a.UnknownElement = element.(*UnknownBlockElement)
}

return nil
Expand All @@ -285,9 +315,18 @@ func toBlockElement(element *Accessory) BlockElement {
if element.DatePickerElement != nil {
return element.DatePickerElement
}
if element.PlainTextInputElement != nil {
return element.PlainTextInputElement
}
if element.RadioButtonsElement != nil {
return element.RadioButtonsElement
}
if element.SelectElement != nil {
return element.SelectElement
}
if element.MultiSelectElement != nil {
return element.MultiSelectElement
}

return nil
}
Expand Down
Loading

0 comments on commit dea0811

Please sign in to comment.