package login
import (
"context"
"log/slog"
"github.com/diamondburned/arikawa/v3/state"
"github.com/diamondburned/chatkit/kits/secret"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
"github.com/diamondburned/gotkit/gtkutil"
"github.com/diamondburned/gotkit/gtkutil/cssutil"
"github.com/pkg/errors"
"libdb.so/dissent/internal/gtkcord"
)
type LoginController interface {
Hook(*gtkcord.State)
Ready(*gtkcord.State)
PromptLogin()
}
type Page struct {
*gtk.Box
Header *gtk.HeaderBar
Login *Component
ctx context.Context
ctrl LoginController
}
var pageCSS = cssutil.Applier("login-page", ``)
func NewPage(ctx context.Context, ctrl LoginController) *Page {
p := Page{
ctx: ctx,
ctrl: ctrl,
}
p.Header = gtk.NewHeaderBar()
p.Header.AddCSSClass("login-page-header")
p.Header.SetShowTitleButtons(true)
p.Login = NewComponent(ctx, &p)
p.Login.SetVExpand(true)
p.Login.SetHExpand(true)
p.Box = gtk.NewBox(gtk.OrientationVertical, 0)
p.Box.Append(p.Header)
p.Box.Append(p.Login)
pageCSS(p)
return &p
}
func (p *Page) LoadKeyring() {
p.asyncLoadFromSecrets(secret.KeyringDriver(p.ctx))
}
func (p *Page) asyncLoadFromSecrets(driver secret.Driver) {
p.Login.Loading.Show()
p.Login.SetSensitive(false)
done := func() {
p.Login.Loading.Hide()
p.Login.SetSensitive(true)
}
gtkutil.Async(p.ctx, func() func() {
b, err := driver.Get("account")
if err != nil {
slog.Info(
"account not found in keyring",
"err", err)
return done
}
return func() {
done()
p.asyncUseToken(string(b))
}
})
}
func (p *Page) asyncUseToken(token string) {
state := gtkcord.Wrap(state.New(token))
p.ctrl.Hook(state)
gtkutil.Async(p.ctx, func() func() {
if err := state.Open(p.ctx); err != nil {
return func() {
p.ctrl.PromptLogin()
p.Login.ShowError(errors.Wrap(err, "cannot open session"))
}
}
return func() {
p.ctrl.Ready(state)
}
})
}