189 lines
4.4 KiB
Go
Raw Normal View History

2016-09-25 22:34:02 +02:00
package components
import (
2016-09-30 12:09:03 +02:00
"fmt"
"strings"
2016-09-25 22:34:02 +02:00
"github.com/gizak/termui"
2016-10-01 14:07:42 +02:00
"github.com/erroneousboat/slack-term/src/service"
2016-09-25 22:34:02 +02:00
)
type Channels struct {
2016-09-27 22:05:44 +02:00
List *termui.List
SelectedChannel int
2016-10-01 12:48:15 +02:00
Offset int
CursorPosition int
2016-09-27 22:05:44 +02:00
}
2016-10-01 12:48:15 +02:00
// CreateChannels is the constructor for the Channels component
2016-09-25 22:34:02 +02:00
func CreateChannels(svc *service.SlackService, inputHeight int) *Channels {
channels := &Channels{
List: termui.NewList(),
}
channels.List.BorderLabel = "Channels"
channels.List.Height = termui.TermHeight() - inputHeight
2016-09-28 22:10:04 +02:00
channels.SelectedChannel = 0
2016-10-01 12:48:15 +02:00
channels.Offset = 0
channels.CursorPosition = channels.List.InnerBounds().Min.Y
2016-09-27 22:05:44 +02:00
2016-09-25 22:34:02 +02:00
channels.GetChannels(svc)
return channels
}
// Buffer implements interface termui.Bufferer
func (c *Channels) Buffer() termui.Buffer {
buf := c.List.Buffer()
2016-09-27 22:05:44 +02:00
2016-10-01 12:48:15 +02:00
for i, item := range c.List.Items[c.Offset:] {
y := c.List.InnerBounds().Min.Y + i
if y > c.List.InnerBounds().Max.Y-1 {
break
}
2016-09-27 22:05:44 +02:00
var cells []termui.Cell
2016-10-01 12:48:15 +02:00
if y == c.CursorPosition {
2016-09-27 22:05:44 +02:00
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()
2016-10-01 12:48:15 +02:00
buf.Set(c.List.InnerBounds().Min.X+x, y, cell)
2016-09-27 22:05:44 +02:00
x += width
}
2016-10-01 12:48:15 +02:00
// When not at the end of the pane fill it up empty characters
for x < c.List.InnerBounds().Max.X-1 {
if y == c.CursorPosition {
buf.Set(x+1, y,
termui.Cell{
Ch: ' ', Fg: termui.ColorBlack, Bg: termui.ColorWhite,
},
)
} else {
buf.Set(x+1, y, termui.Cell{Ch: ' '})
}
x++
}
2016-09-27 22:05:44 +02:00
}
2016-09-25 22:34:02 +02:00
return buf
}
// GetHeight implements interface termui.GridBufferer
func (c *Channels) GetHeight() int {
return c.List.Block.GetHeight()
}
// SetWidth implements interface termui.GridBufferer
func (c *Channels) SetWidth(w int) {
c.List.SetWidth(w)
}
// SetX implements interface termui.GridBufferer
func (c *Channels) SetX(x int) {
c.List.SetX(x)
}
// SetY implements interface termui.GridBufferer
func (c *Channels) SetY(y int) {
c.List.SetY(y)
}
2016-09-30 12:09:03 +02:00
// GetChannels will get all available channels from the SlackService
2016-09-25 22:34:02 +02:00
func (c *Channels) GetChannels(svc *service.SlackService) {
for _, slackChan := range svc.GetChannels() {
2016-09-30 12:09:03 +02:00
c.List.Items = append(c.List.Items, fmt.Sprintf(" %s", slackChan.Name))
2016-09-25 22:34:02 +02:00
}
}
2016-09-27 22:05:44 +02:00
2016-09-30 12:09:03 +02:00
// SetSelectedChannel sets the SelectedChannel given the index
func (c *Channels) SetSelectedChannel(index int) {
c.SelectedChannel = index
2016-09-27 22:05:44 +02:00
}
2016-09-30 12:09:03 +02:00
// MoveCursorUp will decrease the SelectedChannel by 1
2016-09-27 22:05:44 +02:00
func (c *Channels) MoveCursorUp() {
if c.SelectedChannel > 0 {
c.SetSelectedChannel(c.SelectedChannel - 1)
2016-10-01 12:48:15 +02:00
c.ScrollUp()
2016-09-30 12:09:03 +02:00
c.ClearNewMessageIndicator()
2016-09-27 22:05:44 +02:00
}
}
2016-09-30 12:09:03 +02:00
// MoveCursorDown will increase the SelectedChannel by 1
2016-09-27 22:05:44 +02:00
func (c *Channels) MoveCursorDown() {
if c.SelectedChannel < len(c.List.Items)-1 {
c.SetSelectedChannel(c.SelectedChannel + 1)
2016-10-01 12:48:15 +02:00
c.ScrollDown()
2016-09-30 12:09:03 +02:00
c.ClearNewMessageIndicator()
2016-09-27 22:05:44 +02:00
}
}
2016-10-01 12:48:15 +02:00
func (c *Channels) ScrollUp() {
if c.CursorPosition == c.List.InnerBounds().Min.Y {
if c.Offset > 0 {
c.Offset--
}
} else {
c.CursorPosition--
}
}
func (c *Channels) ScrollDown() {
if c.CursorPosition == c.List.InnerBounds().Max.Y-1 {
if c.Offset < len(c.List.Items)-1 {
c.Offset++
}
} else {
c.CursorPosition++
}
}
2016-09-30 12:09:03 +02:00
// NewMessage will be called when a new message arrives and will
// render an asterisk in front of the channel name
2016-09-30 23:52:26 +02:00
func (c *Channels) NewMessage(svc *service.SlackService, channelID string) {
2016-09-30 12:09:03 +02:00
var index int
2016-10-01 12:48:15 +02:00
// Get the correct Channel from svc.Channels
2016-09-30 23:52:26 +02:00
for i, channel := range svc.Channels {
2016-09-30 12:09:03 +02:00
if channelID == channel.ID {
index = i
break
}
}
2016-09-30 16:36:41 +02:00
if !strings.Contains(c.List.Items[index], "*") {
2016-10-01 12:48:15 +02:00
// The order of svc.Channels relates to the order of
2016-09-30 16:36:41 +02:00
// List.Items, index will be the index of the channel
c.List.Items[index] = fmt.Sprintf("* %s", strings.TrimSpace(c.List.Items[index]))
}
2016-09-30 12:09:03 +02:00
// Play terminal bell sound
fmt.Print("\a")
}
// ClearNewMessageIndicator will remove the asterisk in front of a channel that
// received a new message. This will happen as one will move up or down the
// cursor for Channels
func (c *Channels) ClearNewMessageIndicator() {
channelName := strings.Split(c.List.Items[c.SelectedChannel], "* ")
if len(channelName) > 1 {
c.List.Items[c.SelectedChannel] = fmt.Sprintf(" %s", channelName[1])
} else {
c.List.Items[c.SelectedChannel] = channelName[0]
}
2016-09-27 22:05:44 +02:00
}