|
@@ -16,12 +16,12 @@ import (
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
var (
|
|
|
- app *tview.Application
|
|
|
|
|
- loginForm *tview.Form
|
|
|
|
|
- guildsView *tview.TreeView
|
|
|
|
|
- messagesView *tview.TextView
|
|
|
|
|
- messageInputField *tview.InputField
|
|
|
|
|
- mainFlex *tview.Flex
|
|
|
|
|
|
|
+ app *tview.Application
|
|
|
|
|
+ loginWidget *tview.Form
|
|
|
|
|
+ guildsWidget *tview.TreeView
|
|
|
|
|
+ messagesWidget *tview.TextView
|
|
|
|
|
+ inputWidget *tview.InputField
|
|
|
|
|
+ mainFlex *tview.Flex
|
|
|
|
|
|
|
|
config *util.Config
|
|
config *util.Config
|
|
|
session *discordgo.Session
|
|
session *discordgo.Session
|
|
@@ -37,19 +37,19 @@ func main() {
|
|
|
app.EnableMouse(config.Mouse)
|
|
app.EnableMouse(config.Mouse)
|
|
|
app.SetInputCapture(onAppInputCapture)
|
|
app.SetInputCapture(onAppInputCapture)
|
|
|
|
|
|
|
|
- guildsView = ui.NewGuildsView()
|
|
|
|
|
- guildsView.SetSelectedFunc(onGuildsTreeViewSelected)
|
|
|
|
|
|
|
+ guildsWidget = ui.NewGuildsWidget()
|
|
|
|
|
+ guildsWidget.SetSelectedFunc(onGuildsWidgetSelected)
|
|
|
|
|
|
|
|
- messagesView = ui.NewMessagesView(app)
|
|
|
|
|
- messagesView.SetInputCapture(onMessagesViewInputCapture)
|
|
|
|
|
|
|
+ messagesWidget = ui.NewMessagesWidget(app)
|
|
|
|
|
+ messagesWidget.SetInputCapture(onMessagesWidgetInputCapture)
|
|
|
|
|
|
|
|
- messageInputField = ui.NewMessageInputField()
|
|
|
|
|
- messageInputField.SetInputCapture(onMessageInputFieldInputCapture)
|
|
|
|
|
|
|
+ inputWidget = ui.NewInputWidget()
|
|
|
|
|
+ inputWidget.SetInputCapture(onInputWidgetInputCapture)
|
|
|
|
|
|
|
|
mainFlex = ui.NewMainFlex(
|
|
mainFlex = ui.NewMainFlex(
|
|
|
- guildsView,
|
|
|
|
|
- messagesView,
|
|
|
|
|
- messageInputField,
|
|
|
|
|
|
|
+ guildsWidget,
|
|
|
|
|
+ messagesWidget,
|
|
|
|
|
+ inputWidget,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
token := config.Token
|
|
token := config.Token
|
|
@@ -60,7 +60,7 @@ func main() {
|
|
|
if token != "" {
|
|
if token != "" {
|
|
|
app.
|
|
app.
|
|
|
SetRoot(mainFlex, true).
|
|
SetRoot(mainFlex, true).
|
|
|
- SetFocus(guildsView)
|
|
|
|
|
|
|
+ SetFocus(guildsWidget)
|
|
|
|
|
|
|
|
session = newSession()
|
|
session = newSession()
|
|
|
session.Token = token
|
|
session.Token = token
|
|
@@ -69,8 +69,8 @@ func main() {
|
|
|
panic(err)
|
|
panic(err)
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- loginForm = ui.NewLoginForm(onLoginFormLoginButtonSelected, false)
|
|
|
|
|
- app.SetRoot(loginForm, true)
|
|
|
|
|
|
|
+ loginWidget = ui.NewLoginWidget(onLoginFormLoginButtonSelected, false)
|
|
|
|
|
+ app.SetRoot(loginWidget, true)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if err := app.Run(); err != nil {
|
|
if err := app.Run(); err != nil {
|
|
@@ -82,11 +82,11 @@ func onAppInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
if e.Modifiers() == tcell.ModAlt {
|
|
if e.Modifiers() == tcell.ModAlt {
|
|
|
switch e.Rune() {
|
|
switch e.Rune() {
|
|
|
case '1':
|
|
case '1':
|
|
|
- app.SetFocus(guildsView)
|
|
|
|
|
|
|
+ app.SetFocus(guildsWidget)
|
|
|
case '2':
|
|
case '2':
|
|
|
- app.SetFocus(messagesView)
|
|
|
|
|
|
|
+ app.SetFocus(messagesWidget)
|
|
|
case '3':
|
|
case '3':
|
|
|
- app.SetFocus(messageInputField)
|
|
|
|
|
|
|
+ app.SetFocus(inputWidget)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -103,7 +103,7 @@ func findByMessageID(ms []*discordgo.Message, mID string) (int, *discordgo.Messa
|
|
|
return -1, nil
|
|
return -1, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func onMessagesViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
|
|
|
|
+func onMessagesWidgetInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
if selectedChannel == nil {
|
|
if selectedChannel == nil {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
@@ -111,11 +111,11 @@ func onMessagesViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
switch {
|
|
switch {
|
|
|
case e.Key() == tcell.KeyUp || e.Rune() == 'k': // Up
|
|
case e.Key() == tcell.KeyUp || e.Rune() == 'k': // Up
|
|
|
ms := selectedChannel.Messages
|
|
ms := selectedChannel.Messages
|
|
|
- hs := messagesView.GetHighlights()
|
|
|
|
|
|
|
+ hs := messagesWidget.GetHighlights()
|
|
|
// If there are no currently highlighted message, highlight the last
|
|
// If there are no currently highlighted message, highlight the last
|
|
|
// message in the TextView.
|
|
// message in the TextView.
|
|
|
if len(hs) == 0 {
|
|
if len(hs) == 0 {
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Highlight(ms[len(ms)-1].ID).
|
|
Highlight(ms[len(ms)-1].ID).
|
|
|
ScrollToHighlight()
|
|
ScrollToHighlight()
|
|
|
} else {
|
|
} else {
|
|
@@ -130,7 +130,7 @@ func onMessagesViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
}
|
|
}
|
|
|
// Highlight the message just before the currently highlighted
|
|
// Highlight the message just before the currently highlighted
|
|
|
// message.
|
|
// message.
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Highlight(ms[idx-1].ID).
|
|
Highlight(ms[idx-1].ID).
|
|
|
ScrollToHighlight()
|
|
ScrollToHighlight()
|
|
|
}
|
|
}
|
|
@@ -138,11 +138,11 @@ func onMessagesViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
return nil
|
|
return nil
|
|
|
case e.Key() == tcell.KeyDown || e.Rune() == 'j': // Down
|
|
case e.Key() == tcell.KeyDown || e.Rune() == 'j': // Down
|
|
|
ms := selectedChannel.Messages
|
|
ms := selectedChannel.Messages
|
|
|
- hs := messagesView.GetHighlights()
|
|
|
|
|
|
|
+ hs := messagesWidget.GetHighlights()
|
|
|
// If there are no currently highlighted message, highlight the last
|
|
// If there are no currently highlighted message, highlight the last
|
|
|
// message in the TextView.
|
|
// message in the TextView.
|
|
|
if len(hs) == 0 {
|
|
if len(hs) == 0 {
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Highlight(ms[len(ms)-1].ID).
|
|
Highlight(ms[len(ms)-1].ID).
|
|
|
ScrollToHighlight()
|
|
ScrollToHighlight()
|
|
|
} else {
|
|
} else {
|
|
@@ -157,7 +157,7 @@ func onMessagesViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
}
|
|
}
|
|
|
// Highlight the message just after the currently highlighted
|
|
// Highlight the message just after the currently highlighted
|
|
|
// message.
|
|
// message.
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Highlight(ms[idx+1].ID).
|
|
Highlight(ms[idx+1].ID).
|
|
|
ScrollToHighlight()
|
|
ScrollToHighlight()
|
|
|
}
|
|
}
|
|
@@ -167,34 +167,34 @@ func onMessagesViewInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
ms := selectedChannel.Messages
|
|
ms := selectedChannel.Messages
|
|
|
// Highlight the last message in the selectedChannel.Messages slice
|
|
// Highlight the last message in the selectedChannel.Messages slice
|
|
|
// (the first message rendered in the TextView).
|
|
// (the first message rendered in the TextView).
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Highlight(ms[0].ID).
|
|
Highlight(ms[0].ID).
|
|
|
ScrollToHighlight()
|
|
ScrollToHighlight()
|
|
|
case e.Key() == tcell.KeyEnd || e.Rune() == 'G': // Bottom
|
|
case e.Key() == tcell.KeyEnd || e.Rune() == 'G': // Bottom
|
|
|
ms := selectedChannel.Messages
|
|
ms := selectedChannel.Messages
|
|
|
// Highlight the first message in the selectedChannel.Messages slice
|
|
// Highlight the first message in the selectedChannel.Messages slice
|
|
|
// (the last message rendered in the TextView).
|
|
// (the last message rendered in the TextView).
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Highlight(ms[len(ms)-1].ID).
|
|
Highlight(ms[len(ms)-1].ID).
|
|
|
ScrollToHighlight()
|
|
ScrollToHighlight()
|
|
|
case e.Rune() == 'r': // Reply
|
|
case e.Rune() == 'r': // Reply
|
|
|
ms := selectedChannel.Messages
|
|
ms := selectedChannel.Messages
|
|
|
- hs := messagesView.GetHighlights()
|
|
|
|
|
|
|
+ hs := messagesWidget.GetHighlights()
|
|
|
if len(hs) == 0 {
|
|
if len(hs) == 0 {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
_, selectedMessage = findByMessageID(ms, hs[0])
|
|
_, selectedMessage = findByMessageID(ms, hs[0])
|
|
|
- messageInputField.SetTitle(
|
|
|
|
|
|
|
+ inputWidget.SetTitle(
|
|
|
"Replying to " + selectedMessage.Author.Username,
|
|
"Replying to " + selectedMessage.Author.Username,
|
|
|
)
|
|
)
|
|
|
- app.SetFocus(messageInputField)
|
|
|
|
|
|
|
+ app.SetFocus(inputWidget)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return e
|
|
return e
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func onMessageInputFieldInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
|
|
|
|
+func onInputWidgetInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
// If the "Alt" modifier key is pressed, do not handle the event.
|
|
// If the "Alt" modifier key is pressed, do not handle the event.
|
|
|
if e.Modifiers() == tcell.ModAlt {
|
|
if e.Modifiers() == tcell.ModAlt {
|
|
|
return nil
|
|
return nil
|
|
@@ -206,13 +206,13 @@ func onMessageInputFieldInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- t := strings.TrimSpace(messageInputField.GetText())
|
|
|
|
|
|
|
+ t := strings.TrimSpace(inputWidget.GetText())
|
|
|
if t == "" {
|
|
if t == "" {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if selectedMessage != nil {
|
|
if selectedMessage != nil {
|
|
|
- messageInputField.SetTitle("")
|
|
|
|
|
|
|
+ inputWidget.SetTitle("")
|
|
|
go session.ChannelMessageSendReply(
|
|
go session.ChannelMessageSendReply(
|
|
|
selectedMessage.ChannelID,
|
|
selectedMessage.ChannelID,
|
|
|
t,
|
|
t,
|
|
@@ -224,13 +224,13 @@ func onMessageInputFieldInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|
|
go session.ChannelMessageSend(selectedChannel.ID, t)
|
|
go session.ChannelMessageSend(selectedChannel.ID, t)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- messageInputField.SetText("")
|
|
|
|
|
|
|
+ inputWidget.SetText("")
|
|
|
case tcell.KeyCtrlV:
|
|
case tcell.KeyCtrlV:
|
|
|
text, _ := clipboard.ReadAll()
|
|
text, _ := clipboard.ReadAll()
|
|
|
- text = messageInputField.GetText() + text
|
|
|
|
|
- messageInputField.SetText(text)
|
|
|
|
|
|
|
+ text = inputWidget.GetText() + text
|
|
|
|
|
+ inputWidget.SetText(text)
|
|
|
case tcell.KeyEscape: // Cancel
|
|
case tcell.KeyEscape: // Cancel
|
|
|
- messageInputField.SetTitle("")
|
|
|
|
|
|
|
+ inputWidget.SetTitle("")
|
|
|
selectedMessage = nil
|
|
selectedMessage = nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -275,14 +275,14 @@ func onSessionReady(_ *discordgo.Session, r *discordgo.Ready) {
|
|
|
return false
|
|
return false
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- n := guildsView.GetRoot()
|
|
|
|
|
|
|
+ n := guildsWidget.GetRoot()
|
|
|
for _, g := range r.Guilds {
|
|
for _, g := range r.Guilds {
|
|
|
gn := tview.NewTreeNode(g.Name).
|
|
gn := tview.NewTreeNode(g.Name).
|
|
|
SetReference(g.ID)
|
|
SetReference(g.ID)
|
|
|
n.AddChild(gn)
|
|
n.AddChild(gn)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- guildsView.SetCurrentNode(n)
|
|
|
|
|
|
|
+ guildsWidget.SetCurrentNode(n)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func onSessionMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
func onSessionMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
@@ -315,16 +315,16 @@ func onSessionMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
|
|
|
|
|
|
selectedChannel.Messages = append(selectedChannel.Messages, m.Message)
|
|
selectedChannel.Messages = append(selectedChannel.Messages, m.Message)
|
|
|
util.WriteMessage(
|
|
util.WriteMessage(
|
|
|
- messagesView,
|
|
|
|
|
|
|
+ messagesWidget,
|
|
|
m.Message,
|
|
m.Message,
|
|
|
session.State.Ready.User.ID,
|
|
session.State.Ready.User.ID,
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func onGuildsTreeViewSelected(n *tview.TreeNode) {
|
|
|
|
|
|
|
+func onGuildsWidgetSelected(n *tview.TreeNode) {
|
|
|
selectedChannel = nil
|
|
selectedChannel = nil
|
|
|
selectedMessage = nil
|
|
selectedMessage = nil
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Clear().
|
|
Clear().
|
|
|
SetTitle("")
|
|
SetTitle("")
|
|
|
|
|
|
|
@@ -350,7 +350,7 @@ func onGuildsTreeViewSelected(n *tview.TreeNode) {
|
|
|
// Category channels
|
|
// Category channels
|
|
|
ui.CreateCategoryChannelsTreeNodes(session.State, n, cs)
|
|
ui.CreateCategoryChannelsTreeNodes(session.State, n, cs)
|
|
|
// Second-level channels
|
|
// Second-level channels
|
|
|
- ui.CreateSecondLevelChannelsTreeNodes(session.State, guildsView, cs)
|
|
|
|
|
|
|
+ ui.CreateSecondLevelChannelsTreeNodes(session.State, guildsWidget, cs)
|
|
|
default:
|
|
default:
|
|
|
cID := n.GetReference().(string)
|
|
cID := n.GetReference().(string)
|
|
|
c, _ := session.State.Channel(cID)
|
|
c, _ := session.State.Channel(cID)
|
|
@@ -359,13 +359,13 @@ func onGuildsTreeViewSelected(n *tview.TreeNode) {
|
|
|
n.SetExpanded(!n.IsExpanded())
|
|
n.SetExpanded(!n.IsExpanded())
|
|
|
} else if c.Type == discordgo.ChannelTypeGuildNews || c.Type == discordgo.ChannelTypeGuildText {
|
|
} else if c.Type == discordgo.ChannelTypeGuildNews || c.Type == discordgo.ChannelTypeGuildText {
|
|
|
selectedChannel = c
|
|
selectedChannel = c
|
|
|
- app.SetFocus(messageInputField)
|
|
|
|
|
|
|
+ app.SetFocus(inputWidget)
|
|
|
|
|
|
|
|
title := "#" + c.Name
|
|
title := "#" + c.Name
|
|
|
if c.Topic != "" {
|
|
if c.Topic != "" {
|
|
|
title += " - " + c.Topic
|
|
title += " - " + c.Topic
|
|
|
}
|
|
}
|
|
|
- messagesView.
|
|
|
|
|
|
|
+ messagesWidget.
|
|
|
Clear().
|
|
Clear().
|
|
|
SetTitle(title)
|
|
SetTitle(title)
|
|
|
|
|
|
|
@@ -380,7 +380,7 @@ func writeMessages(cID string) {
|
|
|
selectedChannel.Messages = append(selectedChannel.Messages, msgs[i])
|
|
selectedChannel.Messages = append(selectedChannel.Messages, msgs[i])
|
|
|
|
|
|
|
|
util.WriteMessage(
|
|
util.WriteMessage(
|
|
|
- messagesView,
|
|
|
|
|
|
|
+ messagesWidget,
|
|
|
msgs[i],
|
|
msgs[i],
|
|
|
session.State.Ready.User.ID,
|
|
session.State.Ready.User.ID,
|
|
|
)
|
|
)
|
|
@@ -388,8 +388,8 @@ func writeMessages(cID string) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func onLoginFormLoginButtonSelected() {
|
|
func onLoginFormLoginButtonSelected() {
|
|
|
- email := loginForm.GetFormItem(0).(*tview.InputField).GetText()
|
|
|
|
|
- password := loginForm.GetFormItem(1).(*tview.InputField).GetText()
|
|
|
|
|
|
|
+ email := loginWidget.GetFormItem(0).(*tview.InputField).GetText()
|
|
|
|
|
+ password := loginWidget.GetFormItem(1).(*tview.InputField).GetText()
|
|
|
if email == "" || password == "" {
|
|
if email == "" || password == "" {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -404,7 +404,7 @@ func onLoginFormLoginButtonSelected() {
|
|
|
if lr.Token != "" && !lr.MFA {
|
|
if lr.Token != "" && !lr.MFA {
|
|
|
app.
|
|
app.
|
|
|
SetRoot(mainFlex, true).
|
|
SetRoot(mainFlex, true).
|
|
|
- SetFocus(guildsView)
|
|
|
|
|
|
|
+ SetFocus(guildsWidget)
|
|
|
|
|
|
|
|
session.Token = lr.Token
|
|
session.Token = lr.Token
|
|
|
session.Identify.Token = lr.Token
|
|
session.Identify.Token = lr.Token
|
|
@@ -414,8 +414,8 @@ func onLoginFormLoginButtonSelected() {
|
|
|
|
|
|
|
|
go keyring.Set("discordo", "token", lr.Token)
|
|
go keyring.Set("discordo", "token", lr.Token)
|
|
|
} else if lr.MFA {
|
|
} else if lr.MFA {
|
|
|
- loginForm = ui.NewLoginForm(func() {
|
|
|
|
|
- code := loginForm.GetFormItem(0).(*tview.InputField).GetText()
|
|
|
|
|
|
|
+ loginWidget = ui.NewLoginWidget(func() {
|
|
|
|
|
+ code := loginWidget.GetFormItem(0).(*tview.InputField).GetText()
|
|
|
if code == "" {
|
|
if code == "" {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -427,7 +427,7 @@ func onLoginFormLoginButtonSelected() {
|
|
|
|
|
|
|
|
app.
|
|
app.
|
|
|
SetRoot(mainFlex, true).
|
|
SetRoot(mainFlex, true).
|
|
|
- SetFocus(guildsView)
|
|
|
|
|
|
|
+ SetFocus(guildsWidget)
|
|
|
|
|
|
|
|
session.Token = lr.Token
|
|
session.Token = lr.Token
|
|
|
session.Identify.Token = lr.Token
|
|
session.Identify.Token = lr.Token
|
|
@@ -438,6 +438,6 @@ func onLoginFormLoginButtonSelected() {
|
|
|
go keyring.Set("discordo", "token", lr.Token)
|
|
go keyring.Set("discordo", "token", lr.Token)
|
|
|
}, true)
|
|
}, true)
|
|
|
|
|
|
|
|
- app.SetRoot(loginForm, true)
|
|
|
|
|
|
|
+ app.SetRoot(loginWidget, true)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|