main.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package main
  2. import (
  3. "github.com/ayntgl/discordgo"
  4. "github.com/ayntgl/discordo/ui"
  5. "github.com/ayntgl/discordo/util"
  6. "github.com/gdamore/tcell/v2"
  7. "github.com/rivo/tview"
  8. "github.com/zalando/go-keyring"
  9. )
  10. const service = "discordo"
  11. var (
  12. app *tview.Application
  13. loginForm *tview.Form
  14. channelsTreeView *tview.TreeView
  15. messagesTextView *tview.TextView
  16. messageInputField *tview.InputField
  17. mainFlex *tview.Flex
  18. conf *util.Config
  19. session *discordgo.Session
  20. selectedChannel *discordgo.Channel
  21. selectedMessage int = -1
  22. )
  23. func main() {
  24. conf = util.LoadConfig()
  25. tview.Borders.Horizontal = conf.Borders.Horizontal
  26. tview.Borders.Vertical = conf.Borders.Vertical
  27. tview.Borders.TopLeft = conf.Borders.TopLeft
  28. tview.Borders.TopRight = conf.Borders.TopRight
  29. tview.Borders.BottomLeft = conf.Borders.BottomLeft
  30. tview.Borders.BottomRight = conf.Borders.BottomRight
  31. tview.Borders.HorizontalFocus = conf.Borders.HorizontalFocus
  32. tview.Borders.VerticalFocus = conf.Borders.VerticalFocus
  33. tview.Borders.TopLeftFocus = conf.Borders.TopLeftFocus
  34. tview.Borders.TopRightFocus = conf.Borders.TopRightFocus
  35. tview.Borders.BottomLeftFocus = conf.Borders.BottomLeftFocus
  36. tview.Borders.BottomRightFocus = conf.Borders.BottomRightFocus
  37. tview.Styles.PrimitiveBackgroundColor = tcell.GetColor(conf.Theme.Background)
  38. tview.Styles.ContrastBackgroundColor = tcell.GetColor(conf.Theme.Background)
  39. tview.Styles.MoreContrastBackgroundColor = tcell.GetColor(conf.Theme.Background)
  40. tview.Styles.BorderColor = tcell.GetColor(conf.Theme.Border)
  41. tview.Styles.TitleColor = tcell.GetColor(conf.Theme.Title)
  42. tview.Styles.GraphicsColor = tcell.GetColor(conf.Theme.Graphics)
  43. tview.Styles.PrimaryTextColor = tcell.GetColor(conf.Theme.Text)
  44. tview.Styles.SecondaryTextColor = tcell.GetColor(conf.Theme.Text)
  45. tview.Styles.TertiaryTextColor = tcell.GetColor(conf.Theme.Text)
  46. tview.Styles.InverseTextColor = tcell.GetColor(conf.Theme.Text)
  47. tview.Styles.ContrastSecondaryTextColor = tcell.GetColor(conf.Theme.Text)
  48. app = tview.NewApplication()
  49. app.
  50. EnableMouse(conf.Mouse).
  51. SetInputCapture(onAppInputCapture)
  52. channelsTreeView = ui.NewChannelsTreeView()
  53. channelsTreeView.SetSelectedFunc(onChannelsTreeSelected)
  54. messagesTextView = ui.NewMessagesTextView()
  55. messagesTextView.
  56. SetChangedFunc(func() { app.Draw() }).
  57. SetInputCapture(onMessagesViewInputCapture)
  58. messageInputField = ui.NewMessageInputField()
  59. messageInputField.SetInputCapture(onMessageInputFieldInputCapture)
  60. rightFlex := tview.NewFlex().
  61. SetDirection(tview.FlexRow).
  62. AddItem(messagesTextView, 0, 1, false).
  63. AddItem(messageInputField, 3, 1, false)
  64. mainFlex = tview.NewFlex().
  65. AddItem(channelsTreeView, 0, 1, false).
  66. AddItem(rightFlex, 0, 4, false)
  67. token, err := keyring.Get(service, "token")
  68. if err != nil {
  69. token = conf.Token
  70. }
  71. if token != "" {
  72. app.
  73. SetRoot(mainFlex, true).
  74. SetFocus(channelsTreeView)
  75. session = newSession()
  76. session.Token = token
  77. session.Identify.Token = token
  78. if err := session.Open(); err != nil {
  79. panic(err)
  80. }
  81. } else {
  82. loginForm = ui.NewLoginForm(onLoginFormLoginButtonSelected, false)
  83. app.SetRoot(loginForm, true)
  84. }
  85. if err := app.Run(); err != nil {
  86. panic(err)
  87. }
  88. }
  89. func onLoginFormLoginButtonSelected() {
  90. email := loginForm.GetFormItem(0).(*tview.InputField).GetText()
  91. password := loginForm.GetFormItem(1).(*tview.InputField).GetText()
  92. if email == "" || password == "" {
  93. return
  94. }
  95. session = newSession()
  96. // Login using the email and password
  97. lr, err := login(email, password)
  98. if err != nil {
  99. panic(err)
  100. }
  101. if lr.Token != "" && !lr.MFA {
  102. app.
  103. SetRoot(mainFlex, true).
  104. SetFocus(channelsTreeView)
  105. session.Token = lr.Token
  106. session.Identify.Token = lr.Token
  107. if err = session.Open(); err != nil {
  108. panic(err)
  109. }
  110. go keyring.Set(service, "token", lr.Token)
  111. } else if lr.MFA {
  112. // The account has MFA enabled, reattempt login with code and ticket.
  113. loginForm = ui.NewLoginForm(func() {
  114. code := loginForm.GetFormItem(0).(*tview.InputField).GetText()
  115. if code == "" {
  116. return
  117. }
  118. lr, err = totp(code, lr.Ticket)
  119. if err != nil {
  120. panic(err)
  121. }
  122. app.
  123. SetRoot(mainFlex, true).
  124. SetFocus(channelsTreeView)
  125. session.Token = lr.Token
  126. session.Identify.Token = lr.Token
  127. if err = session.Open(); err != nil {
  128. panic(err)
  129. }
  130. go keyring.Set(service, "token", lr.Token)
  131. }, true)
  132. app.SetRoot(loginForm, true)
  133. }
  134. }