erroneousboat-slack-term/handlers/event.go

291 lines
7.3 KiB
Go
Raw Normal View History

2016-09-11 17:55:19 +02:00
package handlers
import (
"github.com/gizak/termui"
"github.com/nlopes/slack"
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) {
anyKeyHandler(ctx)
2016-09-27 17:12:38 +02:00
incomingMessageHandler(ctx)
termui.Handle("/sys/wnd/resize", resizeHandler(ctx))
2016-09-11 17:55:19 +02:00
}
var keyMapping = map[termbox.Key]string{
termbox.KeyPgup: "pg-up",
termbox.KeyCtrlB: "ctrl-b",
termbox.KeyCtrlU: "ctrl-u",
termbox.KeyPgdn: "pg-dn",
termbox.KeyCtrlF: "ctrl-f",
termbox.KeyCtrlD: "ctrl-d",
termbox.KeyEsc: "esc",
termbox.KeyEnter: "enter",
termbox.KeyBackspace: "backspace",
termbox.KeyBackspace2: "backspace",
termbox.KeyDelete: "del",
termbox.KeyArrowRight: "right",
termbox.KeyArrowLeft: "left",
}
var actionMap = map[string]func(*context.AppContext){
"backspace": actionBackSpace,
"delete": actionDelete,
"cursor-right": actionMoveCursorRight,
"cursor-left": actionMoveCursorLeft,
"send": actionSend,
"quit": actionQuit,
"insert": actionInsertMode,
"normal": actionCommandMode,
"channel-up": actionMoveCursorUpChannels,
"channel-down": actionMoveCursorDownChannels,
"channel-top": actionMoveCursorTopChannels,
"channel-bottom": actionMoveCursorBottomChannels,
"chat-up": actionScrollUpChat,
"chat-down": actionScrollDownChat,
}
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)
case 'g':
actionMoveCursorTopChannels(ctx)
case 'G':
actionMoveCursorBottomChannels(ctx)
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, ' ')
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-09-11 17:55:19 +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
// 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)
}
func actionBackSpace(ctx *context.AppContext) {
ctx.View.Input.Backspace()
termui.Render(ctx.View.Input)
2016-10-09 14:59:48 +02:00
}
func actionDelete(ctx *context.AppContext) {
ctx.View.Input.Delete()
termui.Render(ctx.View.Input)
2016-09-11 17:55:19 +02:00
}
func actionMoveCursorRight(ctx *context.AppContext) {
ctx.View.Input.MoveCursorRight()
termui.Render(ctx.View.Input)
2016-09-11 17:55:19 +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() {
// Clear message before sending, to combat
// quick succession of actionSend
2016-10-21 21:23:25 +02:00
message := ctx.View.Input.GetText()
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,
message,
2016-09-27 22:05:44 +02:00
)
2016-09-11 17:55:19 +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)
}
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)
}