Add channel selector, and SendMessage

This commit is contained in:
erroneousboat 2016-09-27 22:05:44 +02:00
parent 5b02f2acc8
commit b70370be1d
5 changed files with 175 additions and 24 deletions

View File

@ -6,7 +6,14 @@ import (
)
type Channels struct {
List *termui.List
List *termui.List
SlackChannels []SlackChannel
SelectedChannel int
}
type SlackChannel struct {
Name string
ID string
}
func CreateChannels(svc *service.SlackService, inputHeight int) *Channels {
@ -15,9 +22,11 @@ func CreateChannels(svc *service.SlackService, inputHeight int) *Channels {
}
channels.List.BorderLabel = "Channels"
channels.List.Overflow = "wrap"
channels.List.Height = termui.TermHeight() - inputHeight
// TODO: should be SetSelectedChannel
channels.SelectedChannel = 4
channels.GetChannels(svc)
return channels
@ -26,9 +35,38 @@ func CreateChannels(svc *service.SlackService, inputHeight int) *Channels {
// Buffer implements interface termui.Bufferer
func (c *Channels) Buffer() termui.Buffer {
buf := c.List.Buffer()
for y, item := range c.List.Items {
var cells []termui.Cell
if y == c.SelectedChannel {
cells = termui.DefaultTxBuilder.Build(
item, termui.ColorBlack, termui.ColorWhite)
} else {
cells = termui.DefaultTxBuilder.Build(
item, c.List.ItemFgColor, c.List.ItemBgColor)
}
cells = termui.DTrimTxCls(cells, c.List.InnerWidth())
x := 0
for _, cell := range cells {
width := cell.Width()
buf.Set(
c.List.InnerBounds().Min.X+x,
c.List.InnerBounds().Min.Y+y,
cell,
)
x += width
}
}
return buf
}
func (c *Channels) Add() {
}
// GetHeight implements interface termui.GridBufferer
func (c *Channels) GetHeight() int {
return c.List.Block.GetHeight()
@ -52,5 +90,31 @@ 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, slackChan.Name)
c.SlackChannels = append(
c.SlackChannels,
SlackChannel{
ID: slackChan.ID,
Name: slackChan.Name,
},
)
}
}
func (c *Channels) SetSelectedChannel(num int) {
c.SelectedChannel = num
}
func (c *Channels) MoveCursorUp() {
if c.SelectedChannel > 0 {
c.SetSelectedChannel(c.SelectedChannel - 1)
}
}
func (c *Channels) MoveCursorDown() {
if c.SelectedChannel < len(c.List.Items)-1 {
c.SetSelectedChannel(c.SelectedChannel + 1)
}
}
func (c *Channels) NewMessage() {
}

View File

