util.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package main
  2. import (
  3. "sort"
  4. "strings"
  5. "github.com/ayntgl/discordgo"
  6. "github.com/rivo/tview"
  7. )
  8. func generateChannelRepr(c *discordgo.Channel) string {
  9. var repr string
  10. if c.Name != "" {
  11. repr = "#" + c.Name
  12. } else if len(c.Recipients) == 1 {
  13. rp := c.Recipients[0]
  14. repr = rp.Username + "#" + rp.Discriminator
  15. } else {
  16. rps := make([]string, len(c.Recipients))
  17. for i, r := range c.Recipients {
  18. rps[i] = r.Username + "#" + r.Discriminator
  19. }
  20. repr = strings.Join(rps, ", ")
  21. }
  22. return repr
  23. }
  24. func findByMessageID(mID string) *discordgo.Message {
  25. for _, m := range selectedChannel.Messages {
  26. if m.ID == mID {
  27. return m
  28. }
  29. }
  30. return nil
  31. }
  32. func createPrivateChannels(cs []*discordgo.Channel, dmNode *tview.TreeNode) {
  33. sort.Slice(cs, func(i, j int) bool {
  34. return cs[i].LastMessageID > cs[j].LastMessageID
  35. })
  36. for _, c := range cs {
  37. var tag string
  38. if isUnread(c) {
  39. tag = "[::b]"
  40. } else {
  41. tag = "[::d]"
  42. }
  43. cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
  44. SetReference(c.ID)
  45. dmNode.AddChild(cn)
  46. }
  47. }
  48. func createGuilds(gs []*discordgo.Guild, rootNode *tview.TreeNode) {
  49. sort.Slice(gs, func(a, b int) bool {
  50. found := false
  51. for _, gID := range session.State.Settings.GuildPositions {
  52. if found {
  53. if gID == gs[b].ID {
  54. return true
  55. }
  56. } else {
  57. if gID == gs[a].ID {
  58. found = true
  59. }
  60. }
  61. }
  62. return false
  63. })
  64. for _, g := range gs {
  65. gn := tview.NewTreeNode(g.Name).Collapse()
  66. rootNode.AddChild(gn)
  67. cs := g.Channels
  68. sort.Slice(cs, func(i, j int) bool {
  69. return cs[i].Position < cs[j].Position
  70. })
  71. // Top-level channels
  72. createTopLevelChannelsTreeNodes(gn, cs)
  73. // Category channels
  74. createCategoryChannelsTreeNodes(gn, cs)
  75. // Second-level channels
  76. createSecondLevelChannelsTreeNodes(cs)
  77. }
  78. }
  79. func createTopLevelChannelsTreeNodes(
  80. n *tview.TreeNode,
  81. cs []*discordgo.Channel,
  82. ) {
  83. for _, c := range cs {
  84. if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
  85. (c.ParentID == "") {
  86. p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
  87. if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
  88. continue
  89. }
  90. var tag string
  91. if isUnread(c) {
  92. tag = "[::b]"
  93. } else {
  94. tag = "[::d]"
  95. }
  96. cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
  97. SetReference(c.ID)
  98. n.AddChild(cn)
  99. continue
  100. }
  101. }
  102. }
  103. func createCategoryChannelsTreeNodes(
  104. n *tview.TreeNode,
  105. cs []*discordgo.Channel,
  106. ) {
  107. CategoryLoop:
  108. for _, c := range cs {
  109. if c.Type == discordgo.ChannelTypeGuildCategory {
  110. p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
  111. if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
  112. continue
  113. }
  114. for _, child := range cs {
  115. if child.ParentID == c.ID {
  116. cn := tview.NewTreeNode(c.Name).
  117. SetReference(c.ID)
  118. n.AddChild(cn)
  119. continue CategoryLoop
  120. }
  121. }
  122. cn := tview.NewTreeNode(c.Name).
  123. SetReference(c.ID)
  124. n.AddChild(cn)
  125. }
  126. }
  127. }
  128. func createSecondLevelChannelsTreeNodes(cs []*discordgo.Channel) {
  129. for _, c := range cs {
  130. if (c.Type == discordgo.ChannelTypeGuildText || c.Type == discordgo.ChannelTypeGuildNews) &&
  131. (c.ParentID != "") {
  132. p, err := session.State.UserChannelPermissions(session.State.User.ID, c.ID)
  133. if err != nil || p&discordgo.PermissionViewChannel != discordgo.PermissionViewChannel {
  134. continue
  135. }
  136. var tag string
  137. if isUnread(c) {
  138. tag = "[::b]"
  139. } else {
  140. tag = "[::d]"
  141. }
  142. pn := getTreeNodeByReference(c.ParentID)
  143. if pn != nil {
  144. cn := tview.NewTreeNode(tag + generateChannelRepr(c) + "[::-]").
  145. SetReference(c.ID)
  146. pn.AddChild(cn)
  147. }
  148. }
  149. }
  150. }
  151. func getTreeNodeByReference(r interface{}) (mn *tview.TreeNode) {
  152. channelsTree.GetRoot().Walk(func(n, _ *tview.TreeNode) bool {
  153. if n.GetReference() == r {
  154. mn = n
  155. return false
  156. }
  157. return true
  158. })
  159. return
  160. }