main.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package main
  2. import (
  3. "log"
  4. "github.com/alecthomas/kong"
  5. "github.com/ayntgl/discordo/config"
  6. "github.com/ayntgl/discordo/ui"
  7. "github.com/gdamore/tcell/v2"
  8. "github.com/rivo/tview"
  9. "github.com/zalando/go-keyring"
  10. )
  11. const (
  12. name = "discordo"
  13. usage = "A lightweight, secure, and feature-rich Discord terminal client"
  14. )
  15. var cli struct {
  16. Token string `help:"The authentication token."`
  17. Config string `help:"The path of the configuration file." type:"path"`
  18. }
  19. func main() {
  20. kong.Parse(&cli, kong.Name(name), kong.Description(usage), kong.UsageOnError())
  21. // If the authentication token is provided via a flag, store it in the default keyring.
  22. if cli.Token != "" {
  23. go keyring.Set(name, "token", cli.Token)
  24. }
  25. // Defaults
  26. if cli.Config == "" {
  27. cli.Config = config.DefaultPath()
  28. }
  29. if cli.Token == "" {
  30. cli.Token, _ = keyring.Get(name, "token")
  31. }
  32. c := config.New()
  33. err := c.Load(cli.Config)
  34. if err != nil {
  35. log.Fatal(err)
  36. }
  37. app := ui.NewApp(cli.Token, c)
  38. if cli.Token != "" {
  39. err := app.Connect()
  40. if err != nil {
  41. log.Fatal(err)
  42. }
  43. app.DrawMainFlex()
  44. app.SetRoot(app.MainFlex, true)
  45. app.SetFocus(app.GuildsTree)
  46. } else {
  47. loginForm := ui.NewLoginForm(false)
  48. loginForm.AddButton("Login", func() {
  49. email := loginForm.GetFormItem(0).(*tview.InputField).GetText()
  50. password := loginForm.GetFormItem(1).(*tview.InputField).GetText()
  51. if email == "" || password == "" {
  52. return
  53. }
  54. // Login using the email and password only
  55. lr, err := app.State.Login(email, password)
  56. if err != nil {
  57. log.Fatal(err)
  58. }
  59. if lr.Token != "" && !lr.MFA {
  60. app.State.Token = lr.Token
  61. err = app.Connect()
  62. if err != nil {
  63. log.Fatal(err)
  64. }
  65. app.DrawMainFlex()
  66. app.SetRoot(app.MainFlex, true)
  67. app.SetFocus(app.GuildsTree)
  68. go keyring.Set(name, "token", lr.Token)
  69. } else {
  70. // The account has MFA enabled, reattempt login with MFA code and ticket.
  71. mfaLoginForm := ui.NewLoginForm(true)
  72. mfaLoginForm.AddButton("Login", func() {
  73. code := mfaLoginForm.GetFormItem(0).(*tview.InputField).GetText()
  74. if code == "" {
  75. return
  76. }
  77. lr, err = app.State.TOTP(code, lr.Ticket)
  78. if err != nil {
  79. log.Fatal(err)
  80. }
  81. app.State.Token = lr.Token
  82. err = app.Connect()
  83. if err != nil {
  84. log.Fatal(err)
  85. }
  86. app.DrawMainFlex()
  87. app.SetRoot(app.MainFlex, true)
  88. app.SetFocus(app.GuildsTree)
  89. go keyring.Set(name, "token", lr.Token)
  90. })
  91. app.SetRoot(mfaLoginForm, true)
  92. }
  93. })
  94. app.SetRoot(loginForm, true)
  95. }
  96. tview.Borders.TopLeftFocus = tview.Borders.TopLeft
  97. tview.Borders.TopRightFocus = tview.Borders.TopRight
  98. tview.Borders.BottomLeftFocus = tview.Borders.BottomLeft
  99. tview.Borders.BottomRightFocus = tview.Borders.BottomRight
  100. tview.Borders.HorizontalFocus = tview.Borders.Horizontal
  101. tview.Borders.VerticalFocus = tview.Borders.Vertical
  102. tview.Borders.TopLeft = 0
  103. tview.Borders.TopRight = 0
  104. tview.Borders.BottomLeft = 0
  105. tview.Borders.BottomRight = 0
  106. tview.Borders.Horizontal = 0
  107. tview.Borders.Vertical = 0
  108. tview.Styles.PrimitiveBackgroundColor = tcell.GetColor(app.Config.Theme.Background)
  109. tview.Styles.BorderColor = tcell.GetColor(app.Config.Theme.Border)
  110. tview.Styles.TitleColor = tcell.GetColor(app.Config.Theme.Title)
  111. err = app.Run()
  112. if err != nil {
  113. log.Fatal(err)
  114. }
  115. }