diff --git a/components/channels.go b/components/channels.go index 007d385..902f733 100644 --- a/components/channels.go +++ b/components/channels.go @@ -235,6 +235,11 @@ func (c *Channels) SetSelectedChannel(index int) { c.SelectedChannel = index } +// Get SelectedChannel returns the ChannelItem that is currently selected +func (c *Channels) GetSelectedChannel() ChannelItem { + return c.ChannelItems[c.SelectedChannel] +} + // MoveCursorUp will decrease the SelectedChannel by 1 func (c *Channels) MoveCursorUp() { if c.SelectedChannel > 0 { diff --git a/config/config.go b/config/config.go index 316cfdc..54c68a2 100644 --- a/config/config.go +++ b/config/config.go @@ -100,6 +100,8 @@ func getDefaultConfig() Config { "j": "channel-down", "g": "channel-top", "G": "channel-bottom", + "K": "thread-up", + "J": "thread-down", "": "chat-up", "C-b": "chat-up", "C-u": "chat-up", diff --git a/handlers/event.go b/handlers/event.go index d3c652d..769966c 100644 --- a/handlers/event.go +++ b/handlers/event.go @@ -45,6 +45,8 @@ var actionMap = map[string]func(*context.AppContext){ "channel-search-next": actionSearchNextChannels, "channel-search-prev": actionSearchPrevChannels, "channel-jump": actionJumpChannels, + "thread-up": actionMoveCursorUpThreads, + "thread-down": actionMoveCursorDownThreads, "chat-up": actionScrollUpChat, "chat-down": actionScrollDownChat, "help": actionHelp, @@ -451,6 +453,63 @@ func actionChangeChannel(ctx *context.AppContext) { termui.Render(ctx.View.Chat) } +func actionChangeThread(ctx *context.AppContext) { + // Clear messages from Chat pane + ctx.View.Chat.ClearMessages() + + // TODO: err + // TODO: change function name to match GetMessages + msgs := ctx.Service.CreateMessageFromReplies( + ctx.View.Threads.ChannelItems[ctx.View.Threads.SelectedChannel].ID, + ctx.View.Channels.ChannelItems[ctx.View.Channels.SelectedChannel].ID, + ) + + // Set messages for the channel + ctx.View.Chat.SetMessages(msgs) + + termui.Render(ctx.View.Channels) + termui.Render(ctx.View.Threads) + termui.Render(ctx.View.Chat) +} + +// TODO +func actionMoveCursorUpThreads(ctx *context.AppContext) { + go func() { + if scrollTimer != nil { + scrollTimer.Stop() + } + + ctx.View.Threads.MoveCursorUp() + termui.Render(ctx.View.Threads) + + scrollTimer = time.NewTimer(time.Second / 4) + <-scrollTimer.C + + // Only actually change channel when the timer expires + actionChangeThread(ctx) + }() + +} + +// TODO +func actionMoveCursorDownThreads(ctx *context.AppContext) { + go func() { + if scrollTimer != nil { + scrollTimer.Stop() + } + + ctx.View.Threads.MoveCursorDown() + termui.Render(ctx.View.Channels) + + scrollTimer = time.NewTimer(time.Second / 4) + <-scrollTimer.C + + // Only actually change thread when the timer expires + actionChangeThread(ctx) + }() + +} + // actionNewMessage will set the new message indicator for a channel, and // if configured will also display a desktop notification func actionNewMessage(ctx *context.AppContext, ev *slack.MessageEvent) { diff --git a/service/slack.go b/service/slack.go index 3e24a8d..85c75d3 100644 --- a/service/slack.go +++ b/service/slack.go @@ -559,7 +559,7 @@ func (s *SlackService) CreateMessage(message slack.Message, channelID string) co msg.Thread = fmt.Sprintf("%s ", threadID) // Create the message replies from the thread - replies := s.CreateMessageFromReplies(message, channelID) + replies := s.CreateMessageFromReplies(message.ThreadTimestamp, channelID) for _, reply := range replies { msg.Messages[reply.ID] = reply } @@ -577,13 +577,13 @@ func (s *SlackService) CreateMessage(message slack.Message, channelID string) co // https://api.slack.com/methods/conversations.replies // https://godoc.org/github.com/nlopes/slack#Client.GetConversationReplies // https://godoc.org/github.com/nlopes/slack#GetConversationRepliesParameters -func (s *SlackService) CreateMessageFromReplies(message slack.Message, channelID string) []components.Message { +func (s *SlackService) CreateMessageFromReplies(messageID string, channelID string) []components.Message { msgs := make([]slack.Message, 0) initReplies, _, initCur, err := s.Client.GetConversationReplies( &slack.GetConversationRepliesParameters{ ChannelID: channelID, - Timestamp: message.ThreadTimestamp, + Timestamp: messageID, Limit: 200, }, ) @@ -597,7 +597,7 @@ func (s *SlackService) CreateMessageFromReplies(message slack.Message, channelID for nextCur != "" { conversationReplies, _, cursor, err := s.Client.GetConversationReplies(&slack.GetConversationRepliesParameters{ ChannelID: channelID, - Timestamp: message.ThreadTimestamp, + Timestamp: messageID, Cursor: nextCur, Limit: 200, }) diff --git a/views/view.go b/views/view.go index 1c1b25d..ec5d492 100644 --- a/views/view.go +++ b/views/view.go @@ -42,7 +42,7 @@ func CreateView(config *config.Config, svc *service.SlackService) (*View, error) chat := components.CreateChatComponent(input.Par.Height) // Chat: fill the component - msgs, thds, err := svc.GetMessages( + msgs, thr, err := svc.GetMessages( channels.ChannelItems[channels.SelectedChannel].ID, chat.GetMaxItems(), ) @@ -58,7 +58,7 @@ func CreateView(config *config.Config, svc *service.SlackService) (*View, error) ) // Threads: set threads in component - threads.SetChannels(thds) + threads.SetChannels(thr) // Debug: create the component debug := components.CreateDebugComponent(input.Par.Height)