ui.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package util
  2. import (
  3. "github.com/ayntgl/discordgo"
  4. "github.com/rivo/tview"
  5. )
  6. // GetTreeNodeByReference walks the root `*TreeNode` of the given `*TreeView` *treeView* and returns the TreeNode whose reference is equal to the given reference *r*. If the `*TreeNode` is not found, `nil` is returned instead.
  7. func GetTreeNodeByReference(treeView *tview.TreeView, r interface{}) (mn *tview.TreeNode) {
  8. treeView.GetRoot().Walk(func(n, _ *tview.TreeNode) bool {
  9. if n.GetReference() == r {
  10. mn = n
  11. return false
  12. }
  13. return true
  14. })
  15. return
  16. }
  17. // CreateTopLevelChannelsNodes builds and creates `*tview.TreeNode`s for top-level (channels that have an empty parent ID and of type GUILD_TEXT, GUILD_NEWS) channels. If the client user does not have the VIEW_CHANNEL permission for a channel, the channel is excluded from the parent.
  18. func CreateTopLevelChannelsNodes(treeView *tview.TreeView, s *discordgo.State, n *tview.TreeNode, cs []*discordgo.Channel) {
  19. for _, c := range cs {
  20. if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
  21. (c.ParentID == "") {
  22. if !HasPermission(s, c.ID, discordgo.PermissionViewChannel) {
  23. continue
  24. }
  25. n.AddChild(CreateChannelNode(s, c))
  26. continue
  27. }
  28. }
  29. }
  30. // CreateCategoryChannelsNodes builds and creates `*tview.TreeNode`s for category (type: GUILD_CATEGORY) channels. If the client user does not have the VIEW_CHANNEL permission for a channel, the channel is excluded from the parent.
  31. func CreateCategoryChannelsNodes(treeView *tview.TreeView, s *discordgo.State, n *tview.TreeNode, cs []*discordgo.Channel) {
  32. CategoryLoop:
  33. for _, c := range cs {
  34. if c.Type == discordgo.ChannelTypeGuildCategory {
  35. if !HasPermission(s, c.ID, discordgo.PermissionViewChannel) {
  36. continue
  37. }
  38. for _, child := range cs {
  39. if child.ParentID == c.ID {
  40. n.AddChild(CreateChannelNode(s, c))
  41. continue CategoryLoop
  42. }
  43. }
  44. n.AddChild(CreateChannelNode(s, c))
  45. }
  46. }
  47. }
  48. // CreateSecondLevelChannelsNodes builds and creates `*tview.TreeNode`s for second-level (channels that have a non-empty parent ID and of type GUILD_TEXT, GUILD_NEWS) channels. If the client user does not have the VIEW_CHANNEL permission for a channel, the channel is excluded from the parent.
  49. func CreateSecondLevelChannelsNodes(treeView *tview.TreeView, s *discordgo.State, cs []*discordgo.Channel) {
  50. for _, c := range cs {
  51. if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
  52. (c.ParentID != "") {
  53. if !HasPermission(s, c.ID, discordgo.PermissionViewChannel) {
  54. continue
  55. }
  56. pn := GetTreeNodeByReference(treeView, c.ParentID)
  57. if pn != nil {
  58. pn.AddChild(CreateChannelNode(s, c))
  59. }
  60. }
  61. }
  62. }
  63. // CreateChannelNode builds (encorporates unread channels in bold tag, otherwise dim, etc.) and returns a node according to the type of the given channel *c*.
  64. func CreateChannelNode(s *discordgo.State, c *discordgo.Channel) *tview.TreeNode {
  65. var cn *tview.TreeNode
  66. switch c.Type {
  67. case discordgo.ChannelTypeGuildText, discordgo.ChannelTypeGuildNews:
  68. tag := "[::d]"
  69. if ChannelIsUnread(s, c) {
  70. tag = "[::b]"
  71. }
  72. cn = tview.NewTreeNode(tag + ChannelToString(c) + "[::-]").
  73. SetReference(c.ID)
  74. case discordgo.ChannelTypeGuildCategory:
  75. cn = tview.NewTreeNode(c.Name).
  76. SetReference(c.ID)
  77. }
  78. return cn
  79. }
  80. // HasPermission returns a boolean that indicates whether the client user has the given permission *p* in the given channel ID *cID*.
  81. func HasPermission(s *discordgo.State, cID string, p int64) bool {
  82. perm, err := s.UserChannelPermissions(s.User.ID, cID)
  83. if err != nil {
  84. return false
  85. }
  86. return perm&p == p
  87. }
  88. func HasKeybinding(sl []string, s string) bool {
  89. for _, str := range sl {
  90. if str == s {
  91. return true
  92. }
  93. }
  94. return false
  95. }