refactor: modularize func to reduce cyclomatic complexity

This commit is contained in:
ayntgl 2021-10-16 18:50:57 +04:00
parent 2d95068ded
commit f486f54f1c
3 changed files with 178 additions and 165 deletions

View file

@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"regexp"
"sort"
"strings"
"github.com/ayntgl/discordgo"
@ -42,60 +41,11 @@ func newSession() *discordgo.Session {
func onSessionReady(_ *discordgo.Session, r *discordgo.Ready) {
dmNode := tview.NewTreeNode("Direct Messages").
Collapse()
n := channelsTree.GetRoot()
n.AddChild(dmNode)
sort.Slice(r.PrivateChannels, func(i, j int) bool {
return r.PrivateChannels[i].LastMessageID > r.PrivateChannels[j].LastMessageID
})
for _, c := range r.PrivateChannels {
var tag string
if isUnread(c) {
tag = "[::b]"
} else {
tag = "[::d]"
}
cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
SetReference(c.ID)
dmNode.AddChild(cn)
}
sort.Slice(r.Guilds, func(a, b int) bool {
found := false
for _, gID := range r.Settings.GuildPositions {
if found {
if gID == r.Guilds[b].ID {
return true
}
} else {
if gID == r.Guilds[a].ID {
found = true
}
}
}
return false
})
for _, g := range r.Guilds {
gn := tview.NewTreeNode(g.Name).Collapse()
n.AddChild(gn)
cs := g.Channels
sort.Slice(cs, func(i, j int) bool {
return cs[i].Position < cs[j].Position
})
// Top-level channels
createTopLevelChannelsTreeNodes(gn, cs)
// Category channels
createCategoryChannelsTreeNodes(gn, cs)
// Second-level channels
createSecondLevelChannelsTreeNodes(cs)
}
createPrivateChannels(r.PrivateChannels, dmNode)
createGuilds(r.Guilds, n)
channelsTree.SetCurrentNode(n)
}

113
ui.go
View file

@ -104,119 +104,6 @@ func onChannelsTreeSelected(n *tview.TreeNode) {
}
}
func generateChannelRepr(c *discordgo.Channel) string {
var repr string
if c.Name != "" {
repr = "#" + c.Name
} else if len(c.Recipients) == 1 {
rp := c.Recipients[0]
repr = rp.Username + "#" + rp.Discriminator
} else {
rps := make([]string, len(c.Recipients))
for i, r := range c.Recipients {
rps[i] = r.Username + "#" + r.Discriminator
}
repr = strings.Join(rps, ", ")
}
return repr
}
func createTopLevelChannelsTreeNodes(
n *tview.TreeNode,
cs []*discordgo.Channel,
) {
for _, c := range cs {
if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
(c.ParentID == "") {
p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
continue
}
var tag string
if isUnread(c) {
tag = "[::b]"
} else {
tag = "[::d]"
}
cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
SetReference(c.ID)
n.AddChild(cn)
continue
}
}
}
func createCategoryChannelsTreeNodes(
n *tview.TreeNode,
cs []*discordgo.Channel,
) {
CategoryLoop:
for _, c := range cs {
if c.Type == discordgo.ChannelTypeGuildCategory {
p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
continue
}
for _, child := range cs {
if child.ParentID == c.ID {
cn := tview.NewTreeNode(c.Name).
SetReference(c.ID)
n.AddChild(cn)
continue CategoryLoop
}
}
cn := tview.NewTreeNode(c.Name).
SetReference(c.ID)
n.AddChild(cn)
}
}
}
func createSecondLevelChannelsTreeNodes(cs []*discordgo.Channel) {
for _, c := range cs {
if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
(c.ParentID != "") {
p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
continue
}
var tag string
if isUnread(c) {
tag = "[::b]"
} else {
tag = "[::d]"
}
pn := getTreeNodeByReference(c.ParentID)
if pn != nil {
cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
SetReference(c.ID)
pn.AddChild(cn)
}
}
}
}
func getTreeNodeByReference(r interface{}) (mn *tview.TreeNode) {
channelsTree.GetRoot().Walk(func(n, _ *tview.TreeNode) bool {
if n.GetReference() == r {
mn = n
return false
}
return true
})
return
}
func newMessagesView() *tview.TextView {
textView := tview.NewTextView()
textView.

176
util.go
View file

@ -1,5 +1,32 @@
package main
import (
"sort"
"strings"
"github.com/ayntgl/discordgo"
"github.com/rivo/tview"
)
func generateChannelRepr(c *discordgo.Channel) string {
var repr string
if c.Name != "" {
repr = "#" + c.Name
} else if len(c.Recipients) == 1 {
rp := c.Recipients[0]
repr = rp.Username + "#" + rp.Discriminator
} else {
rps := make([]string, len(c.Recipients))
for i, r := range c.Recipients {
rps[i] = r.Username + "#" + r.Discriminator
}
repr = strings.Join(rps, ", ")
}
return repr
}
func findIndexByMessageID(mID string) int {
for i, m := range selectedChannel.Messages {
if m.ID == mID {
@ -9,3 +36,152 @@ func findIndexByMessageID(mID string) int {
return -1
}
func createPrivateChannels(cs []*discordgo.Channel, dmNode *tview.TreeNode) {
sort.Slice(cs, func(i, j int) bool {
return cs[i].LastMessageID > cs[j].LastMessageID
})
for _, c := range cs {
var tag string
if isUnread(c) {
tag = "[::b]"
} else {
tag = "[::d]"
}
cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
SetReference(c.ID)
dmNode.AddChild(cn)
}
}
func createGuilds(gs []*discordgo.Guild, rootNode *tview.TreeNode) {
sort.Slice(gs, func(a, b int) bool {
found := false
for _, gID := range session.State.Settings.GuildPositions {
if found {
if gID == gs[b].ID {
return true
}
} else {
if gID == gs[a].ID {
found = true
}
}
}
return false
})
for _, g := range gs {
gn := tview.NewTreeNode(g.Name).Collapse()
rootNode.AddChild(gn)
cs := g.Channels
sort.Slice(cs, func(i, j int) bool {
return cs[i].Position < cs[j].Position
})
// Top-level channels
createTopLevelChannelsTreeNodes(gn, cs)
// Category channels
createCategoryChannelsTreeNodes(gn, cs)
// Second-level channels
createSecondLevelChannelsTreeNodes(cs)
}
}
func createTopLevelChannelsTreeNodes(
n *tview.TreeNode,
cs []*discordgo.Channel,
) {
for _, c := range cs {
if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
(c.ParentID == "") {
p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
continue
}
var tag string
if isUnread(c) {
tag = "[::b]"
} else {
tag = "[::d]"
}
cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
SetReference(c.ID)
n.AddChild(cn)
continue
}
}
}
func createCategoryChannelsTreeNodes(
n *tview.TreeNode,
cs []*discordgo.Channel,
) {
CategoryLoop:
for _, c := range cs {
if c.Type == discordgo.ChannelTypeGuildCategory {
p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
continue
}
for _, child := range cs {
if child.ParentID == c.ID {
cn := tview.NewTreeNode(c.Name).
SetReference(c.ID)
n.AddChild(cn)
continue CategoryLoop
}
}
cn := tview.NewTreeNode(c.Name).
SetReference(c.ID)
n.AddChild(cn)
}
}
}
func createSecondLevelChannelsTreeNodes(cs []*discordgo.Channel) {
for _, c := range cs {
if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
(c.ParentID != "") {
p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
continue
}
var tag string
if isUnread(c) {
tag = "[::b]"
} else {
tag = "[::d]"
}
pn := getTreeNodeByReference(c.ParentID)
if pn != nil {
cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
SetReference(c.ID)
pn.AddChild(cn)
}
}
}
}
func getTreeNodeByReference(r interface{}) (mn *tview.TreeNode) {
channelsTree.GetRoot().Walk(func(n, _ *tview.TreeNode) bool {
if n.GetReference() == r {
mn = n
return false
}
return true
})
return
}