discordo/internal/ui/login/model.go

104 lines
2.3 KiB
Go

package login
import (
"github.com/ayn2op/tview/tabs"
"github.com/ayn2op/discordo/internal/config"
"github.com/ayn2op/discordo/internal/ui"
"github.com/ayn2op/discordo/internal/ui/login/password"
"github.com/ayn2op/discordo/internal/ui/login/qr"
"github.com/ayn2op/discordo/internal/ui/login/token"
"github.com/ayn2op/tview"
)
// tab is a login method shown as a tab.
type tab int
const (
tabPassword tab = iota
tabQR
tabToken
tabCount
)
// Model shows the login methods as tabs inside a bordered box.
type Model struct {
cfg *config.Config
password password.Model
qr qr.Model
token token.Model
active tab
}
var _ tview.Model[Model] = Model{}
func NewModel(cfg *config.Config) Model {
return Model{cfg: cfg, qr: qr.NewModel()}
}
// Init initializes the active tab.
func (m Model) Init() tview.Cmd {
switch m.active {
case tabPassword:
return m.password.Init()
case tabQR:
return m.qr.Init()
case tabToken:
return m.token.Init()
}
return nil
}
// View shows the tabs in a box.
func (m Model) View() tview.Widget {
var content tview.Widget
switch m.active {
case tabPassword:
content = m.password.View()
case tabQR:
content = m.qr.View()
case tabToken:
content = m.token.View()
}
t := m.tabs().
Active(int(m.active)).
Content(content).
Keybind(tabAction).
OnSelect(func(i int) tview.Msg { return selectTabMsg(i) })
return ui.Box(t, &m.cfg.Theme, false)
}
// tabs returns the login methods as tabs set up by the tabs config.
func (m Model) tabs() tabs.Widget {
cfg := m.cfg.UI.Tabs
return tabs.New(m.password.Label(), m.qr.Label(), m.token.Label()).
Alignment(cfg.Alignment.Alignment).
Wrap(cfg.Wrap).
Separator(cfg.Separator).
Padding(cfg.Padding[0], cfg.Padding[1]).
Arrows(cfg.Arrows[0], cfg.Arrows[1]).
ClickableArrows(cfg.ClickableArrows)
}
func (m Model) Update(msg tview.Msg) (Model, tview.Cmd) {
var errCmd tview.Cmd
switch msg := msg.(type) {
case selectTabMsg:
m.active = tab(msg)
return m, m.Init()
case error:
// The active tab still gets the error, so the QR tab can close its connection.
errCmd = showErrorDialog(msg)
}
var cmd tview.Cmd
switch m.active {
case tabPassword:
m.password, cmd = m.password.Update(msg)
case tabQR:
m.qr, cmd = m.qr.Update(msg)
case tabToken:
m.token, cmd = m.token.Update(msg)
}
return m, tview.Batch(errCmd, cmd)
}