@ -17,12 +17,9 @@ func CreateChat(svc *service.SlackService, inputHeight int) *Chat {
List: termui.NewList(),
}
// TODO: should be SetSelectedChannel
chat.SelectedChannel = svc.GetChannels()[0].ID
chat.List.Height = termui.TermHeight() - inputHeight
chat.List.Overflow = "wrap"
chat.GetMessages(svc)
// chat.GetMessages(svc)
return chat
}
@ -130,10 +127,10 @@ func (c *Chat) SetY(y int) {
c.List.SetY(y)
}
func (c *Chat) GetMessages(svc *service.SlackService) {
func (c *Chat) GetMessages(svc *service.SlackService, channel string) {
// Get the count of message that fit in the pane
count := c.List.InnerBounds().Max.Y - c.List.InnerBounds().Min.Y
messages := svc.GetMessages(c.SelectedChannel, count)
messages := svc.GetMessages(channel, count)
for _, message := range messages {
c.AddMessage(message)

View File

@ -1,6 +1,9 @@
package components
import "github.com/gizak/termui"
import (
"github.com/erroneousboat/slack-term/src/service"
"github.com/gizak/termui"
)
// Input is the definition of and input box
type Input struct {
@ -59,6 +62,10 @@ func (i *Input) SetY(y int) {
i.Par.SetY(y)
}
func (i *Input) SendMessage(svc *service.SlackService, channel string, message string) {
svc.SendMessage(channel, message)
}
// Insert will insert a given key at the place of the current CursorPosition
func (i *Input) Insert(key string) {
if len(i.Par.Text) < i.Par.InnerBounds().Dx()-1 {

View File

@ -2,6 +2,8 @@ package handlers
import (
"fmt"
"strconv"
"time"
"github.com/gizak/termui"
"github.com/nlopes/slack"
@ -26,6 +28,12 @@ func anyKeyHandler(ctx *context.AppContext) func(termui.Event) {
case "q":
actionQuit()
return
case "j":
actionMoveCursorDownChannels(ctx)
return
case "k":
actionMoveCursorUpChannels(ctx)
return
case "i":
actionInsertMode(ctx)
return
@ -70,6 +78,7 @@ func timeHandler(ctx *context.AppContext) func(termui.Event) {
}
}
// TODO: it'll always add the latest message
func incomingMessageHandler(ctx *context.AppContext) {
go func() {
for {
@ -86,12 +95,25 @@ func incomingMessageHandler(ctx *context.AppContext) {
} else {
name = "unknown"
}
m := fmt.Sprintf("[%s] %s", name, ev.Text)
// Parse the time we get from slack which is a Unix time float
floatTime, err := strconv.ParseFloat(ev.Timestamp, 64)
if err != nil {
floatTime = 0.0
}
intTime := int64(floatTime)
m := fmt.Sprintf(
"[%s] <%s> %s",
time.Unix(intTime, 0).Format("15:04"),
name,
ev.Text,
)
// Add message to the selected channel
// fmt.Println(ev.Channel)
if ev.Channel == ctx.View.Chat.SelectedChannel {
if ev.Channel == ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID {
ctx.View.Chat.AddMessage(m)
termui.Render(ctx.View.Chat)
}
}
}
@ -129,8 +151,11 @@ func actionMoveCursorLeft(view *views.View) {
func actionSend(ctx *context.AppContext) {
if !ctx.View.Input.IsEmpty() {
// FIXME
ctx.View.Chat.List.Items = append(ctx.View.Chat.List.Items, ctx.View.Input.Text())
ctx.View.Input.SendMessage(
ctx.Service,
ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID,
ctx.View.Input.Text(),
)
ctx.View.Input.Clear()
ctx.View.Refresh()
}
@ -152,9 +177,12 @@ func actionCommandMode(ctx *context.AppContext) {
termui.Render(ctx.View.Mode)
}
// TODO: get message for channel
func actionGetMessages(ctx *context.AppContext) {
ctx.View.Chat.GetMessages(ctx.Service)
ctx.View.Chat.GetMessages(
ctx.Service,
ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID,
)
termui.Render(ctx.View.Chat)
}
@ -162,3 +190,27 @@ func actionGetChannels(ctx *context.AppContext) {
ctx.View.Channels.GetChannels(ctx.Service)
termui.Render(ctx.View.Channels)
}
func actionMoveCursorUpChannels(ctx *context.AppContext) {
ctx.View.Channels.MoveCursorUp()
ctx.View.Chat.GetMessages(
ctx.Service,
ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID,
)
termui.Render(ctx.View.Channels)
termui.Render(ctx.View.Chat)
}
func actionMoveCursorDownChannels(ctx *context.AppContext) {
ctx.View.Channels.MoveCursorDown()
ctx.View.Chat.GetMessages(
ctx.Service,
ctx.View.Channels.SlackChannels[ctx.View.Channels.SelectedChannel].ID,
)
termui.Render(ctx.View.Channels)
termui.Render(ctx.View.Chat)
}

View File

@ -3,6 +3,8 @@ package service
import (
"fmt"
"log"
"strconv"
"time"
"github.com/nlopes/slack"
)
@ -50,7 +52,13 @@ func (s *SlackService) GetChannels() []Channel {
return chans
}
func (s *SlackService) SendMessage(message string) {}
func (s *SlackService) SendMessage(channel, message string) {
// https://godoc.org/github.com/nlopes/slack#PostMessageParameters
postParams := slack.PostMessageParameters{}
// https://godoc.org/github.com/nlopes/slack#Client.PostMessage
s.Client.PostMessage(channel, message, postParams)
}
func (s *SlackService) GetMessages(channel string, count int) []string {
// https://api.slack.com/methods/channels.history
@ -67,18 +75,41 @@ func (s *SlackService) GetMessages(channel string, count int) []string {
return []string{""}
}
// TODO: this takes a long time, maybe use some dynamic programming
// Here we will construct the messages and format them with a username.
// Because we need to call the API again for an username because we only
// will get an user ID from a message, we will storage user ID's and names
// in a map.
var messages []string
users := make(map[string]string)
for _, message := range history.Messages {
var name string
user, err := s.Client.GetUserInfo(message.User)
if err == nil {
name = user.Name
} else {
name = "unknown"
name, ok := users[message.User]
if !ok {
user, err := s.Client.GetUserInfo(message.User)
if err == nil {
name = user.Name
users[message.User] = user.Name
} else {
name = "unknown"
users[message.User] = user.Name
}
}
msg := fmt.Sprintf("[%s] %s", name, message.Text)
// TODO: refactor this to CreateMessage
// Parse the time we get from slack which is a Unix time float
floatTime, err := strconv.ParseFloat(message.Timestamp, 64)
if err != nil {
floatTime = 0.0
}
intTime := int64(floatTime)
msg := fmt.Sprintf(
"[%s] <%s> %s",
time.Unix(intTime, 0).Format("15:04"),
name,
message.Text,
)
messages = append(messages, msg)
}