guilds.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package ui
  2. import (
  3. "sort"
  4. dsc "github.com/diamondburned/arikawa/v3/discord"
  5. "github.com/rivo/tview"
  6. )
  7. type GuildsTree struct {
  8. *tview.TreeView
  9. app *App
  10. }
  11. func NewGuildsTree(app *App) *GuildsTree {
  12. gt := &GuildsTree{
  13. TreeView: tview.NewTreeView(),
  14. app: app,
  15. }
  16. rootNode := tview.NewTreeNode("")
  17. rootNode.AddChild(tview.NewTreeNode("Direct Messages"))
  18. gt.SetRoot(rootNode)
  19. gt.SetTopLevel(1)
  20. gt.SetSelectedFunc(gt.onSelected)
  21. gt.SetTitle("Guilds")
  22. gt.SetTitleAlign(tview.AlignLeft)
  23. gt.SetBorder(true)
  24. gt.SetBorderPadding(0, 0, 1, 1)
  25. return gt
  26. }
  27. func (gt *GuildsTree) onSelected(node *tview.TreeNode) {
  28. gt.app.SelectedChannel = nil
  29. gt.app.SelectedMessage = -1
  30. rootNode := gt.app.ChannelsTree.GetRoot()
  31. rootNode.ClearChildren()
  32. gt.app.MessagesTextView.
  33. Highlight().
  34. Clear().
  35. SetTitle("")
  36. gt.app.MessageInputField.SetText("")
  37. ref := node.GetReference()
  38. // If the reference of the selected node is nil, it must be the direct messages node.
  39. if ref == nil {
  40. cs, err := gt.app.State.Cabinet.PrivateChannels()
  41. if err != nil {
  42. return
  43. }
  44. sort.Slice(cs, func(i, j int) bool {
  45. return cs[i].LastMessageID > cs[j].LastMessageID
  46. })
  47. for _, c := range cs {
  48. channelNode := tview.NewTreeNode(c.Name)
  49. channelNode.SetReference(c.ID)
  50. rootNode.AddChild(channelNode)
  51. }
  52. } else { // Guild
  53. cs, err := gt.app.State.Cabinet.Channels(ref.(dsc.GuildID))
  54. if err != nil {
  55. return
  56. }
  57. sort.Slice(cs, func(i, j int) bool {
  58. return cs[i].Position < cs[j].Position
  59. })
  60. for _, c := range cs {
  61. if (c.Type == dsc.GuildText || c.Type == dsc.GuildNews) && (!c.ParentID.IsValid()) {
  62. channelNode := tview.NewTreeNode(channelToString(c))
  63. channelNode.SetReference(c.ID)
  64. rootNode.AddChild(channelNode)
  65. }
  66. }
  67. CATEGORY:
  68. for _, c := range cs {
  69. if c.Type == dsc.GuildCategory {
  70. for _, nestedChannel := range cs {
  71. if nestedChannel.ParentID == c.ID {
  72. channelNode := tview.NewTreeNode(c.Name)
  73. channelNode.SetReference(c.ID)
  74. rootNode.AddChild(channelNode)
  75. continue CATEGORY
  76. }
  77. }
  78. channelNode := tview.NewTreeNode(channelToString(c))
  79. channelNode.SetReference(c.ID)
  80. rootNode.AddChild(channelNode)
  81. }
  82. }
  83. for _, c := range cs {
  84. if (c.Type == dsc.GuildText || c.Type == dsc.GuildNews) && (c.ParentID.IsValid()) {
  85. var parentNode *tview.TreeNode
  86. rootNode.Walk(func(node, _ *tview.TreeNode) bool {
  87. if node.GetReference() == c.ParentID {
  88. parentNode = node
  89. return false
  90. }
  91. return true
  92. })
  93. if parentNode != nil {
  94. channelNode := tview.NewTreeNode(channelToString(c))
  95. channelNode.SetReference(c.ID)
  96. parentNode.AddChild(channelNode)
  97. }
  98. }
  99. }
  100. }
  101. gt.app.ChannelsTree.SetCurrentNode(rootNode)
  102. gt.app.SetFocus(gt.app.ChannelsTree)
  103. }