guilds_tree.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "github.com/diamondburned/arikawa/v3/discord"
  6. "github.com/rivo/tview"
  7. )
  8. type GuildsTree struct {
  9. *tview.TreeView
  10. root *tview.TreeNode
  11. }
  12. func newGuildsTree() *GuildsTree {
  13. gt := &GuildsTree{
  14. TreeView: tview.NewTreeView(),
  15. root: tview.NewTreeNode(""),
  16. }
  17. gt.SetRoot(gt.root)
  18. gt.SetTopLevel(1)
  19. gt.SetSelectedFunc(gt.onSelected)
  20. gt.SetTitle("Guilds")
  21. gt.SetBorder(true)
  22. gt.SetBorderPadding(cfg.BorderPadding())
  23. return gt
  24. }
  25. func (gt *GuildsTree) newGuildFromID(n *tview.TreeNode, gid discord.GuildID) error {
  26. g, err := discordState.Cabinet.Guild(gid)
  27. if err != nil {
  28. return err
  29. }
  30. gn := tview.NewTreeNode(g.Name)
  31. gn.SetReference(g.ID)
  32. n.AddChild(gn)
  33. return nil
  34. }
  35. func (gt *GuildsTree) newChannel(n *tview.TreeNode, c discord.Channel) {
  36. cn := tview.NewTreeNode(gt.channelToString(c))
  37. cn.SetReference(c.ID)
  38. n.AddChild(cn)
  39. }
  40. func (gt *GuildsTree) channelToString(c discord.Channel) string {
  41. switch c.Type {
  42. case discord.GuildText:
  43. return "#" + c.Name
  44. case discord.GuildVoice:
  45. return "v-" + c.Name
  46. case discord.GuildNews:
  47. return "n-" + c.Name
  48. case discord.GuildStore:
  49. return "s-" + c.Name
  50. default:
  51. return c.Name
  52. }
  53. }
  54. func (gt *GuildsTree) onSelected(n *tview.TreeNode) {
  55. if len(n.GetChildren()) != 0 {
  56. n.SetExpanded(!n.IsExpanded())
  57. }
  58. switch ref := n.GetReference().(type) {
  59. case discord.GuildID:
  60. cs, err := discordState.Cabinet.Channels(ref)
  61. if err != nil {
  62. log.Println(err)
  63. return
  64. }
  65. // Orphan (top-level) channels
  66. for _, c := range cs {
  67. if c.Type != discord.GuildCategory && !c.ParentID.IsValid() {
  68. gt.newChannel(n, c)
  69. }
  70. }
  71. // Category channels
  72. CATEGORY:
  73. for _, c := range cs {
  74. if c.Type == discord.GuildCategory {
  75. for _, nestedChannel := range cs {
  76. if nestedChannel.ParentID == c.ID {
  77. gt.newChannel(n, c)
  78. continue CATEGORY
  79. }
  80. }
  81. gt.newChannel(n, c)
  82. }
  83. }
  84. // Children (category-bound) channels
  85. for _, c := range cs {
  86. if c.ParentID.IsValid() {
  87. var parent *tview.TreeNode
  88. n.Walk(func(node, _ *tview.TreeNode) bool {
  89. if node.GetReference() == c.ParentID {
  90. parent = node
  91. return false
  92. }
  93. return true
  94. })
  95. if parent != nil {
  96. gt.newChannel(parent, c)
  97. }
  98. }
  99. }
  100. case discord.ChannelID:
  101. messagesText.Clear()
  102. c, err := discordState.Cabinet.Channel(ref)
  103. if err != nil {
  104. log.Println(err)
  105. return
  106. }
  107. ms, err := discordState.Messages(ref, cfg.MessagesLimit)
  108. if err != nil {
  109. log.Println(err)
  110. return
  111. }
  112. for _, m := range ms {
  113. if messagesText.newMessage(&m); err != nil {
  114. fmt.Println(err)
  115. continue
  116. }
  117. }
  118. messagesText.SetTitle(gt.channelToString(*c))
  119. app.SetFocus(messagesText)
  120. }
  121. }