Merge branch 'color-messages' into v0.3.0
* color-messages: Implement theming for several components Start with theming functionality Start with adding colors for messages
This commit is contained in:
commit
f0df903d9d
@ -1,6 +1,8 @@
|
|||||||
package components
|
package components
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/erroneousboat/termui"
|
"github.com/erroneousboat/termui"
|
||||||
@ -13,8 +15,82 @@ const (
|
|||||||
IconGroup = "☰"
|
IconGroup = "☰"
|
||||||
IconIM = "●"
|
IconIM = "●"
|
||||||
IconNotification = "*"
|
IconNotification = "*"
|
||||||
|
|
||||||
|
PresenceAway = "away"
|
||||||
|
PresenceActive = "active"
|
||||||
|
|
||||||
|
ChannelTypeChannel = "channel"
|
||||||
|
ChannelTypeGroup = "group"
|
||||||
|
ChannelTypeIM = "im"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ChannelItem struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
Topic string
|
||||||
|
Type string
|
||||||
|
UserID string
|
||||||
|
Presence string
|
||||||
|
Notification bool
|
||||||
|
|
||||||
|
StylePrefix string
|
||||||
|
StyleIcon string
|
||||||
|
StyleText string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString will set the label of the channel, how it will be
|
||||||
|
// displayed on screen. Based on the type, different icons are
|
||||||
|
// shown, as well as an optional notification icon.
|
||||||
|
func (c ChannelItem) ToString() string {
|
||||||
|
var prefix string
|
||||||
|
if c.Notification {
|
||||||
|
prefix = IconNotification
|
||||||
|
} else {
|
||||||
|
prefix = " "
|
||||||
|
}
|
||||||
|
|
||||||
|
var icon string
|
||||||
|
switch c.Type {
|
||||||
|
case ChannelTypeChannel:
|
||||||
|
icon = IconChannel
|
||||||
|
case ChannelTypeGroup:
|
||||||
|
icon = IconGroup
|
||||||
|
case ChannelTypeIM:
|
||||||
|
switch c.Presence {
|
||||||
|
case PresenceActive:
|
||||||
|
icon = IconOnline
|
||||||
|
case PresenceAway:
|
||||||
|
icon = IconOffline
|
||||||
|
default:
|
||||||
|
icon = IconIM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label := fmt.Sprintf(
|
||||||
|
"[%s](%s) [%s](%s) [%s](%s)",
|
||||||
|
prefix, c.StylePrefix,
|
||||||
|
icon, c.StyleIcon,
|
||||||
|
c.Name, c.StyleText,
|
||||||
|
)
|
||||||
|
|
||||||
|
return label
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChannelName will return a formatted representation of the
|
||||||
|
// name of the channel
|
||||||
|
func (c ChannelItem) GetChannelName() string {
|
||||||
|
var channelName string
|
||||||
|
if c.Topic != "" {
|
||||||
|
channelName = fmt.Sprintf("%s - %s",
|
||||||
|
html.UnescapeString(c.Name),
|
||||||
|
html.UnescapeString(c.Topic),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
channelName = c.Name
|
||||||
|
}
|
||||||
|
return channelName
|
||||||
|
}
|
||||||
|
|
||||||
// Channels is the definition of a Channels component
|
// Channels is the definition of a Channels component
|
||||||
type Channels struct {
|
type Channels struct {
|
||||||
List *termui.List
|
List *termui.List
|
||||||
@ -51,6 +127,7 @@ func (c *Channels) Buffer() termui.Buffer {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the visible cursor
|
||||||
var cells []termui.Cell
|
var cells []termui.Cell
|
||||||
if y == c.CursorPosition {
|
if y == c.CursorPosition {
|
||||||
cells = termui.DefaultTxBuilder.Build(
|
cells = termui.DefaultTxBuilder.Build(
|
||||||
|
@ -16,17 +16,31 @@ type Message struct {
|
|||||||
Time time.Time
|
Time time.Time
|
||||||
Name string
|
Name string
|
||||||
Content string
|
Content string
|
||||||
|
|
||||||
|
StyleTime string
|
||||||
|
StyleName string
|
||||||
|
StyleText string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Message) ToString() string {
|
func (m Message) ToString() string {
|
||||||
|
if (m.Time != time.Time{} && m.Name != "") {
|
||||||
|
|
||||||
return html.UnescapeString(
|
return html.UnescapeString(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"[%s] <%s> %s",
|
"[[%s]](%s) [<%s>](%s) [%s](%s)",
|
||||||
m.Time.Format("15:04"),
|
m.Time.Format("15:04"),
|
||||||
|
m.StyleTime,
|
||||||
m.Name,
|
m.Name,
|
||||||
|
m.StyleName,
|
||||||
m.Content,
|
m.Content,
|
||||||
|
m.StyleText,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
return html.UnescapeString(
|
||||||
|
fmt.Sprintf("[%s](%s)", m.Content, m.StyleText),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chat is the definition of a Chat component
|
// Chat is the definition of a Chat component
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
package components
|
package components
|
||||||
|
|
||||||
import "github.com/erroneousboat/termui"
|
import (
|
||||||
|
"github.com/erroneousboat/termui"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CommandMode = "NORMAL"
|
||||||
|
InsertMode = "INSERT"
|
||||||
|
SearchMode = "SEARCH"
|
||||||
|
)
|
||||||
|
|
||||||
// Mode is the definition of Mode component
|
// Mode is the definition of Mode component
|
||||||
type Mode struct {
|
type Mode struct {
|
||||||
@ -10,10 +18,11 @@ type Mode struct {
|
|||||||
// CreateMode is the constructor of the Mode struct
|
// CreateMode is the constructor of the Mode struct
|
||||||
func CreateModeComponent() *Mode {
|
func CreateModeComponent() *Mode {
|
||||||
mode := &Mode{
|
mode := &Mode{
|
||||||
Par: termui.NewPar("NORMAL"),
|
Par: termui.NewPar(CommandMode),
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Par.Height = 3
|
mode.Par.Height = 3
|
||||||
|
mode.SetCommandMode()
|
||||||
|
|
||||||
return mode
|
return mode
|
||||||
}
|
}
|
||||||
@ -82,16 +91,16 @@ func (m *Mode) SetY(y int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mode) SetInsertMode() {
|
func (m *Mode) SetInsertMode() {
|
||||||
m.Par.Text = "INSERT"
|
m.Par.Text = InsertMode
|
||||||
termui.Render(m)
|
termui.Render(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mode) SetCommandMode() {
|
func (m *Mode) SetCommandMode() {
|
||||||
m.Par.Text = "NORMAL"
|
m.Par.Text = CommandMode
|
||||||
termui.Render(m)
|
termui.Render(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mode) SetSearchMode() {
|
func (m *Mode) SetSearchMode() {
|
||||||
m.Par.Text = "SEARCH"
|
m.Par.Text = SearchMode
|
||||||
termui.Render(m)
|
termui.Render(m)
|
||||||
}
|
}
|
||||||
|
@ -11,18 +11,51 @@ import (
|
|||||||
// Config is the definition of a Config struct
|
// Config is the definition of a Config struct
|
||||||
type Config struct {
|
type Config struct {
|
||||||
SlackToken string `json:"slack_token"`
|
SlackToken string `json:"slack_token"`
|
||||||
Theme string `json:"theme"`
|
|
||||||
SidebarWidth int `json:"sidebar_width"`
|
SidebarWidth int `json:"sidebar_width"`
|
||||||
MainWidth int `json:"-"`
|
MainWidth int `json:"-"`
|
||||||
KeyMap map[string]keyMapping `json:"key_map"`
|
KeyMap map[string]keyMapping `json:"key_map"`
|
||||||
|
Theme Theme `json:"theme"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type keyMapping map[string]string
|
type keyMapping map[string]string
|
||||||
|
|
||||||
// NewConfig loads the config file and returns a Config struct
|
// NewConfig loads the config file and returns a Config struct
|
||||||
func NewConfig(filepath string) (*Config, error) {
|
func NewConfig(filepath string) (*Config, error) {
|
||||||
cfg := Config{
|
cfg := getDefaultConfig()
|
||||||
Theme: "dark",
|
|
||||||
|
file, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return &cfg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.NewDecoder(file).Decode(&cfg); err != nil {
|
||||||
|
return &cfg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.SlackToken == "" {
|
||||||
|
return &cfg, errors.New("couldn't find 'slack_token' parameter")
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.SidebarWidth < 1 || cfg.SidebarWidth > 11 {
|
||||||
|
return &cfg, errors.New("please specify the 'sidebar_width' between 1 and 11")
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.MainWidth = 12 - cfg.SidebarWidth
|
||||||
|
|
||||||
|
termui.ColorMap = map[string]termui.Attribute{
|
||||||
|
"fg": termui.StringToAttribute(cfg.Theme.View.Fg),
|
||||||
|
"bg": termui.StringToAttribute(cfg.Theme.View.Bg),
|
||||||
|
"border.fg": termui.StringToAttribute(cfg.Theme.View.BorderFg),
|
||||||
|
"label.fg": termui.StringToAttribute(cfg.Theme.View.LabelFg),
|
||||||
|
"par.fg": termui.StringToAttribute(cfg.Theme.View.ParFg),
|
||||||
|
"par.label.bg": termui.StringToAttribute(cfg.Theme.View.ParLabelFg),
|
||||||
|
}
|
||||||
|
|
||||||
|
return &cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDefaultConfig() Config {
|
||||||
|
return Config{
|
||||||
SidebarWidth: 1,
|
SidebarWidth: 1,
|
||||||
MainWidth: 11,
|
MainWidth: 11,
|
||||||
KeyMap: map[string]keyMapping{
|
KeyMap: map[string]keyMapping{
|
||||||
@ -63,37 +96,25 @@ func NewConfig(filepath string) (*Config, error) {
|
|||||||
"<space>": "space",
|
"<space>": "space",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Theme: Theme{
|
||||||
|
View: View{
|
||||||
|
Fg: "white",
|
||||||
|
Bg: "default",
|
||||||
|
BorderFg: "white",
|
||||||
|
LabelFg: "green,bold",
|
||||||
|
ParFg: "white",
|
||||||
|
ParLabelFg: "white",
|
||||||
|
},
|
||||||
|
Channel: Channel{
|
||||||
|
Prefix: "",
|
||||||
|
Icon: "fg-green,fg-bold",
|
||||||
|
Text: "fg-blue,fg-bold",
|
||||||
|
},
|
||||||
|
Message: Message{
|
||||||
|
Time: "fg-red,fg-bold",
|
||||||
|
Name: "fg-blue,fg-bold",
|
||||||
|
Text: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
return &cfg, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.NewDecoder(file).Decode(&cfg); err != nil {
|
|
||||||
return &cfg, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.SlackToken == "" {
|
|
||||||
return &cfg, errors.New("couldn't find 'slack_token' parameter")
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.SidebarWidth < 1 || cfg.SidebarWidth > 11 {
|
|
||||||
return &cfg, errors.New("please specify the 'sidebar_width' between 1 and 11")
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.MainWidth = 12 - cfg.SidebarWidth
|
|
||||||
|
|
||||||
if cfg.Theme == "light" {
|
|
||||||
termui.ColorMap = map[string]termui.Attribute{
|
|
||||||
"fg": termui.ColorBlack,
|
|
||||||
"bg": termui.ColorWhite,
|
|
||||||
"border.fg": termui.ColorBlack,
|
|
||||||
"label.fg": termui.ColorBlue,
|
|
||||||
"par.fg": termui.ColorYellow,
|
|
||||||
"par.label.bg": termui.ColorWhite,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &cfg, nil
|
|
||||||
}
|
}
|
||||||
|
28
config/theme.go
Normal file
28
config/theme.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Theme struct {
|
||||||
|
View View `json:"view"`
|
||||||
|
Channel Channel `json:"channel"`
|
||||||
|
Message Message `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type View struct {
|
||||||
|
Fg string `json:"fg"`
|
||||||
|
Bg string `json:"bg"`
|
||||||
|
BorderFg string `json:"border_fg"`
|
||||||
|
LabelFg string `json:"border_fg"`
|
||||||
|
ParFg string `json:"par_fg"`
|
||||||
|
ParLabelFg string `json:"par_label_fg"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Time string `json:"time"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Channel struct {
|
||||||
|
Prefix string `json:"prefix"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
@ -44,13 +44,13 @@ func CreateAppContext(flgConfig string, flgDebug bool) (*AppContext, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create Service
|
// Create Service
|
||||||
svc, err := service.NewSlackService(config.SlackToken)
|
svc, err := service.NewSlackService(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the main view
|
// Create the main view
|
||||||
view := views.CreateView(svc)
|
view := views.CreateView(config, svc)
|
||||||
|
|
||||||
// Setup the interface
|
// Setup the interface
|
||||||
if flgDebug {
|
if flgDebug {
|
||||||
|
@ -109,7 +109,9 @@ func messageHandler(ctx *context.AppContext) {
|
|||||||
// reverse order of messages, mainly done
|
// reverse order of messages, mainly done
|
||||||
// when attachments are added to message
|
// when attachments are added to message
|
||||||
for i := len(msg) - 1; i >= 0; i-- {
|
for i := len(msg) - 1; i >= 0; i-- {
|
||||||
ctx.View.Chat.AddMessage(msg[i])
|
ctx.View.Chat.AddMessage(
|
||||||
|
msg[i].ToString(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
termui.Render(ctx.View.Chat)
|
termui.Render(ctx.View.Chat)
|
||||||
@ -259,11 +261,17 @@ func actionSearchMode(ctx *context.AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func actionGetMessages(ctx *context.AppContext) {
|
func actionGetMessages(ctx *context.AppContext) {
|
||||||
messages := ctx.Service.GetMessages(
|
msgs := ctx.Service.GetMessages(
|
||||||
ctx.Service.Channels[ctx.View.Channels.SelectedChannel],
|
ctx.Service.Channels[ctx.View.Channels.SelectedChannel],
|
||||||
ctx.View.Chat.GetMaxItems(),
|
ctx.View.Chat.GetMaxItems(),
|
||||||
)
|
)
|
||||||
ctx.View.Chat.SetMessages(messages)
|
|
||||||
|
var strMsgs []string
|
||||||
|
for _, msg := range msgs {
|
||||||
|
strMsgs = append(strMsgs, msg.ToString())
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.View.Chat.SetMessages(strMsgs)
|
||||||
|
|
||||||
termui.Render(ctx.View.Chat)
|
termui.Render(ctx.View.Chat)
|
||||||
}
|
}
|
||||||
@ -324,13 +332,18 @@ func actionChangeChannel(ctx *context.AppContext) {
|
|||||||
|
|
||||||
// Get messages of the SelectedChannel, and get the count of messages
|
// Get messages of the SelectedChannel, and get the count of messages
|
||||||
// that fit into the Chat component
|
// that fit into the Chat component
|
||||||
messages := ctx.Service.GetMessages(
|
msgs := ctx.Service.GetMessages(
|
||||||
ctx.Service.GetSlackChannel(ctx.View.Channels.SelectedChannel),
|
ctx.Service.GetSlackChannel(ctx.View.Channels.SelectedChannel),
|
||||||
ctx.View.Chat.GetMaxItems(),
|
ctx.View.Chat.GetMaxItems(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var strMsgs []string
|
||||||
|
for _, msg := range msgs {
|
||||||
|
strMsgs = append(strMsgs, msg.ToString())
|
||||||
|
}
|
||||||
|
|
||||||
// Set messages for the channel
|
// Set messages for the channel
|
||||||
ctx.View.Chat.SetMessages(messages)
|
ctx.View.Chat.SetMessages(strMsgs)
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
// Set channel name for the Chat pane
|
// Set channel name for the Chat pane
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"html"
|
|
||||||
|
|
||||||
"github.com/erroneousboat/slack-term/components"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
PresenceAway = "away"
|
|
||||||
PresenceActive = "active"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Channel struct {
|
|
||||||
ID string
|
|
||||||
Name string
|
|
||||||
Topic string
|
|
||||||
Type string
|
|
||||||
UserID string
|
|
||||||
Presence string
|
|
||||||
Notification bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToString will set the label of the channel, how it will be
|
|
||||||
// displayed on screen. Based on the type, different icons are
|
|
||||||
// shown, as well as an optional notification icon.
|
|
||||||
func (c Channel) ToString() string {
|
|
||||||
var prefix string
|
|
||||||
if c.Notification {
|
|
||||||
prefix = components.IconNotification
|
|
||||||
} else {
|
|
||||||
prefix = " "
|
|
||||||
}
|
|
||||||
|
|
||||||
var label string
|
|
||||||
switch c.Type {
|
|
||||||
case ChannelTypeChannel:
|
|
||||||
label = fmt.Sprintf("%s %s %s", prefix, components.IconChannel, c.Name)
|
|
||||||
case ChannelTypeGroup:
|
|
||||||
label = fmt.Sprintf("%s %s %s", prefix, components.IconGroup, c.Name)
|
|
||||||
case ChannelTypeIM:
|
|
||||||
var icon string
|
|
||||||
switch c.Presence {
|
|
||||||
case PresenceActive:
|
|
||||||
icon = components.IconOnline
|
|
||||||
case PresenceAway:
|
|
||||||
icon = components.IconOffline
|
|
||||||
default:
|
|
||||||
icon = components.IconIM
|
|
||||||
}
|
|
||||||
label = fmt.Sprintf("%s %s %s", prefix, icon, c.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return label
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChannelName will return a formatted representation of the
|
|
||||||
// name of the channel
|
|
||||||
func (c Channel) GetChannelName() string {
|
|
||||||
var channelName string
|
|
||||||
if c.Topic != "" {
|
|
||||||
channelName = fmt.Sprintf("%s - %s",
|
|
||||||
html.UnescapeString(c.Name),
|
|
||||||
html.UnescapeString(c.Topic),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
channelName = c.Name
|
|
||||||
}
|
|
||||||
return channelName
|
|
||||||
}
|
|
@ -22,10 +22,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SlackService struct {
|
type SlackService struct {
|
||||||
|
Config *config.Config
|
||||||
Client *slack.Client
|
Client *slack.Client
|
||||||
RTM *slack.RTM
|
RTM *slack.RTM
|
||||||
SlackChannels []interface{}
|
SlackChannels []interface{}
|
||||||
Channels []Channel
|
Channels []components.ChannelItem
|
||||||
UserCache map[string]string
|
UserCache map[string]string
|
||||||
CurrentUserID string
|
CurrentUserID string
|
||||||
CurrentUsername string
|
CurrentUsername string
|
||||||
@ -33,9 +34,10 @@ type SlackService struct {
|
|||||||
|
|
||||||
// NewSlackService is the constructor for the SlackService and will initialize
|
// NewSlackService is the constructor for the SlackService and will initialize
|
||||||
// the RTM and a Client
|
// the RTM and a Client
|
||||||
func NewSlackService(token string) (*SlackService, error) {
|
func NewSlackService(config *config.Config) (*SlackService, error) {
|
||||||
svc := &SlackService{
|
svc := &SlackService{
|
||||||
Client: slack.New(token),
|
Config: config,
|
||||||
|
Client: slack.New(config.SlackToken),
|
||||||
UserCache: make(map[string]string),
|
UserCache: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,23 +79,27 @@ func NewSlackService(token string) (*SlackService, error) {
|
|||||||
// an []interface as well as to a []Channel which will give us easy access
|
// an []interface as well as to a []Channel which will give us easy access
|
||||||
// to the id and name of the Channel.
|
// to the id and name of the Channel.
|
||||||
func (s *SlackService) GetChannels() []string {
|
func (s *SlackService) GetChannels() []string {
|
||||||
var chans []Channel
|
var chans []components.ChannelItem
|
||||||
|
|
||||||
// Channel
|
// Channel
|
||||||
slackChans, err := s.Client.GetChannels(true)
|
slackChans, err := s.Client.GetChannels(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chans = append(chans, Channel{})
|
chans = append(chans, components.ChannelItem{})
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, chn := range slackChans {
|
for _, chn := range slackChans {
|
||||||
if chn.IsMember {
|
if chn.IsMember {
|
||||||
s.SlackChannels = append(s.SlackChannels, chn)
|
s.SlackChannels = append(s.SlackChannels, chn)
|
||||||
chans = append(
|
chans = append(
|
||||||
chans, Channel{
|
chans, components.ChannelItem{
|
||||||
ID: chn.ID,
|
ID: chn.ID,
|
||||||
Name: chn.Name,
|
Name: chn.Name,
|
||||||
Topic: chn.Topic.Value,
|
Topic: chn.Topic.Value,
|
||||||
Type: ChannelTypeChannel,
|
Type: components.ChannelTypeChannel,
|
||||||
UserID: "",
|
UserID: "",
|
||||||
|
StylePrefix: s.Config.Theme.Channel.Prefix,
|
||||||
|
StyleIcon: s.Config.Theme.Channel.Icon,
|
||||||
|
StyleText: s.Config.Theme.Channel.Text,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -102,17 +108,20 @@ func (s *SlackService) GetChannels() []string {
|
|||||||
// Groups
|
// Groups
|
||||||
slackGroups, err := s.Client.GetGroups(true)
|
slackGroups, err := s.Client.GetGroups(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chans = append(chans, Channel{})
|
chans = append(chans, components.ChannelItem{})
|
||||||
}
|
}
|
||||||
for _, grp := range slackGroups {
|
for _, grp := range slackGroups {
|
||||||
s.SlackChannels = append(s.SlackChannels, grp)
|
s.SlackChannels = append(s.SlackChannels, grp)
|
||||||
chans = append(
|
chans = append(
|
||||||
chans, Channel{
|
chans, components.ChannelItem{
|
||||||
ID: grp.ID,
|
ID: grp.ID,
|
||||||
Name: grp.Name,
|
Name: grp.Name,
|
||||||
Topic: grp.Topic.Value,
|
Topic: grp.Topic.Value,
|
||||||
Type: ChannelTypeGroup,
|
Type: components.ChannelTypeGroup,
|
||||||
UserID: "",
|
UserID: "",
|
||||||
|
StylePrefix: s.Config.Theme.Channel.Prefix,
|
||||||
|
StyleIcon: s.Config.Theme.Channel.Icon,
|
||||||
|
StyleText: s.Config.Theme.Channel.Text,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -120,7 +129,7 @@ func (s *SlackService) GetChannels() []string {
|
|||||||
// IM
|
// IM
|
||||||
slackIM, err := s.Client.GetIMChannels()
|
slackIM, err := s.Client.GetIMChannels()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chans = append(chans, Channel{})
|
chans = append(chans, components.ChannelItem{})
|
||||||
}
|
}
|
||||||
for _, im := range slackIM {
|
for _, im := range slackIM {
|
||||||
|
|
||||||
@ -136,13 +145,16 @@ func (s *SlackService) GetChannels() []string {
|
|||||||
if ok {
|
if ok {
|
||||||
chans = append(
|
chans = append(
|
||||||
chans,
|
chans,
|
||||||
Channel{
|
components.ChannelItem{
|
||||||
ID: im.ID,
|
ID: im.ID,
|
||||||
Name: name,
|
Name: name,
|
||||||
Topic: "",
|
Topic: "",
|
||||||
Type: ChannelTypeIM,
|
Type: components.ChannelTypeIM,
|
||||||
UserID: im.User,
|
UserID: im.User,
|
||||||
Presence: presence,
|
Presence: presence,
|
||||||
|
StylePrefix: s.Config.Theme.Channel.Prefix,
|
||||||
|
StyleIcon: s.Config.Theme.Channel.Icon,
|
||||||
|
StyleText: s.Config.Theme.Channel.Text,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
s.SlackChannels = append(s.SlackChannels, im)
|
s.SlackChannels = append(s.SlackChannels, im)
|
||||||
@ -271,7 +283,7 @@ func (s *SlackService) SendMessage(channelID int, message string) {
|
|||||||
|
|
||||||
// GetMessages will get messages for a channel, group or im channel delimited
|
// GetMessages will get messages for a channel, group or im channel delimited
|
||||||
// by a count.
|
// by a count.
|
||||||
func (s *SlackService) GetMessages(channel interface{}, count int) []string {
|
func (s *SlackService) GetMessages(channel interface{}, count int) []components.Message {
|
||||||
// https://api.slack.com/methods/channels.history
|
// https://api.slack.com/methods/channels.history
|
||||||
historyParams := slack.HistoryParameters{
|
historyParams := slack.HistoryParameters{
|
||||||
Count: count,
|
Count: count,
|
||||||
@ -301,7 +313,7 @@ func (s *SlackService) GetMessages(channel interface{}, count int) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct the messages
|
// Construct the messages
|
||||||
var messages []string
|
var messages []components.Message
|
||||||
for _, message := range history.Messages {
|
for _, message := range history.Messages {
|
||||||
msg := s.CreateMessage(message)
|
msg := s.CreateMessage(message)
|
||||||
messages = append(messages, msg...)
|
messages = append(messages, msg...)
|
||||||
@ -309,7 +321,7 @@ func (s *SlackService) GetMessages(channel interface{}, count int) []string {
|
|||||||
|
|
||||||
// Reverse the order of the messages, we want the newest in
|
// Reverse the order of the messages, we want the newest in
|
||||||
// the last place
|
// the last place
|
||||||
var messagesReversed []string
|
var messagesReversed []components.Message
|
||||||
for i := len(messages) - 1; i >= 0; i-- {
|
for i := len(messages) - 1; i >= 0; i-- {
|
||||||
messagesReversed = append(messagesReversed, messages[i])
|
messagesReversed = append(messagesReversed, messages[i])
|
||||||
}
|
}
|
||||||
@ -324,8 +336,8 @@ func (s *SlackService) GetMessages(channel interface{}, count int) []string {
|
|||||||
//
|
//
|
||||||
// This returns an array of string because we will try to uncover attachments
|
// This returns an array of string because we will try to uncover attachments
|
||||||
// associated with messages.
|
// associated with messages.
|
||||||
func (s *SlackService) CreateMessage(message slack.Message) []string {
|
func (s *SlackService) CreateMessage(message slack.Message) []components.Message {
|
||||||
var msgs []string
|
var msgs []components.Message
|
||||||
var name string
|
var name string
|
||||||
|
|
||||||
// Get username from cache
|
// Get username from cache
|
||||||
@ -360,7 +372,7 @@ func (s *SlackService) CreateMessage(message slack.Message) []string {
|
|||||||
|
|
||||||
// When there are attachments append them
|
// When there are attachments append them
|
||||||
if len(message.Attachments) > 0 {
|
if len(message.Attachments) > 0 {
|
||||||
msgs = append(msgs, createMessageFromAttachments(message.Attachments)...)
|
msgs = append(msgs, s.CreateMessageFromAttachments(message.Attachments)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse time
|
// Parse time
|
||||||
@ -375,16 +387,19 @@ func (s *SlackService) CreateMessage(message slack.Message) []string {
|
|||||||
Time: time.Unix(intTime, 0),
|
Time: time.Unix(intTime, 0),
|
||||||
Name: name,
|
Name: name,
|
||||||
Content: parseMessage(s, message.Text),
|
Content: parseMessage(s, message.Text),
|
||||||
|
StyleTime: s.Config.Theme.Message.Time,
|
||||||
|
StyleName: s.Config.Theme.Message.Name,
|
||||||
|
StyleText: s.Config.Theme.Message.Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs = append(msgs, msg.ToString())
|
msgs = append(msgs, msg)
|
||||||
|
|
||||||
return msgs
|
return msgs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SlackService) CreateMessageFromMessageEvent(message *slack.MessageEvent) []string {
|
func (s *SlackService) CreateMessageFromMessageEvent(message *slack.MessageEvent) []components.Message {
|
||||||
|
|
||||||
var msgs []string
|
var msgs []components.Message
|
||||||
var name string
|
var name string
|
||||||
|
|
||||||
// Append (edited) when an edited message is received
|
// Append (edited) when an edited message is received
|
||||||
@ -425,7 +440,7 @@ func (s *SlackService) CreateMessageFromMessageEvent(message *slack.MessageEvent
|
|||||||
|
|
||||||
// When there are attachments append them
|
// When there are attachments append them
|
||||||
if len(message.Attachments) > 0 {
|
if len(message.Attachments) > 0 {
|
||||||
msgs = append(msgs, createMessageFromAttachments(message.Attachments)...)
|
msgs = append(msgs, s.CreateMessageFromAttachments(message.Attachments)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse time
|
// Parse time
|
||||||
@ -440,9 +455,12 @@ func (s *SlackService) CreateMessageFromMessageEvent(message *slack.MessageEvent
|
|||||||
Time: time.Unix(intTime, 0),
|
Time: time.Unix(intTime, 0),
|
||||||
Name: name,
|
Name: name,
|
||||||
Content: parseMessage(s, message.Text),
|
Content: parseMessage(s, message.Text),
|
||||||
|
StyleTime: s.Config.Theme.Message.Time,
|
||||||
|
StyleName: s.Config.Theme.Message.Name,
|
||||||
|
StyleText: s.Config.Theme.Message.Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs = append(msgs, msg.ToString())
|
msgs = append(msgs, msg)
|
||||||
|
|
||||||
return msgs
|
return msgs
|
||||||
}
|
}
|
||||||
@ -522,27 +540,37 @@ func parseEmoji(msg string) string {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createMessageFromAttachments will construct a array of string of the Field
|
// CreateMessageFromAttachments will construct a array of string of the Field
|
||||||
// values of Attachments from a Message.
|
// values of Attachments from a Message.
|
||||||
func createMessageFromAttachments(atts []slack.Attachment) []string {
|
func (s *SlackService) CreateMessageFromAttachments(atts []slack.Attachment) []components.Message {
|
||||||
var msgs []string
|
var msgs []components.Message
|
||||||
for _, att := range atts {
|
for _, att := range atts {
|
||||||
for i := len(att.Fields) - 1; i >= 0; i-- {
|
for i := len(att.Fields) - 1; i >= 0; i-- {
|
||||||
msgs = append(msgs,
|
msgs = append(msgs, components.Message{
|
||||||
fmt.Sprintf(
|
Content: fmt.Sprintf(
|
||||||
"%s %s",
|
"%s %s",
|
||||||
att.Fields[i].Title,
|
att.Fields[i].Title,
|
||||||
att.Fields[i].Value,
|
att.Fields[i].Value,
|
||||||
),
|
),
|
||||||
|
StyleTime: s.Config.Theme.Message.Time,
|
||||||
|
StyleName: s.Config.Theme.Message.Name,
|
||||||
|
StyleText: s.Config.Theme.Message.Text,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if att.Text != "" {
|
if att.Text != "" {
|
||||||
msgs = append(msgs, att.Text)
|
msgs = append(
|
||||||
|
msgs,
|
||||||
|
components.Message{Content: fmt.Sprintf("%s", att.Text)},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if att.Title != "" {
|
if att.Title != "" {
|
||||||
msgs = append(msgs, att.Title)
|
msgs = append(
|
||||||
|
msgs,
|
||||||
|
components.Message{Content: fmt.Sprintf("%s", att.Title)},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,12 @@ import (
|
|||||||
"github.com/erroneousboat/termui"
|
"github.com/erroneousboat/termui"
|
||||||
|
|
||||||
"github.com/erroneousboat/slack-term/components"
|
"github.com/erroneousboat/slack-term/components"
|
||||||
|
"github.com/erroneousboat/slack-term/config"
|
||||||
"github.com/erroneousboat/slack-term/service"
|
"github.com/erroneousboat/slack-term/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
type View struct {
|
type View struct {
|
||||||
|
Config *config.Config
|
||||||
Input *components.Input
|
Input *components.Input
|
||||||
Chat *components.Chat
|
Chat *components.Chat
|
||||||
Channels *components.Channels
|
Channels *components.Channels
|
||||||
@ -15,7 +17,7 @@ type View struct {
|
|||||||
Debug *components.Debug
|
Debug *components.Debug
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateView(svc *service.SlackService) *View {
|
func CreateView(config *config.Config, svc *service.SlackService) *View {
|
||||||
// Create Input component
|
// Create Input component
|
||||||
input := components.CreateInputComponent()
|
input := components.CreateInputComponent()
|
||||||
|
|
||||||
@ -30,11 +32,17 @@ func CreateView(svc *service.SlackService) *View {
|
|||||||
chat := components.CreateChatComponent(input.Par.Height)
|
chat := components.CreateChatComponent(input.Par.Height)
|
||||||
|
|
||||||
// Chat: fill the component
|
// Chat: fill the component
|
||||||
slackMsgs := svc.GetMessages(
|
msgs := svc.GetMessages(
|
||||||
svc.GetSlackChannel(channels.SelectedChannel),
|
svc.GetSlackChannel(channels.SelectedChannel),
|
||||||
chat.GetMaxItems(),
|
chat.GetMaxItems(),
|
||||||
)
|
)
|
||||||
chat.SetMessages(slackMsgs)
|
|
||||||
|
var strMsgs []string
|
||||||
|
for _, msg := range msgs {
|
||||||
|
strMsgs = append(strMsgs, msg.ToString())
|
||||||
|
}
|
||||||
|
|
||||||
|
chat.SetMessages(strMsgs)
|
||||||
chat.SetBorderLabel(svc.Channels[channels.SelectedChannel].GetChannelName())
|
chat.SetBorderLabel(svc.Channels[channels.SelectedChannel].GetChannelName())
|
||||||
|
|
||||||
// Debug: create the component
|
// Debug: create the component
|
||||||
@ -44,6 +52,7 @@ func CreateView(svc *service.SlackService) *View {
|
|||||||
mode := components.CreateModeComponent()
|
mode := components.CreateModeComponent()
|
||||||
|
|
||||||
view := &View{
|
view := &View{
|
||||||
|
Config: config,
|
||||||
Input: input,
|
Input: input,
|
||||||
Channels: channels,
|
Channels: channels,
|
||||||
Chat: chat,
|
Chat: chat,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user