| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package login
- import (
- "errors"
- "log/slog"
- "github.com/ayn2op/tview/layers"
- "github.com/gdamore/tcell/v3"
- "github.com/ayn2op/discordo/internal/clipboard"
- "github.com/ayn2op/discordo/internal/config"
- "github.com/ayn2op/discordo/internal/keyring"
- "github.com/ayn2op/discordo/internal/ui"
- "github.com/ayn2op/tview"
- )
- const (
- formLayerName = "form"
- errorLayerName = "error"
- qrLayerName = "qr"
- )
- type Form struct {
- *layers.Layers
- app *tview.Application
- cfg *config.Config
- form *tview.Form
- }
- func NewForm(app *tview.Application, cfg *config.Config) *Form {
- f := &Form{
- Layers: layers.New(),
- app: app,
- cfg: cfg,
- form: tview.NewForm(),
- }
- f.form.
- AddPasswordField("Token", "", 0, 0, nil).
- AddButton("Login", f.login).
- AddButton("Login with QR", f.loginWithQR)
- f.SetBackgroundLayerStyle(f.cfg.Theme.Dialog.BackgroundStyle.Style)
- f.AddLayer(f.form, layers.WithName(formLayerName), layers.WithResize(true), layers.WithVisible(true))
- return f
- }
- func (f *Form) login() {
- token := f.form.GetFormItem(0).(*tview.InputField).GetText()
- if token == "" {
- f.onError(errors.New("token required"))
- return
- }
- go keyring.SetToken(token)
- f.app.QueueEvent(NewTokenEvent(token))
- }
- func (f *Form) onError(err error) {
- slog.Error("failed to login", "err", err)
- message := err.Error()
- modal := tview.NewModal().
- SetText(message).
- AddButtons([]string{"Copy", "Close"}).
- SetDoneFunc(func(buttonIndex int, _ string) {
- if buttonIndex == 0 {
- go func() {
- if err := clipboard.Write(clipboard.FmtText, []byte(message)); err != nil {
- slog.Error("failed to copy error message", "err", err)
- }
- }()
- } else {
- f.RemoveLayer(errorLayerName)
- }
- })
- {
- bg := f.cfg.Theme.Dialog.Style.GetBackground()
- buttonStyle := f.cfg.Theme.Dialog.Style.Style
- if bg != tcell.ColorDefault {
- modal.SetBackgroundColor(bg)
- buttonStyle = buttonStyle.Background(bg)
- }
- fg := f.cfg.Theme.Dialog.Style.GetForeground()
- if fg != tcell.ColorDefault {
- modal.SetTextColor(fg)
- buttonStyle = buttonStyle.Foreground(fg)
- }
- // Keep button styles aligned with dialog content without hiding text.
- modal.SetButtonStyle(buttonStyle)
- modal.SetButtonActivatedStyle(buttonStyle)
- }
- f.
- AddLayer(
- ui.Centered(modal, 0, 0),
- layers.WithName(errorLayerName),
- layers.WithResize(true),
- layers.WithVisible(true),
- layers.WithOverlay(),
- ).
- SendToFront(errorLayerName)
- }
- func (f *Form) loginWithQR() {
- qr := newQRLogin(f.app, f.cfg, func(token string, err error) {
- if err != nil {
- f.onError(err)
- return
- }
- if token == "" {
- f.RemoveLayer(qrLayerName)
- return
- }
- go keyring.SetToken(token)
- f.RemoveLayer(qrLayerName)
- f.app.QueueEvent(NewTokenEvent(token))
- })
- f.AddLayer(qr, layers.WithName(qrLayerName), layers.WithResize(true), layers.WithVisible(true))
- qr.start()
- }
|