2016-09-11 17:55:19 +02:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/gizak/termui"
|
2016-10-05 21:20:46 +02:00
|
|
|
"github.com/nlopes/slack"
|
2016-10-15 20:55:05 +02:00
|
|
|
termbox "github.com/nsf/termbox-go"
|
2016-09-11 17:55:19 +02:00
|
|
|
|
2016-10-19 09:08:31 +02:00
|
|
|
"github.com/erroneousboat/slack-term/context"
|
|
|
|
"github.com/erroneousboat/slack-term/views"
|
2016-09-11 17:55:19 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func RegisterEventHandlers(ctx *context.AppContext) {
|
2016-10-15 20:55:05 +02:00
|
|
|
anyKeyHandler(ctx)
|
2016-09-27 17:12:38 +02:00
|
|
|
incomingMessageHandler(ctx)
|
2016-10-15 20:55:05 +02:00
|
|
|
termui.Handle("/sys/wnd/resize", resizeHandler(ctx))
|
2016-09-11 17:55:19 +02:00
|
|
|
}
|
|
|
|
|
2016-10-15 20:55:05 +02:00
|
|
|
func anyKeyHandler(ctx *context.AppContext) {
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
ev := termbox.PollEvent()
|
|
|
|
|
|
|
|
if ev.Type == termbox.EventKey {
|
|
|
|
if ctx.Mode == context.CommandMode {
|
|
|
|
switch ev.Key {
|
|
|
|
case termbox.KeyPgup:
|
|
|
|
actionScrollUpChat(ctx)
|
|
|
|
case termbox.KeyCtrlB:
|
|
|
|
actionScrollUpChat(ctx)
|
|
|
|
case termbox.KeyCtrlU:
|
|
|
|
actionScrollUpChat(ctx)
|
|
|
|
case termbox.KeyPgdn:
|
|
|
|
actionScrollDownChat(ctx)
|
|
|
|
case termbox.KeyCtrlF:
|
|
|
|
actionScrollDownChat(ctx)
|
|
|
|
case termbox.KeyCtrlD:
|
|
|
|
actionScrollDownChat(ctx)
|
|
|
|
default:
|
|
|
|
switch ev.Ch {
|
|
|
|
case 'q':
|
|
|
|
actionQuit()
|
|
|
|
case 'j':
|
|
|
|
actionMoveCursorDownChannels(ctx)
|
|
|
|
case 'k':
|
|
|
|
actionMoveCursorUpChannels(ctx)
|
2016-10-18 21:11:29 +02:00
|
|
|
case 'g':
|
|
|
|
actionMoveCursorTopChannels(ctx)
|
|
|
|
case 'G':
|
|
|
|
actionMoveCursorBottomChannels(ctx)
|
2016-10-15 20:55:05 +02:00
|
|
|
case 'i':
|
|
|
|
actionInsertMode(ctx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ctx.Mode == context.InsertMode {
|
|
|
|
switch ev.Key {
|
|
|
|
case termbox.KeyEsc:
|
|
|
|
actionCommandMode(ctx)
|
|
|
|
case termbox.KeyEnter:
|
|
|
|
actionSend(ctx)
|
|
|
|
case termbox.KeySpace:
|
2016-10-21 21:23:25 +02:00
|
|
|
actionInput(ctx.View, ' ')
|
2016-10-15 20:55:05 +02:00
|
|
|
case termbox.KeyBackspace, termbox.KeyBackspace2:
|
|
|
|
actionBackSpace(ctx.View)
|
|
|
|
case termbox.KeyDelete:
|
|
|
|
actionDelete(ctx.View)
|
|
|
|
case termbox.KeyArrowRight:
|
|
|
|
actionMoveCursorRight(ctx.View)
|
|
|
|
case termbox.KeyArrowLeft:
|
|
|
|
actionMoveCursorLeft(ctx.View)
|
|
|
|
default:
|
2016-10-21 21:23:25 +02:00
|
|
|
actionInput(ctx.View, ev.Ch)
|
2016-10-15 20:55:05 +02:00
|
|
|
}
|
|
|
|
}
|
2016-09-11 17:55:19 +02:00
|
|
|
}
|
|
|
|
}
|
2016-10-15 20:55:05 +02:00
|
|
|
}()
|
2016-09-11 17:55:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func resizeHandler(ctx *context.AppContext) func(termui.Event) {
|
|
|
|
return func(e termui.Event) {
|
|
|
|
actionResize(ctx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-27 17:12:38 +02:00
|
|
|
func incomingMessageHandler(ctx *context.AppContext) {
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case msg := <-ctx.Service.RTM.IncomingEvents:
|
|
|
|
switch ev := msg.Data.(type) {
|
|
|
|
case *slack.MessageEvent:
|
|
|
|
|
2016-09-29 21:19:09 +02:00
|
|
|
// Construct message
|
2016-10-09 14:19:28 +02:00
|
|
|
msg := ctx.Service.CreateMessageFromMessageEvent(ev)
|
2016-09-27 17:12:38 +02:00
|
|
|
|
|
|
|
// Add message to the selected channel
|
2016-09-30 23:52:26 +02:00
|
|
|
if ev.Channel == ctx.Service.Channels[ctx.View.Channels.SelectedChannel].ID {
|
2016-10-11 18:50:25 +02:00
|
|
|
|
|
|
|
// reverse order of messages, mainly done
|
|
|
|
// when attachments are added to message
|
|
|
|
for i := len(msg) - 1; i >= 0; i-- {
|
|
|
|
ctx.View.Chat.AddMessage(msg[i])
|
2016-10-09 14:19:28 +02:00
|
|
|
}
|
2016-10-11 18:50:25 +02:00
|
|
|
|
2016-09-27 22:05:44 +02:00
|
|
|
termui.Render(ctx.View.Chat)
|
2016-09-30 16:36:41 +02:00
|
|
|
|
2016-10-01 12:48:15 +02:00
|
|
|
// TODO: set Chat.Offset to 0, to automatically scroll
|
|
|
|
// down?
|
2016-09-27 17:12:38 +02:00
|
|
|
}
|
2016-09-30 12:09:03 +02:00
|
|
|
|
2016-10-01 12:48:15 +02:00
|
|
|
// Set new message indicator for channel, I'm leaving
|
|
|
|
// this here because I also want to be notified when
|
|
|
|
// I'm currently in a channel but not in the terminal
|
2016-10-05 21:57:43 +02:00
|
|
|
// window (tmux). But only create a notification when
|
|
|
|
// it comes from someone else but the current user.
|
|
|
|
if ev.User != ctx.Service.CurrentUserID {
|
|
|
|
actionNewMessage(ctx, ev.Channel)
|
|
|
|
}
|
2016-09-27 17:12:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2016-09-11 17:55:19 +02:00
|
|
|
// FIXME: resize only seems to work for width and resizing it too small
|
|
|
|
// will cause termui to panic
|
|
|
|
func actionResize(ctx *context.AppContext) {
|
|
|
|
termui.Body.Width = termui.TermWidth()
|
|
|
|
termui.Body.Align()
|
|
|
|
termui.Render(termui.Body)
|
|
|
|
}
|
|
|
|
|
2016-10-21 21:23:25 +02:00
|
|
|
func actionInput(view *views.View, key rune) {
|
2016-09-11 17:55:19 +02:00
|
|
|
view.Input.Insert(key)
|
|
|
|
termui.Render(view.Input)
|
|
|
|
}
|
|
|
|
|
2016-10-27 18:51:06 +02:00
|
|
|
func actionBackSpace(ctx *context.AppContext) {
|
|
|
|
ctx.View.Input.Backspace()
|
|
|
|
termui.Render(ctx.View.Input)
|
2016-10-09 14:59:48 +02:00
|
|
|
}
|
|
|
|
|
2016-10-27 18:51:06 +02:00
|
|
|
func actionDelete(ctx *context.AppContext) {
|
|
|
|
ctx.View.Input.Delete()
|
|
|
|
termui.Render(ctx.View.Input)
|
2016-09-11 17:55:19 +02:00
|
|
|
}
|
|
|
|
|
2016-10-27 18:51:06 +02:00
|
|
|
func actionMoveCursorRight(ctx *context.AppContext) {
|
|
|
|
ctx.View.Input.MoveCursorRight()
|
|
|
|
termui.Render(ctx.View.Input)
|
2016-09-11 17:55:19 +02:00
|
|
|
}
|
|
|
|
|
2016-10-27 18:51:06 +02:00
|
|
|
func actionMoveCursorLeft(ctx *context.AppContext) {
|
|
|
|
ctx.View.Input.MoveCursorLeft()
|
|
|
|
termui.Render(ctx.View.Input)
|
2016-09-11 17:55:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func actionSend(ctx *context.AppContext) {
|
|
|
|
if !ctx.View.Input.IsEmpty() {
|
2016-10-14 17:04:22 +02:00
|
|
|
|
|
|
|
// Clear message before sending, to combat
|
|
|
|
// quick succession of actionSend
|
2016-10-21 21:23:25 +02:00
|
|
|
message := ctx.View.Input.GetText()
|
2016-10-14 17:04:22 +02:00
|
|
|
ctx.View.Input.Clear()
|
|
|
|
ctx.View.Refresh()
|
|
|
|
|
2016-09-27 22:05:44 +02:00
|
|
|
ctx.View.Input.SendMessage(
|
|
|
|
ctx.Service,
|
2016-09-30 23:52:26 +02:00
|
|
|
ctx.Service.Channels[ctx.View.Channels.SelectedChannel].ID,
|
2016-10-14 17:04:22 +02:00
|
|
|
message,
|
2016-09-27 22:05:44 +02:00
|
|
|
)
|
2016-09-11 17:55:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-27 18:51:06 +02:00
|
|
|
func actionQuit(*context.AppContext) {
|
2016-09-11 17:55:19 +02:00
|
|
|
termui.StopLoop()
|
|
|
|
}
|
|
|
|
|
|
|
|
func actionInsertMode(ctx *context.AppContext) {
|
|
|
|
ctx.Mode = context.InsertMode
|
2016-09-25 22:34:02 +02:00
|
|
|
ctx.View.Mode.Par.Text = "INSERT"
|
2016-09-11 17:55:19 +02:00
|
|
|
termui.Render(ctx.View.Mode)
|
|
|
|
}
|
|
|
|
|
|
|
|
func actionCommandMode(ctx *context.AppContext) {
|
|
|
|
ctx.Mode = context.CommandMode
|
2016-09-25 22:34:02 +02:00
|
|
|
ctx.View.Mode.Par.Text = "NORMAL"
|
2016-09-11 17:55:19 +02:00
|
|
|
termui.Render(ctx.View.Mode)
|
|
|
|
}
|
2016-09-25 22:34:02 +02:00
|
|
|
|
|
|
|
func actionGetMessages(ctx *context.AppContext) {
|
2016-09-27 22:05:44 +02:00
|
|
|
ctx.View.Chat.GetMessages(
|
|
|
|
ctx.Service,
|
2016-09-30 23:52:26 +02:00
|
|
|
ctx.Service.Channels[ctx.View.Channels.SelectedChannel],
|
2016-09-27 22:05:44 +02:00
|
|
|
)
|
|
|
|
|
2016-09-25 22:34:02 +02:00
|
|
|
termui.Render(ctx.View.Chat)
|
|
|
|
}
|
|
|
|
|
|
|
|
func actionGetChannels(ctx *context.AppContext) {
|
|
|
|
ctx.View.Channels.GetChannels(ctx.Service)
|
|
|
|
termui.Render(ctx.View.Channels)
|
|
|
|
}
|
2016-09-27 22:05:44 +02:00
|
|
|
|
|
|
|
func actionMoveCursorUpChannels(ctx *context.AppContext) {
|
|
|
|
ctx.View.Channels.MoveCursorUp()
|
2016-09-29 19:09:30 +02:00
|
|
|
actionChangeChannel(ctx)
|
2016-09-27 22:05:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func actionMoveCursorDownChannels(ctx *context.AppContext) {
|
|
|
|
ctx.View.Channels.MoveCursorDown()
|
2016-09-29 19:09:30 +02:00
|
|
|
actionChangeChannel(ctx)
|
|
|
|
}
|
|
|
|
|
2016-10-18 21:11:29 +02:00
|
|
|
func actionMoveCursorTopChannels(ctx *context.AppContext) {
|
|
|
|
ctx.View.Channels.MoveCursorTop()
|
|
|
|
actionChangeChannel(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func actionMoveCursorBottomChannels(ctx *context.AppContext) {
|
|
|
|
ctx.View.Channels.MoveCursorBottom()
|
|
|
|
actionChangeChannel(ctx)
|
|
|
|
}
|
|
|
|
|
2016-09-29 19:09:30 +02:00
|
|
|
func actionChangeChannel(ctx *context.AppContext) {
|
|
|
|
// Clear messages from Chat pane
|
|
|
|
ctx.View.Chat.ClearMessages()
|
2016-09-27 22:05:44 +02:00
|
|
|
|
2016-09-29 19:09:30 +02:00
|
|
|
// Get message for the new channel
|
2016-09-27 22:05:44 +02:00
|
|
|
ctx.View.Chat.GetMessages(
|
|
|
|
ctx.Service,
|
2016-09-30 23:52:26 +02:00
|
|
|
ctx.Service.SlackChannels[ctx.View.Channels.SelectedChannel],
|
2016-09-27 22:05:44 +02:00
|
|
|
)
|
|
|
|
|
2016-09-29 19:09:30 +02:00
|
|
|
// Set channel name for the Chat pane
|
2016-09-28 22:10:04 +02:00
|
|
|
ctx.View.Chat.SetBorderLabel(
|
2016-09-30 23:52:26 +02:00
|
|
|
ctx.Service.Channels[ctx.View.Channels.SelectedChannel].Name,
|
2016-09-28 22:10:04 +02:00
|
|
|
)
|
|
|
|
|
2016-09-27 22:05:44 +02:00
|
|
|
termui.Render(ctx.View.Channels)
|
|
|
|
termui.Render(ctx.View.Chat)
|
|
|
|
}
|
2016-09-30 12:09:03 +02:00
|
|
|
|
|
|
|
func actionNewMessage(ctx *context.AppContext, channelID string) {
|
2016-09-30 23:52:26 +02:00
|
|
|
ctx.View.Channels.NewMessage(ctx.Service, channelID)
|
2016-09-30 12:09:03 +02:00
|
|
|
termui.Render(ctx.View.Channels)
|
|
|
|
}
|
2016-09-30 16:36:41 +02:00
|
|
|
|
|
|
|
func actionScrollUpChat(ctx *context.AppContext) {
|
|
|
|
ctx.View.Chat.ScrollUp()
|
|
|
|
termui.Render(ctx.View.Chat)
|
|
|
|
}
|
|
|
|
|
|
|
|
func actionScrollDownChat(ctx *context.AppContext) {
|
|
|
|
ctx.View.Chat.ScrollDown()
|
|
|
|
termui.Render(ctx.View.Chat)
|
|
|
|
}
|