guilds.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package ui
  2. import (
  3. "sort"
  4. "github.com/ayntgl/astatine"
  5. "github.com/ayntgl/discordo/discord"
  6. "github.com/rivo/tview"
  7. )
  8. type GuildsList struct {
  9. *tview.List
  10. app *App
  11. }
  12. func NewGuildsList(app *App) *GuildsList {
  13. gl := &GuildsList{
  14. List: tview.NewList(),
  15. app: app,
  16. }
  17. gl.AddItem("Direct Messages", "", 0, nil)
  18. gl.ShowSecondaryText(false)
  19. gl.SetTitle("Guilds")
  20. gl.SetTitleAlign(tview.AlignLeft)
  21. gl.SetBorder(true)
  22. gl.SetBorderPadding(0, 0, 1, 1)
  23. gl.SetSelectedFunc(gl.onSelected)
  24. return gl
  25. }
  26. func (gl *GuildsList) onSelected(idx int, mainText string, secondaryText string, shortcut rune) {
  27. rootTreeNode := gl.app.ChannelsTreeView.GetRoot()
  28. rootTreeNode.ClearChildren()
  29. gl.app.SelectedMessage = -1
  30. gl.app.MessagesTextView.
  31. Highlight().
  32. Clear()
  33. gl.app.MessageInputField.SetText("")
  34. if mainText == "Direct Messages" {
  35. cs := gl.app.Session.State.PrivateChannels
  36. sort.Slice(cs, func(i, j int) bool {
  37. return cs[i].LastMessageID > cs[j].LastMessageID
  38. })
  39. for _, c := range cs {
  40. channelTreeNode := tview.NewTreeNode(discord.ChannelToString(c)).
  41. SetReference(c.ID)
  42. rootTreeNode.AddChild(channelTreeNode)
  43. }
  44. } else { // Guild
  45. // Decrement the index of the selected item by one since the first item in the list is always "Direct Messages".
  46. cs := gl.app.Session.State.Guilds[idx-1].Channels
  47. sort.Slice(cs, func(i, j int) bool {
  48. return cs[i].Position < cs[j].Position
  49. })
  50. for _, c := range cs {
  51. if (c.Type == astatine.ChannelTypeGuildText || c.Type == astatine.ChannelTypeGuildNews) && (c.ParentID == "") {
  52. channelTreeNode := tview.NewTreeNode(discord.ChannelToString(c)).
  53. SetReference(c.ID)
  54. rootTreeNode.AddChild(channelTreeNode)
  55. }
  56. }
  57. CATEGORY:
  58. for _, c := range cs {
  59. if c.Type == astatine.ChannelTypeGuildCategory {
  60. for _, nestedChannel := range cs {
  61. if nestedChannel.ParentID == c.ID {
  62. channelTreeNode := tview.NewTreeNode(c.Name).
  63. SetReference(c.ID)
  64. rootTreeNode.AddChild(channelTreeNode)
  65. continue CATEGORY
  66. }
  67. }
  68. channelTreeNode := tview.NewTreeNode(c.Name).
  69. SetReference(c.ID)
  70. rootTreeNode.AddChild(channelTreeNode)
  71. }
  72. }
  73. for _, c := range cs {
  74. if (c.Type == astatine.ChannelTypeGuildText || c.Type == astatine.ChannelTypeGuildNews) && (c.ParentID != "") {
  75. var parentTreeNode *tview.TreeNode
  76. rootTreeNode.Walk(func(node, _ *tview.TreeNode) bool {
  77. if node.GetReference() == c.ParentID {
  78. parentTreeNode = node
  79. return false
  80. }
  81. return true
  82. })
  83. if parentTreeNode != nil {
  84. channelTreeNode := tview.NewTreeNode(discord.ChannelToString(c)).
  85. SetReference(c.ID)
  86. parentTreeNode.AddChild(channelTreeNode)
  87. }
  88. }
  89. }
  90. }
  91. gl.app.ChannelsTreeView.SetCurrentNode(rootTreeNode)
  92. gl.app.SetFocus(gl.app.ChannelsTreeView)
  93. }