main.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package main
  2. import (
  3. "os"
  4. "github.com/ayntgl/discordo/config"
  5. "github.com/ayntgl/discordo/ui"
  6. "github.com/gdamore/tcell/v2"
  7. "github.com/rivo/tview"
  8. "github.com/urfave/cli/v2"
  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. func main() {
  16. t, _ := keyring.Get(name, "token")
  17. cliApp := &cli.App{
  18. Name: name,
  19. Usage: usage,
  20. EnableBashCompletion: true,
  21. Flags: []cli.Flag{
  22. &cli.StringFlag{
  23. Name: "token",
  24. Usage: "The client authentication token.",
  25. Value: t,
  26. DefaultText: "From keyring",
  27. Aliases: []string{"t"},
  28. },
  29. &cli.StringFlag{
  30. Name: "config",
  31. Usage: "The path of the configuration file.",
  32. Value: config.DefaultPath(),
  33. Aliases: []string{"c"},
  34. },
  35. },
  36. }
  37. cliApp.Action = func(ctx *cli.Context) error {
  38. c := config.New()
  39. c.Load(ctx.String("config"))
  40. token := ctx.String("token")
  41. app := ui.NewApp(token, c)
  42. if token != "" {
  43. err := app.Connect()
  44. if err != nil {
  45. panic(err)
  46. }
  47. app.DrawMainFlex()
  48. app.SetFocus(app.GuildsList)
  49. } else {
  50. loginForm := ui.NewLoginForm(false)
  51. loginForm.AddButton("Login", func() {
  52. email := loginForm.GetFormItem(0).(*tview.InputField).GetText()
  53. password := loginForm.GetFormItem(1).(*tview.InputField).GetText()
  54. if email == "" || password == "" {
  55. return
  56. }
  57. // Login using the email and password
  58. lr, err := app.Session.Login(email, password)
  59. if err != nil {
  60. panic(err)
  61. }
  62. if lr.Token != "" && !lr.Mfa {
  63. app.Session.Identify.Token = lr.Token
  64. err = app.Connect()
  65. if err != nil {
  66. panic(err)
  67. }
  68. app.DrawMainFlex()
  69. app.SetFocus(app.GuildsList)
  70. go keyring.Set(name, "token", lr.Token)
  71. } else {
  72. // The account has MFA enabled, reattempt login with MFA code and ticket.
  73. mfaLoginForm := ui.NewLoginForm(true)
  74. mfaLoginForm.AddButton("Login", func() {
  75. code := loginForm.GetFormItem(0).(*tview.InputField).GetText()
  76. if code == "" {
  77. return
  78. }
  79. lr, err = app.Session.Totp(code, lr.Ticket)
  80. if err != nil {
  81. panic(err)
  82. }
  83. app.Session.Identify.Token = lr.Token
  84. err = app.Connect()
  85. if err != nil {
  86. panic(err)
  87. }
  88. app.DrawMainFlex()
  89. app.SetFocus(app.GuildsList)
  90. go keyring.Set(name, "token", lr.Token)
  91. })
  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. panic(err)
  114. }
  115. return nil
  116. }
  117. err := cliApp.Run(os.Args)
  118. if err != nil {
  119. panic(err)
  120. }
  121. }