Repository: slack-go/slack
Pull request #870 (2020-12-14 05:50:53)

Added timepicker form block element
Slack has added a `timepicker` form block component. This mimics the existing `datepicker` API, only adding functionality.


Patch:
diff --git a/block.go b/block.go
index dd4b871..9946a29 100644
--- a/block.go
+++ b/block.go
@@ -48,11 +48,13 @@ type BlockAction struct {
 	SelectedConversation  string              `json:"selected_conversation"`
 	SelectedConversations []string            `json:"selected_conversations"`
 	SelectedDate          string              `json:"selected_date"`
+	SelectedTime          string              `json:"selected_time"`
 	InitialOption         OptionBlockObject   `json:"initial_option"`
 	InitialUser           string              `json:"initial_user"`
 	InitialChannel        string              `json:"initial_channel"`
 	InitialConversation   string              `json:"initial_conversation"`
 	InitialDate           string              `json:"initial_date"`
+	InitialTime           string              `json:"initial_time"`
 }
 
 // actionType returns the type of the action
diff --git a/block_conv.go b/block_conv.go
index 656a9ab..4e1f270 100644
--- a/block_conv.go
+++ b/block_conv.go
@@ -105,6 +105,8 @@ func (b *InputBlock) UnmarshalJSON(data []byte) error {
 	switch s.TypeVal {
 	case "datepicker":
 		e = &DatePickerBlockElement{}
+	case "timepicker":
+		e = &TimePickerBlockElement{}
 	case "plain_text_input":
 		e = &PlainTextInputBlockElement{}
 	case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
@@ -262,6 +264,12 @@ func (a *Accessory) UnmarshalJSON(data []byte) error {
 			return err
 		}
 		a.DatePickerElement = element.(*DatePickerBlockElement)
+	case "timepicker":
+		element, err := unmarshalBlockElement(r, &TimePickerBlockElement{})
+		if err != nil {
+			return err
+		}
+		a.TimePickerElement = element.(*TimePickerBlockElement)
 	case "plain_text_input":
 		element, err := unmarshalBlockElement(r, &PlainTextInputBlockElement{})
 		if err != nil {
@@ -324,6 +332,9 @@ func toBlockElement(element *Accessory) BlockElement {
 	if element.DatePickerElement != nil {
 		return element.DatePickerElement
 	}
+	if element.TimePickerElement != nil {
+		return element.TimePickerElement
+	}
 	if element.PlainTextInputElement != nil {
 		return element.PlainTextInputElement
 	}
diff --git a/block_element.go b/block_element.go
index 91b6adc..77b10b4 100644
--- a/block_element.go
+++ b/block_element.go
@@ -8,6 +8,7 @@ const (
 	METButton         MessageElementType = "button"
 	METOverflow       MessageElementType = "overflow"
 	METDatepicker     MessageElementType = "datepicker"
+	METTimepicker     MessageElementType = "timepicker"
 	METPlainTextInput MessageElementType = "plain_text_input"
 	METRadioButtons   MessageElementType = "radio_buttons"
 
@@ -44,6 +45,7 @@ type Accessory struct {
 	ButtonElement              *ButtonBlockElement
 	OverflowElement            *OverflowBlockElement
 	DatePickerElement          *DatePickerBlockElement
+	TimePickerElement          *TimePickerBlockElement
 	PlainTextInputElement      *PlainTextInputBlockElement
 	RadioButtonsElement        *RadioButtonsBlockElement
 	SelectElement              *SelectBlockElement
@@ -63,6 +65,8 @@ func NewAccessory(element BlockElement) *Accessory {
 		return &Accessory{OverflowElement: element.(*OverflowBlockElement)}
 	case *DatePickerBlockElement:
 		return &Accessory{DatePickerElement: element.(*DatePickerBlockElement)}
+	case *TimePickerBlockElement:
+		return &Accessory{TimePickerElement: element.(*TimePickerBlockElement)}
 	case *PlainTextInputBlockElement:
 		return &Accessory{PlainTextInputElement: element.(*PlainTextInputBlockElement)}
 	case *RadioButtonsBlockElement:
@@ -350,6 +354,32 @@ func NewDatePickerBlockElement(actionID string) *DatePickerBlockElement {
 	}
 }
 
+// TimePickerBlockElement defines an element which lets users easily select a
+// time from nice UI. Time picker elements can be used inside of
+// section and actions blocks.
+//
+// More Information: https://api.slack.com/reference/messaging/block-elements#timepicker
+type TimePickerBlockElement struct {
+	Type        MessageElementType       `json:"type"`
+	ActionID    string                   `json:"action_id,omitempty"`
+	Placeholder *TextBlockObject         `json:"placeholder,omitempty"`
+	InitialTime string                   `json:"initial_time,omitempty"`
+	Confirm     *ConfirmationBlockObject `json:"confirm,omitempty"`
+}
+
+// ElementType returns the type of the Element
+func (s TimePickerBlockElement) ElementType() MessageElementType {
+	return s.Type
+}
+
+// NewTimePickerBlockElement returns an instance of a date picker element
+func NewTimePickerBlockElement(actionID string) *TimePickerBlockElement {
+	return &TimePickerBlockElement{
+		Type:     METTimepicker,
+		ActionID: actionID,
+	}
+}
+
 // PlainTextInputBlockElement creates a field where a user can enter freeform
 // data.
 // Plain-text input elements are currently only available in modals.
diff --git a/examples/blocks/blocks.go b/examples/blocks/blocks.go
index d085123..28d54d1 100644
--- a/examples/blocks/blocks.go
+++ b/examples/blocks/blocks.go
@@ -510,6 +510,9 @@ func unmarshalExample() {
 				case slack.METDatepicker:
 					datepickerElem := elem.(*slack.DatePickerBlockElement)
 					fmt.Printf("do something with datepicker block element: %v\n", datepickerElem)
+				case slack.METTimepicker:
+					timepickerElem := elem.(*slack.TimePickerBlockElement)
+					fmt.Printf("do something with timepicker block element: %v\n", timepickerElem)
 				}
 			}
 			respBlocks = append(respBlocks, block)


Test patch:
diff --git a/block_element_test.go b/block_element_test.go
index 68c1dfd..55387fc 100644
--- a/block_element_test.go
+++ b/block_element_test.go
@@ -112,6 +112,12 @@ func TestNewDatePickerBlockElement(t *testing.T) {
 
 }
 
+func TestNewTimePickerBlockElement(t *testing.T) {
+	timepickerElement := NewTimePickerBlockElement("test")
+	assert.Equal(t, string(timepickerElement.Type), "timepicker")
+	assert.Equal(t, timepickerElement.ActionID, "test")
+}
+
 func TestNewPlainTextInputBlockElement(t *testing.T) {
 
 	plainTextInputElement := NewPlainTextInputBlockElement(nil, "test")