Implement configuration for desktop notifications

This commit is contained in:
erroneousboat 2018-04-06 13:42:12 +02:00
parent 50114764a7
commit 56000c4f3e
4 changed files with 71 additions and 24 deletions

View File

@ -44,9 +44,10 @@ Setup
// OPTIONAL: set the width of the sidebar (between 1 and 11), default is 1
"sidebar_width": 1,
// OPTIONAL: turn on desktop notifications for all incoming messages,
default is false
"notify": false,
// OPTIONAL: turn on desktop notifications for all incoming messages, set
// the value as: "all", and for only mentions and im messages set the
// value as: "mention", default is turned off: ""
"notify": "",
// OPTIONAL: define custom key mappings, defaults are:
"key_map": {

View File

@ -9,10 +9,15 @@ import (
"github.com/erroneousboat/termui"
)
const (
NotifyAll = "all"
NotifyMention = "mention"
)
// Config is the definition of a Config struct
type Config struct {
SlackToken string `json:"slack_token"`
Notify bool `json:"notify"`
Notify string `json:"notify"`
SidebarWidth int `json:"sidebar_width"`
MainWidth int `json:"-"`
KeyMap map[string]keyMapping `json:"key_map"`
@ -44,6 +49,13 @@ func NewConfig(filepath string) (*Config, error) {
cfg.MainWidth = 12 - cfg.SidebarWidth
switch cfg.Notify {
case NotifyAll, NotifyMention, "":
break
default:
return &cfg, fmt.Errorf("unsupported setting for notify: %s", cfg.Notify)
}
termui.ColorMap = map[string]termui.Attribute{
"fg": termui.StringToAttribute(cfg.Theme.View.Fg),
"bg": termui.StringToAttribute(cfg.Theme.View.Bg),
@ -60,7 +72,7 @@ func getDefaultConfig() Config {
return Config{
SidebarWidth: 1,
MainWidth: 11,
Notify: true,
Notify: "",
KeyMap: map[string]keyMapping{
"command": {
"i": "mode-insert",

View File

@ -11,6 +11,7 @@ import (
"github.com/nlopes/slack"
termbox "github.com/nsf/termbox-go"
"github.com/erroneousboat/slack-term/config"
"github.com/erroneousboat/slack-term/context"
"github.com/erroneousboat/slack-term/views"
)
@ -136,7 +137,7 @@ func messageHandler(ctx *context.AppContext) {
// 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)
actionNewMessage(ctx, ev)
}
case *slack.PresenceChangeEvent:
actionSetPresence(ctx, ev.User, ev.Presence)
@ -400,8 +401,10 @@ func actionChangeChannel(ctx *context.AppContext) {
termui.Render(ctx.View.Chat)
}
func actionNewMessage(ctx *context.AppContext, channelID string) {
ctx.Service.MarkAsUnread(channelID)
// actionNewMessage will set the new message indicator for a channel, and
// if configured will also display a desktop notification
func actionNewMessage(ctx *context.AppContext, ev *slack.MessageEvent) {
ctx.Service.MarkAsUnread(ev.Channel)
ctx.View.Channels.SetChannels(ctx.Service.ChannelsToString())
termui.Render(ctx.View.Channels)
@ -409,22 +412,12 @@ func actionNewMessage(ctx *context.AppContext, channelID string) {
fmt.Print("\a")
// Desktop notification
if ctx.Config.Notify {
go func() {
if notifyTimer != nil {
notifyTimer.Stop()
}
notifyTimer = time.NewTimer(time.Second * 2)
<-notifyTimer.C
// Only actually notify when time expires
ctx.Notify.Push(
"slack-term",
ctx.Service.CreateNotifyMessage(channelID), "",
notificator.UR_NORMAL,
)
}()
if ctx.Config.Notify == config.NotifyMention {
if ctx.Service.CheckNotifyMention(ev) {
createNotifyMessage(ctx, ev)
}
} else if ctx.Config.Notify == config.NotifyAll {
createNotifyMessage(ctx, ev)
}
}
@ -498,3 +491,21 @@ func getKeyString(e termbox.Event) string {
ek = pre + mod + k
return ek
}
func createNotifyMessage(ctx *context.AppContext, ev *slack.MessageEvent) {
go func() {
if notifyTimer != nil {
notifyTimer.Stop()
}
notifyTimer = time.NewTimer(time.Second * 2)
<-notifyTimer.C
// Only actually notify when time expires
ctx.Notify.Push(
"slack-term",
ctx.Service.CreateNotifyMessage(ev.Channel), "",
notificator.UR_NORMAL,
)
}()
}

View File

@ -532,6 +532,29 @@ func (s *SlackService) CreateMessageFromMessageEvent(message *slack.MessageEvent
return msgs, nil
}
// CheckNotifyMention check if the message event is either contains a
// mention or is posted on an IM channel
func (s *SlackService) CheckNotifyMention(ev *slack.MessageEvent) bool {
channel := s.Channels[s.FindChannel(ev.Channel)]
switch channel.Type {
case ChannelTypeIM:
return true
}
// Mentions have the following format:
// <@U12345|erroneousboat>
// <@U12345>
r := regexp.MustCompile(`\<@(\w+\|*\w+)\>`)
matches := r.FindAllString(ev.Text, -1)
for _, match := range matches {
if strings.Contains(match, s.CurrentUserID) {
return true
}
}
return false
}
func (s *SlackService) CreateNotifyMessage(channelID string) string {
channel := s.Channels[s.FindChannel(channelID)]