From d45103932c9b14e4d1f75bc50b384f7195e54b9d Mon Sep 17 00:00:00 2001 From: erroneousboat Date: Fri, 1 Dec 2017 16:35:03 +0100 Subject: [PATCH] Fix channel scrolling --- components/channels.go | 3 ++- components/chat.go | 1 + components/debug.go | 7 +++++ context/context.go | 5 +++- handlers/event.go | 20 +++++++++++--- service/slack.go | 61 +++++++++++++++++++++++++----------------- vendor/vendor.json | 16 +++++------ views/chat.go | 2 ++ 8 files changed, 78 insertions(+), 37 deletions(-) diff --git a/components/channels.go b/components/channels.go index a479ce9..1bf1458 100644 --- a/components/channels.go +++ b/components/channels.go @@ -15,7 +15,7 @@ const ( IconChannel = "#" IconGroup = "☰" IconIM = "●" - IconNotification = "🞷" + IconNotification = "*" PresenceAway = "away" PresenceActive = "active" @@ -118,6 +118,7 @@ func (c *Channels) SetSelectedChannel(index int) { c.SelectedChannel = index } +// TODO: documentation func (c *Channels) GetSelectedChannel() string { return c.Items[c.SelectedChannel] } diff --git a/components/chat.go b/components/chat.go index 216d249..50c4743 100644 --- a/components/chat.go +++ b/components/chat.go @@ -47,6 +47,7 @@ func (c *Chat) Layout(g *gocui.Gui) error { return nil } +// FIXME: maybe not necessary func (c *Chat) Refresh() { for _, msg := range c.Items { fmt.Fprintln(c.View, msg) diff --git a/components/debug.go b/components/debug.go index 46d3972..e53f479 100644 --- a/components/debug.go +++ b/components/debug.go @@ -6,6 +6,12 @@ import ( "github.com/erroneousboat/gocui" ) +// Debug component gives the possibility to print +// debugging statements in the GUI. +// +// Usage: +// +// ctx.View.Debug.SetText("debugging statement") type Debug struct { Component View *gocui.View @@ -42,6 +48,7 @@ func (d *Debug) Layout(g *gocui.Gui) error { return nil } +// SetText will set the text of the Debug component func (d *Debug) SetText(text string) { fmt.Fprintln(d.View, text) } diff --git a/context/context.go b/context/context.go index 2a6309b..95f1849 100644 --- a/context/context.go +++ b/context/context.go @@ -34,7 +34,10 @@ func CreateAppContext(flgConfig string) (*AppContext, error) { } // Create Service - svc := service.NewSlackService(config.SlackToken) + svc, err := service.NewSlackService(config.SlackToken) + if err != nil { + return nil, err + } // Create ChatView view := views.CreateChatView(svc) diff --git a/handlers/event.go b/handlers/event.go index 0989d9a..acaac81 100644 --- a/handlers/event.go +++ b/handlers/event.go @@ -50,7 +50,6 @@ func eventHandler(ctx *context.AppContext) { }() for { - ctx.View.GUI.Flush() select { @@ -242,6 +241,9 @@ func actionQuit(ctx *context.AppContext) { // termui.Render(ctx.View.Chat) // } +// actionMoveCursorUpChannels will execute the actionChangeChannel +// function. A timer is implemented to support fast scrolling through +// the list without executing the actionChangeChannel event. func actionMoveCursorUpChannels(ctx *context.AppContext) { go func() { if timer != nil { @@ -253,10 +255,17 @@ func actionMoveCursorUpChannels(ctx *context.AppContext) { timer = time.NewTimer(time.Second / 4) <-timer.C + // Only actually change channel when timer expired actionChangeChannel(ctx) + + // Flush, because this is run in a goroutine + ctx.View.GUI.Flush() }() } +// actionMoveCursorDownChannels will execute the actionChangeChannel +// function. A timer is implemented to support fast scrolling through +// the list without executing the actionChangeChannel event. func actionMoveCursorDownChannels(ctx *context.AppContext) { go func() { if timer != nil { @@ -268,7 +277,11 @@ func actionMoveCursorDownChannels(ctx *context.AppContext) { timer = time.NewTimer(time.Second / 4) <-timer.C + // Only actually change channel when timer expired actionChangeChannel(ctx) + + // Flush, because this is run in a goroutine + ctx.View.GUI.Flush() }() } @@ -297,16 +310,17 @@ func actionChangeChannel(ctx *context.AppContext) { // Set messages for the new channel ctx.View.Chat.SetMessages(messages) + // TODO // Set channel name for the Chat pane // ctx.View.Chat.SetBorderLabel( // ctx.Service.Channels[ctx.View.Channels.SelectedChannel], // ) + // TODO // Set read mark // ctx.View.Channels.SetReadMark(ctx.Service) - ctx.View.Debug.SetText("hello, world") - + // FIXME: maybe not necessary // Refresh Chat component ctx.View.Chat.Refresh() } diff --git a/service/slack.go b/service/slack.go index 853c508..08c179a 100644 --- a/service/slack.go +++ b/service/slack.go @@ -1,6 +1,7 @@ package service import ( + "errors" "fmt" "log" "regexp" @@ -20,12 +21,13 @@ const ( ) type SlackService struct { - Client *slack.Client - RTM *slack.RTM - SlackChannels []interface{} - Channels []Channel - UserCache map[string]string - CurrentUserID string + Client *slack.Client + RTM *slack.RTM + SlackChannels []interface{} + Channels []Channel + UserCache map[string]string + CurrentUserID string + CurrentUsername string } type Channel struct { @@ -39,7 +41,7 @@ type Channel struct { // NewSlackService is the constructor for the SlackService and will initialize // the RTM and a Client -func NewSlackService(token string) *SlackService { +func NewSlackService(token string) (*SlackService, error) { svc := &SlackService{ Client: slack.New(token), UserCache: make(map[string]string), @@ -50,7 +52,7 @@ func NewSlackService(token string) *SlackService { // arrives authTest, err := svc.Client.AuthTest() if err != nil { - log.Fatal("ERROR: not able to authorize client, check your connection and/or slack-token") + return nil, errors.New("not able to authorize client, check your connection and/or slack-token") } svc.CurrentUserID = authTest.UserID @@ -68,7 +70,14 @@ func NewSlackService(token string) *SlackService { } } - return svc + // Get name of current user + currentUser, err := svc.Client.GetUserInfo(svc.CurrentUserID) + if err != nil { + svc.CurrentUsername = "slack-term" + } + svc.CurrentUsername = currentUser.Name + + return svc, nil } // GetChannels will retrieve all available channels, groups, and im channels. @@ -84,16 +93,18 @@ func (s *SlackService) GetChannels() []Channel { chans = append(chans, Channel{}) } for _, chn := range slackChans { - s.SlackChannels = append(s.SlackChannels, chn) - chans = append( - chans, Channel{ - ID: chn.ID, - Name: chn.Name, - Topic: chn.Topic.Value, - Type: ChannelTypeChannel, - UserID: "", - }, - ) + if chn.IsMember { + s.SlackChannels = append(s.SlackChannels, chn) + chans = append( + chans, Channel{ + ID: chn.ID, + Name: chn.Name, + Topic: chn.Topic.Value, + Type: ChannelTypeChannel, + UserID: "", + }, + ) + } } // Groups @@ -192,7 +203,8 @@ func (s *SlackService) SetChannelReadMark(channel interface{}) { func (s *SlackService) SendMessage(channel string, message string) { // https://godoc.org/github.com/nlopes/slack#PostMessageParameters postParams := slack.PostMessageParameters{ - AsUser: true, + AsUser: true, + Username: s.CurrentUsername, } // https://godoc.org/github.com/nlopes/slack#Client.PostMessage @@ -401,14 +413,15 @@ func parseMessage(s *SlackService, msg string) string { // <@U12345> func parseMentions(s *SlackService, msg string) string { r := regexp.MustCompile(`\<@(\w+\|*\w+)\>`) - rs := r.FindStringSubmatch(msg) - if len(rs) < 1 { - return msg - } return r.ReplaceAllStringFunc( msg, func(str string) string { var userID string + rs := r.FindStringSubmatch(str) + if len(rs) < 1 { + return str + } + split := strings.Split(rs[1], "|") if len(split) > 0 { userID = split[0] diff --git a/vendor/vendor.json b/vendor/vendor.json index 94edd0e..1b6f5b5 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -15,10 +15,10 @@ "revisionTime": "2017-05-02T14:12:00Z" }, { - "checksumSHA1": "7hln62oZPZmyqEmgXaybf9WxQ7A=", + "checksumSHA1": "zpFCi2nWiwR5F2INAJOvQqsj7lY=", "path": "github.com/maruel/panicparse/stack", - "revision": "868abbf1ebac0fb2760cd9a410a5bd2f5afb2f76", - "revisionTime": "2017-07-16T23:31:26Z" + "revision": "766956aceb8ff49664065ae50bef0ae8a0a83ec4", + "revisionTime": "2017-11-29T15:16:18Z" }, { "checksumSHA1": "cJE7dphDlam/i7PhnsyosNWtbd4=", @@ -39,16 +39,16 @@ "revisionTime": "2017-07-25T12:17:30Z" }, { - "checksumSHA1": "GY8G0wn9l4zVTQW9POZCdH+iftM=", + "checksumSHA1": "Zi8hWUMkKtii1fc6YaGgoYAssIw=", "path": "github.com/nsf/termbox-go", - "revision": "d51f2f6d6ccb97dd83ed04ae2f79c34234851f39", - "revisionTime": "2017-09-30T11:41:06Z" + "revision": "aa4a75b1c20a2b03751b1a9f7e41d58bd6f71c43", + "revisionTime": "2017-11-04T16:23:16Z" }, { "checksumSHA1": "7EZyXN0EmZLgGxZxK01IJua4c8o=", "path": "golang.org/x/net/websocket", - "revision": "f5079bd7f6f74e23c4d65efa0f4ce14cbd6a3c0f", - "revisionTime": "2017-07-19T21:11:51Z" + "revision": "a8b9294777976932365dabb6640cf1468d95c70f", + "revisionTime": "2017-11-29T19:21:16Z" } ], "rootPath": "github.com/erroneousboat/slack-term" diff --git a/views/chat.go b/views/chat.go index 0afe5be..adb6136 100644 --- a/views/chat.go +++ b/views/chat.go @@ -73,6 +73,8 @@ func CreateChatView(svc *service.SlackService) *View { // Initialize keybindings // initKeyBindings(view) + view.GUI.Flush() + return view }