feat: merge channels & guilds TreeView for ease-of-use (#37)
* feat: merge channels & guilds TreeView for ease-of-use * docs: update README preview
This commit is contained in:
parent
88e27fa413
commit
93a422bc9e
5 changed files with 50 additions and 75 deletions
BIN
.github/preview.png
vendored
BIN
.github/preview.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 197 KiB |
|
|
@ -43,10 +43,9 @@ By default, Discordo utilizes OS-specific keyring to store credentials such as c
|
|||
|
||||
### Default Keybindings
|
||||
|
||||
- `Alt` + `g`: Sets the focus on the guilds treeview.
|
||||
- `Alt` + `c`: Sets the focus on the channels treeview.
|
||||
- `Alt` + `m`: Sets the focus on the messages textview.
|
||||
- `Alt` + `i`: Sets the focus on the message inputfield.
|
||||
- `Alt` + `g`: Sets the focus on the guilds TreeView.
|
||||
- `Alt` + `m`: Sets the focus on the messages TextView.
|
||||
- `Alt` + `i`: Sets the focus on the message InputField.
|
||||
|
||||
### Clipboard
|
||||
|
||||
|
|
|
|||
75
discordo.go
75
discordo.go
|
|
@ -16,7 +16,6 @@ var (
|
|||
app *tview.Application
|
||||
loginForm *tview.Form
|
||||
guildsTreeView *tview.TreeView
|
||||
channelsTreeView *tview.TreeView
|
||||
messagesTextView *tview.TextView
|
||||
messageInputField *tview.InputField
|
||||
mainFlex *tview.Flex
|
||||
|
|
@ -37,10 +36,9 @@ func main() {
|
|||
EnableMouse(config.Mouse).
|
||||
SetInputCapture(onAppInputCapture)
|
||||
guildsTreeView = ui.NewGuildsTreeView(onGuildsTreeViewSelected)
|
||||
channelsTreeView = ui.NewChannelsTreeView(onChannelsTreeViewSelected)
|
||||
messagesTextView = ui.NewMessagesTextView(app)
|
||||
messageInputField = ui.NewMessageInputField(onMessageInputFieldInputCapture)
|
||||
mainFlex = ui.NewMainFlex(guildsTreeView, channelsTreeView, messagesTextView, messageInputField)
|
||||
mainFlex = ui.NewMainFlex(guildsTreeView, messagesTextView, messageInputField)
|
||||
|
||||
token := config.Token
|
||||
if t := util.GetPassword("token"); t != "" {
|
||||
|
|
@ -72,8 +70,6 @@ func onAppInputCapture(e *tcell.EventKey) *tcell.EventKey {
|
|||
switch e.Name() {
|
||||
case "Alt+Rune[g]":
|
||||
app.SetFocus(guildsTreeView)
|
||||
case "Alt+Rune[c]":
|
||||
app.SetFocus(channelsTreeView)
|
||||
case "Alt+Rune[m]":
|
||||
app.SetFocus(messagesTextView)
|
||||
case "Alt+Rune[i]":
|
||||
|
|
@ -145,14 +141,14 @@ func onSessionReady(_ *discordgo.Session, r *discordgo.Ready) {
|
|||
return false
|
||||
})
|
||||
|
||||
rootN := guildsTreeView.GetRoot()
|
||||
n := guildsTreeView.GetRoot()
|
||||
for _, g := range r.Guilds {
|
||||
gn := tview.NewTreeNode(g.Name).
|
||||
SetReference(g.ID)
|
||||
rootN.AddChild(gn)
|
||||
n.AddChild(gn)
|
||||
}
|
||||
|
||||
guildsTreeView.SetCurrentNode(rootN)
|
||||
guildsTreeView.SetCurrentNode(n)
|
||||
}
|
||||
|
||||
func onSessionMessageCreate(_ *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
|
|
@ -161,40 +157,41 @@ func onSessionMessageCreate(_ *discordgo.Session, m *discordgo.MessageCreate) {
|
|||
}
|
||||
}
|
||||
|
||||
func onGuildsTreeViewSelected(gn *tview.TreeNode) {
|
||||
selectedChannel = nil
|
||||
app.SetFocus(channelsTreeView)
|
||||
messagesTextView.
|
||||
Clear().
|
||||
SetTitle("")
|
||||
func onGuildsTreeViewSelected(n *tview.TreeNode) {
|
||||
switch n.GetLevel() {
|
||||
case 1:
|
||||
if len(n.GetChildren()) != 0 {
|
||||
n.SetExpanded(!n.IsExpanded())
|
||||
return
|
||||
}
|
||||
|
||||
gID := gn.GetReference().(string)
|
||||
g, _ := session.State.Guild(gID)
|
||||
cs := g.Channels
|
||||
sort.Slice(cs, func(i, j int) bool {
|
||||
return cs[i].Position < cs[j].Position
|
||||
})
|
||||
selectedChannel = nil
|
||||
n.ClearChildren()
|
||||
messagesTextView.
|
||||
Clear().
|
||||
SetTitle("")
|
||||
|
||||
rootN := channelsTreeView.GetRoot()
|
||||
rootN.ClearChildren()
|
||||
// Top-level channels
|
||||
ui.CreateTopLevelChannelsTreeNodes(session.State, rootN, cs)
|
||||
// Category channels
|
||||
ui.CreateCategoryChannelsTreeNodes(session.State, rootN, cs)
|
||||
// Second-level channels
|
||||
ui.CreateSecondLevelChannelsTreeNodes(session.State, channelsTreeView, rootN, cs)
|
||||
gID := n.GetReference().(string)
|
||||
g, _ := session.State.Guild(gID)
|
||||
|
||||
channelsTreeView.SetCurrentNode(rootN)
|
||||
}
|
||||
cs := g.Channels
|
||||
sort.Slice(cs, func(i, j int) bool {
|
||||
return cs[i].Position < cs[j].Position
|
||||
})
|
||||
|
||||
func onChannelsTreeViewSelected(n *tview.TreeNode) {
|
||||
cID := n.GetReference().(string)
|
||||
c, _ := session.State.Channel(cID)
|
||||
switch c.Type {
|
||||
case discordgo.ChannelTypeGuildCategory:
|
||||
n.SetExpanded(!n.IsExpanded())
|
||||
case discordgo.ChannelTypeGuildText, discordgo.ChannelTypeGuildNews:
|
||||
if len(n.GetChildren()) == 0 {
|
||||
// Top-level channels
|
||||
ui.CreateTopLevelChannelsTreeNodes(session.State, n, cs)
|
||||
// Category channels
|
||||
ui.CreateCategoryChannelsTreeNodes(session.State, n, cs)
|
||||
// Second-level channels
|
||||
ui.CreateSecondLevelChannelsTreeNodes(session.State, guildsTreeView, cs)
|
||||
default:
|
||||
cID := n.GetReference().(string)
|
||||
c, _ := session.State.Channel(cID)
|
||||
|
||||
if c.Type == discordgo.ChannelTypeGuildCategory {
|
||||
n.SetExpanded(!n.IsExpanded())
|
||||
} else if c.Type == discordgo.ChannelTypeGuildNews || c.Type == discordgo.ChannelTypeGuildText {
|
||||
selectedChannel = c
|
||||
app.SetFocus(messageInputField)
|
||||
|
||||
|
|
@ -207,8 +204,6 @@ func onChannelsTreeViewSelected(n *tview.TreeNode) {
|
|||
SetTitle(title)
|
||||
|
||||
go writeMessages(c.ID)
|
||||
} else {
|
||||
n.SetExpanded(!n.IsExpanded())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,13 @@ import (
|
|||
)
|
||||
|
||||
// NewMainFlex creates and returns a new main flex.
|
||||
func NewMainFlex(gTreeV *tview.TreeView, cTreeV *tview.TreeView, textV *tview.TextView, i *tview.InputField) *tview.Flex {
|
||||
lf := tview.NewFlex().
|
||||
SetDirection(tview.FlexRow).
|
||||
AddItem(gTreeV, 0, 1, false).
|
||||
AddItem(cTreeV, 0, 2, false)
|
||||
func NewMainFlex(treeV *tview.TreeView, textV *tview.TextView, i *tview.InputField) *tview.Flex {
|
||||
rf := tview.NewFlex().
|
||||
SetDirection(tview.FlexRow).
|
||||
AddItem(textV, 0, 1, false).
|
||||
AddItem(i, 3, 1, false)
|
||||
mf := tview.NewFlex().
|
||||
AddItem(lf, 0, 1, false).
|
||||
AddItem(treeV, 0, 1, false).
|
||||
AddItem(rf, 0, 4, false)
|
||||
|
||||
return mf
|
||||
|
|
|
|||
|
|
@ -21,21 +21,6 @@ func NewGuildsTreeView(onGuildsTreeViewSelected func(*tview.TreeNode)) *tview.Tr
|
|||
return v
|
||||
}
|
||||
|
||||
// NewChannelsTreeView creates and returns a new channels treeview.
|
||||
func NewChannelsTreeView(onChannelsTreeViewSelected func(*tview.TreeNode)) *tview.TreeView {
|
||||
v := tview.NewTreeView()
|
||||
v.
|
||||
SetTopLevel(1).
|
||||
SetRoot(tview.NewTreeNode("")).
|
||||
SetSelectedFunc(onChannelsTreeViewSelected).
|
||||
SetBorder(true).
|
||||
SetBorderPadding(0, 0, 1, 0).
|
||||
SetTitle("Channels").
|
||||
SetTitleAlign(tview.AlignLeft)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// NewTextChannelTreeNode creates and returns a new text channel treenode.
|
||||
func NewTextChannelTreeNode(c *discordgo.Channel) *tview.TreeNode {
|
||||
n := tview.NewTreeNode("[::d]#" + c.Name + "[::-]").
|
||||
|
|
@ -58,8 +43,8 @@ func GetTreeNodeByReference(r interface{}, treeV *tview.TreeView) (mn *tview.Tre
|
|||
return
|
||||
}
|
||||
|
||||
// CreateTopLevelChannelsTreeNodes creates treenodes for the top-level (orphan) channels.
|
||||
func CreateTopLevelChannelsTreeNodes(s *discordgo.State, rootN *tview.TreeNode, cs []*discordgo.Channel) {
|
||||
// CreateTopLevelChannelsTreeNodes creates TreeNodes for the top-level (orphan) channels.
|
||||
func CreateTopLevelChannelsTreeNodes(s *discordgo.State, n *tview.TreeNode, cs []*discordgo.Channel) {
|
||||
for _, c := range cs {
|
||||
if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) && (c.ParentID == "") {
|
||||
if !util.HasPermission(s, s.User.ID, c.ID, discordgo.PermissionViewChannel) {
|
||||
|
|
@ -67,14 +52,14 @@ func CreateTopLevelChannelsTreeNodes(s *discordgo.State, rootN *tview.TreeNode,
|
|||
}
|
||||
|
||||
cn := NewTextChannelTreeNode(c)
|
||||
rootN.AddChild(cn)
|
||||
n.AddChild(cn)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCategoryChannelsTreeNodes creates treenodes for the category channels.
|
||||
func CreateCategoryChannelsTreeNodes(s *discordgo.State, rootN *tview.TreeNode, cs []*discordgo.Channel) {
|
||||
// CreateCategoryChannelsTreeNodes creates TreeNodes for the category (parent) channels.
|
||||
func CreateCategoryChannelsTreeNodes(s *discordgo.State, n *tview.TreeNode, cs []*discordgo.Channel) {
|
||||
CategoryLoop:
|
||||
for _, c := range cs {
|
||||
if c.Type == discordgo.ChannelTypeGuildCategory {
|
||||
|
|
@ -86,27 +71,27 @@ CategoryLoop:
|
|||
if child.ParentID == c.ID {
|
||||
cn := tview.NewTreeNode(c.Name).
|
||||
SetReference(c.ID)
|
||||
rootN.AddChild(cn)
|
||||
n.AddChild(cn)
|
||||
continue CategoryLoop
|
||||
}
|
||||
}
|
||||
|
||||
cn := tview.NewTreeNode(c.Name).
|
||||
SetReference(c.ID)
|
||||
rootN.AddChild(cn)
|
||||
n.AddChild(cn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CreateSecondLevelChannelsTreeNodes creates treenodes for the second-level (category children) channels.
|
||||
func CreateSecondLevelChannelsTreeNodes(s *discordgo.State, channelsTreeView *tview.TreeView, rootN *tview.TreeNode, cs []*discordgo.Channel) {
|
||||
// CreateSecondLevelChannelsTreeNodes creates TreeNodes for the second-level (category children) channels.
|
||||
func CreateSecondLevelChannelsTreeNodes(s *discordgo.State, treeV *tview.TreeView, cs []*discordgo.Channel) {
|
||||
for _, c := range cs {
|
||||
if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) && (c.ParentID != "") {
|
||||
if !util.HasPermission(s, s.User.ID, c.ID, discordgo.PermissionViewChannel) {
|
||||
continue
|
||||
}
|
||||
|
||||
if pn := GetTreeNodeByReference(c.ParentID, channelsTreeView); pn != nil {
|
||||
if pn := GetTreeNodeByReference(c.ParentID, treeV); pn != nil {
|
||||
cn := NewTextChannelTreeNode(c)
|
||||
pn.AddChild(cn)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue