app.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package app
  2. import (
  3. "fmt"
  4. "log/slog"
  5. "github.com/ayn2op/discordo/internal/clipboard"
  6. "github.com/ayn2op/discordo/internal/config"
  7. "github.com/ayn2op/discordo/internal/consts"
  8. "github.com/ayn2op/discordo/internal/ui/chat"
  9. "github.com/ayn2op/discordo/internal/ui/login"
  10. "github.com/ayn2op/tview"
  11. "github.com/gdamore/tcell/v3"
  12. )
  13. type App struct {
  14. inner *tview.Application
  15. chatView *chat.ChatView
  16. cfg *config.Config
  17. }
  18. func New(cfg *config.Config) *App {
  19. tview.Styles = tview.Theme{}
  20. app := &App{
  21. inner: tview.NewApplication(),
  22. cfg: cfg,
  23. }
  24. if err := clipboard.Init(); err != nil {
  25. slog.Error("failed to init clipboard", "err", err)
  26. }
  27. app.inner.SetInputCapture(app.onInputCapture)
  28. return app
  29. }
  30. func (a *App) Run(token string) error {
  31. screen, err := tcell.NewScreen()
  32. if err != nil {
  33. return fmt.Errorf("failed to create screen: %w", err)
  34. }
  35. if err := screen.Init(); err != nil {
  36. return fmt.Errorf("failed to init screen: %w", err)
  37. }
  38. if a.cfg.Mouse {
  39. screen.EnableMouse()
  40. }
  41. screen.SetTitle(consts.Name)
  42. screen.EnablePaste()
  43. screen.EnableFocus()
  44. a.inner.SetScreen(screen)
  45. if token == "" {
  46. loginForm := login.NewForm(a.inner, a.cfg, func(token string) {
  47. if err := a.showChatView(token); err != nil {
  48. slog.Error("failed to show chat view", "err", err)
  49. }
  50. })
  51. a.inner.SetRoot(loginForm)
  52. } else {
  53. if err := a.showChatView(token); err != nil {
  54. return err
  55. }
  56. }
  57. return a.inner.Run()
  58. }
  59. func (a *App) showChatView(token string) error {
  60. a.chatView = chat.NewChatView(a.inner, a.cfg, a.quit)
  61. if err := a.chatView.OpenState(token); err != nil {
  62. return err
  63. }
  64. a.inner.SetRoot(a.chatView)
  65. return nil
  66. }
  67. func (a *App) quit() {
  68. if a.chatView != nil {
  69. if err := a.chatView.CloseState(); err != nil {
  70. slog.Error("failed to close the session", "err", err)
  71. }
  72. }
  73. a.inner.Stop()
  74. }
  75. func (a *App) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
  76. switch event.Name() {
  77. case a.cfg.Keys.Quit:
  78. a.quit()
  79. return nil
  80. case "Ctrl+C":
  81. // https://github.com/ayn2op/tview/blob/a64fc48d7654432f71922c8b908280cdb525805c/application.go#L153
  82. return tcell.NewEventKey(tcell.KeyCtrlC, "", tcell.ModNone)
  83. }
  84. return event
  85. }