From e71602c214938bb76176bd719975849e62bbfe51 Mon Sep 17 00:00:00 2001 From: erroneousboat Date: Fri, 30 Sep 2016 23:52:26 +0200 Subject: [PATCH] Start with group and im channels --- TODO.md | 1 + src/components/channels.go | 16 +------ src/components/chat.go | 8 ++-- src/handlers/event.go | 12 ++--- src/service/slack.go | 94 ++++++++++++++++++++++++++++++++++---- src/views/chat.go | 5 +- 6 files changed, 100 insertions(+), 36 deletions(-) diff --git a/TODO.md b/TODO.md index 0d6fe41..3a24ad8 100644 --- a/TODO.md +++ b/TODO.md @@ -26,4 +26,5 @@ Features: - [x] new message indicator - [x] scrolling in chat pane - [ ] group channels, im channels +- [ ] incomming message event.go probably need a type switch - [ ] scrolling in channel pane diff --git a/src/components/channels.go b/src/components/channels.go index fc1ffcd..3723e14 100644 --- a/src/components/channels.go +++ b/src/components/channels.go @@ -10,7 +10,6 @@ import ( type Channels struct { List *termui.List - SlackChannels []SlackChannel SelectedChannel int } @@ -65,10 +64,6 @@ func (c *Channels) Buffer() termui.Buffer { return buf } -func (c *Channels) Add() { - -} - // GetHeight implements interface termui.GridBufferer func (c *Channels) GetHeight() int { return c.List.Block.GetHeight() @@ -96,13 +91,6 @@ func (c *Channels) SetY(y int) { func (c *Channels) GetChannels(svc *service.SlackService) { for _, slackChan := range svc.GetChannels() { c.List.Items = append(c.List.Items, fmt.Sprintf(" %s", slackChan.Name)) - c.SlackChannels = append( - c.SlackChannels, - SlackChannel{ - ID: slackChan.ID, - Name: slackChan.Name, - }, - ) } } @@ -129,11 +117,11 @@ func (c *Channels) MoveCursorDown() { // NewMessage will be called when a new message arrives and will // render an asterisk in front of the channel name -func (c *Channels) NewMessage(channelID string) { +func (c *Channels) NewMessage(svc *service.SlackService, channelID string) { var index int // Get the correct Channel from SlackChannels - for i, channel := range c.SlackChannels { + for i, channel := range svc.Channels { if channelID == channel.ID { index = i break diff --git a/src/components/chat.go b/src/components/chat.go index 362e8ef..dccf433 100644 --- a/src/components/chat.go +++ b/src/components/chat.go @@ -14,7 +14,7 @@ type Chat struct { } // CreateChat is the constructor for the Chat struct -func CreateChat(svc *service.SlackService, inputHeight int, selectedChannel SlackChannel) *Chat { +func CreateChat(svc *service.SlackService, inputHeight int, selectedChannel interface{}) *Chat { chat := &Chat{ List: termui.NewList(), Offset: 0, @@ -23,8 +23,8 @@ func CreateChat(svc *service.SlackService, inputHeight int, selectedChannel Slac chat.List.Height = termui.TermHeight() - inputHeight chat.List.Overflow = "wrap" - chat.GetMessages(svc, selectedChannel.ID) - chat.SetBorderLabel(selectedChannel.Name) + chat.GetMessages(svc, selectedChannel) + // chat.SetBorderLabel(selectedChannel.Name) return chat } @@ -136,7 +136,7 @@ func (c *Chat) SetY(y int) { // GetMessages will get an array of strings for a specific channel which will // contain messages in turn all these messages will be added to List.Items -func (c *Chat) GetMessages(svc *service.SlackService, channel string) { +func (c *Chat) GetMessages(svc *service.SlackService, channel interface{}) { // Get the count of message that fit in the pane count := c.List.InnerBounds().Max.Y - c.List.InnerBounds().Min.Y messages := svc.GetMessages(channel, count) diff --git a/src/handlers/event.go b/src/handlers/event.go index a4196eb..64287aa 100644 --- a/src/handlers/event.go +++ b/src/handlers/event.go @@ -90,7 +90,7 @@ func incomingMessageHandler(ctx *context.AppContext) { m := ctx.Service.CreateMessageFromMessageEvent(ev) // Add message to the selected channel - if ev.Channel == ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID { + if ev.Channel == ctx.Service.Channels[ctx.View.Channels.SelectedChannel].ID { ctx.View.Chat.AddMessage(m) termui.Render(ctx.View.Chat) @@ -137,7 +137,7 @@ func actionSend(ctx *context.AppContext) { if !ctx.View.Input.IsEmpty() { ctx.View.Input.SendMessage( ctx.Service, - ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID, + ctx.Service.Channels[ctx.View.Channels.SelectedChannel].ID, ctx.View.Input.Text(), ) ctx.View.Input.Clear() @@ -164,7 +164,7 @@ func actionCommandMode(ctx *context.AppContext) { func actionGetMessages(ctx *context.AppContext) { ctx.View.Chat.GetMessages( ctx.Service, - ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID, + ctx.Service.Channels[ctx.View.Channels.SelectedChannel], ) termui.Render(ctx.View.Chat) @@ -192,12 +192,12 @@ func actionChangeChannel(ctx *context.AppContext) { // Get message for the new channel ctx.View.Chat.GetMessages( ctx.Service, - ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID, + ctx.Service.SlackChannels[ctx.View.Channels.SelectedChannel], ) // Set channel name for the Chat pane ctx.View.Chat.SetBorderLabel( - ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].Name, + ctx.Service.Channels[ctx.View.Channels.SelectedChannel].Name, ) termui.Render(ctx.View.Channels) @@ -205,7 +205,7 @@ func actionChangeChannel(ctx *context.AppContext) { } func actionNewMessage(ctx *context.AppContext, channelID string) { - ctx.View.Channels.NewMessage(channelID) + ctx.View.Channels.NewMessage(ctx.Service, channelID) termui.Render(ctx.View.Channels) } diff --git a/src/service/slack.go b/src/service/slack.go index 93e7d8b..eb15741 100644 --- a/src/service/slack.go +++ b/src/service/slack.go @@ -10,10 +10,11 @@ import ( ) type SlackService struct { - Client *slack.Client - RTM *slack.RTM - Channels []slack.Channel - UserCache map[string]string + Client *slack.Client + RTM *slack.RTM + SlackChannels []interface{} + Channels []Channel + UserCache map[string]string } type Channel struct { @@ -42,17 +43,39 @@ func NewSlackService(token string) *SlackService { func (s *SlackService) GetChannels() []Channel { var chans []Channel + // Channel slackChans, err := s.Client.GetChannels(true) if err != nil { chans = append(chans, Channel{}) } - - s.Channels = slackChans - - for _, slackChan := range slackChans { - chans = append(chans, Channel{slackChan.ID, slackChan.Name}) + for _, chn := range slackChans { + s.SlackChannels = append(s.SlackChannels, chn) + chans = append(chans, Channel{chn.ID, chn.Name}) } + // TODO: json: cannot unmarshal number into Go value of type string, GetMessages + // Groups + // slackGroups, err := s.Client.GetGroups(true) + // if err != nil { + // chans = append(chans, Channel{}) + // } + // for _, grp := range slackGroups { + // s.SlackChannels = append(s.SlackChannels, grp) + // chans = append(chans, Channel{grp.ID, grp.Name}) + // } + + // IM + slackIM, err := s.Client.GetIMChannels() + if err != nil { + chans = append(chans, Channel{}) + } + for _, im := range slackIM { + s.SlackChannels = append(s.SlackChannels, im) + chans = append(chans, Channel{im.ID, im.User}) + } + + s.Channels = chans + return chans } @@ -66,7 +89,54 @@ func (s *SlackService) SendMessage(channel string, message string) { s.Client.PostMessage(channel, message, postParams) } -func (s *SlackService) GetMessages(channel string, count int) []string { +func (s *SlackService) GetMessages(channel interface{}, count int) []string { + // https://api.slack.com/methods/channels.history + historyParams := slack.HistoryParameters{ + Count: count, + Inclusive: false, + Unreads: false, + } + + // https://godoc.org/github.com/nlopes/slack#History + history := new(slack.History) + var err error + switch chnType := channel.(type) { + case slack.Channel: + history, err = s.Client.GetChannelHistory(chnType.ID, historyParams) + if err != nil { + log.Fatal(err) // FIXME + } + case slack.Group: + // TODO: json: cannot unmarshal number into Go value of type string + history, err = s.Client.GetGroupHistory(chnType.ID, historyParams) + if err != nil { + log.Fatal(err) // FIXME + } + case slack.IM: + history, err = s.Client.GetIMHistory(chnType.ID, historyParams) + if err != nil { + log.Fatal(err) // FIXME + } + } + + // Construct the messages + var messages []string + for _, message := range history.Messages { + msg := s.CreateMessage(message) + messages = append(messages, msg) + } + + // Reverse the order of the messages, we want the newest in + // the last place + var messagesReversed []string + for i := len(messages) - 1; i >= 0; i-- { + messagesReversed = append(messagesReversed, messages[i]) + } + + return messagesReversed +} + +func (s *SlackService) GetMessagesForChannel(channel string, count int) []string { // https://api.slack.com/methods/channels.history historyParams := slack.HistoryParameters{ Count: count, @@ -98,6 +168,10 @@ func (s *SlackService) GetMessages(channel string, count int) []string { return messagesReversed } +func (s *SlackService) GetMessageForGroup() { + +} + // CreateMessage will create a string formatted message that can be rendered // in the Chat pane. // diff --git a/src/views/chat.go b/src/views/chat.go index 6585aac..235f64b 100644 --- a/src/views/chat.go +++ b/src/views/chat.go @@ -20,8 +20,9 @@ func CreateChatView(svc *service.SlackService) *View { channels := components.CreateChannels(svc, input.Par.Height) chat := components.CreateChat( - svc, input.Par.Height, - channels.SlackChannels[channels.SelectedChannel], + svc, + input.Par.Height, + svc.SlackChannels[channels.SelectedChannel], ) mode := components.CreateMode()