cchat-gtk/internal/ui/service/auth/auth.go

164 lines
3.8 KiB
Go
Raw Normal View History

2020-05-26 06:51:06 +00:00
package auth
import (
"github.com/diamondburned/cchat"
"github.com/diamondburned/cchat-gtk/internal/gts"
"github.com/diamondburned/cchat-gtk/internal/ui/dialog"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/spinner"
"github.com/diamondburned/cchat/text"
"github.com/diamondburned/handy"
2020-05-26 06:51:06 +00:00
"github.com/gotk3/gotk3/gtk"
)
type Dialog struct {
*dialog.Dialog
header *gtk.HeaderBar
backRev *gtk.Revealer
back *gtk.Button // might be hidden
stack *gtk.Stack
2020-05-26 06:51:06 +00:00
spinner *spinner.Boxed
leaflet *handy.Leaflet
2020-05-26 06:51:06 +00:00
stageList *StageList
request *RequestStack // might be nil
Auther cchat.Authenticator
onAuth func(cchat.Session)
2020-05-26 06:51:06 +00:00
}
// NewDialog makes a new authentication dialog. Auth() is called when the user
// is authenticated successfully inside the Gtk main thread.
func NewDialog(name text.Rich, authers []cchat.Authenticator, auth func(cchat.Session)) *Dialog {
2020-05-26 06:51:06 +00:00
d := &Dialog{
Auther: nil,
2020-05-26 06:51:06 +00:00
onAuth: auth,
}
d.spinner = spinner.NewVisible()
d.spinner.SetSizeRequest(50, 50)
d.spinner.Stop()
d.spinner.Show()
d.request = NewRequestStack()
d.request.SetHExpand(true)
d.request.SetName("request")
d.request.Show()
d.leaflet = handy.LeafletNew()
d.leaflet.SetCanSwipeBack(true)
d.leaflet.SetCanSwipeForward(false)
d.leaflet.SetVExpand(true)
d.leaflet.SetTransitionType(handy.LeafletTransitionTypeSlide)
d.leaflet.Show()
d.stack, _ = gtk.StackNew()
d.stack.SetVExpand(true)
d.stack.SetHExpand(true)
d.stack.AddNamed(d.leaflet, "leaflet")
d.stack.AddNamed(d.spinner, "spinner")
d.stack.SetVisibleChildName("leaflet")
d.stack.Show()
d.back, _ = gtk.ButtonNewFromIconName("go-previous-symbolic", gtk.ICON_SIZE_BUTTON)
d.back.Show()
d.back.Connect("clicked", func(back *gtk.Button) {
// If check just in case.
if d.stageList != nil {
d.leaflet.SetVisibleChild(d.stageList)
d.backRev.SetRevealChild(false)
2020-05-26 06:51:06 +00:00
}
})
d.backRev, _ = gtk.RevealerNew()
d.backRev.SetTransitionDuration(50)
d.backRev.SetTransitionType(gtk.REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
d.backRev.Add(d.back)
d.backRev.Show()
2020-05-26 06:51:06 +00:00
d.header, _ = gtk.HeaderBarNew()
d.header.SetShowCloseButton(true)
d.header.SetTitle("Log in to " + name.Content)
d.header.PackStart(d.backRev)
d.header.Show()
2020-05-26 06:51:06 +00:00
d.setAuthers(authers)
2020-05-26 06:51:06 +00:00
primitives.LeafletOnFold(d.leaflet, func(folded bool) {
visibleChildName := primitives.GetName(d.leaflet.GetVisibleChild().ToWidget())
2020-05-26 06:51:06 +00:00
if folded && visibleChildName == "request" {
d.backRev.SetRevealChild(true)
2020-06-04 23:00:41 +00:00
} else {
d.backRev.SetRevealChild(false)
2020-06-04 23:00:41 +00:00
}
})
2020-06-04 23:00:41 +00:00
d.Dialog = dialog.NewCSD(d.stack, d.header)
d.Dialog.SetDefaultSize(500, 350)
d.Dialog.Show()
2020-06-04 23:00:41 +00:00
return d
2020-06-04 23:00:41 +00:00
}
func (d *Dialog) setAuthers(authers []cchat.Authenticator) {
primitives.RemoveChildren(d.leaflet)
2020-06-04 23:00:41 +00:00
d.request.SetRequest(nil, nil)
2020-06-04 23:00:41 +00:00
d.stageList = NewStageList(authers, d.setAuther)
d.stageList.SetName("stagelist")
d.stageList.Show()
2020-05-26 06:51:06 +00:00
d.leaflet.Add(d.stageList)
d.leaflet.Add(d.request)
2020-06-04 23:00:41 +00:00
d.stageList.SelectFirst()
d.leaflet.SetVisibleChild(d.stageList)
d.backRev.SetRevealChild(false)
2020-06-04 23:00:41 +00:00
}
func (d *Dialog) setAuther(auther cchat.Authenticator) {
d.Auther = auther
d.request.SetRequest(auther, d.onContinue)
d.backRev.SetRevealChild(d.leaflet.GetFolded())
d.leaflet.SetVisibleChild(d.request)
2020-06-04 23:00:41 +00:00
}
func (d *Dialog) onContinue() {
request := d.request.Request()
values := request.values()
auther := d.Auther
2020-06-04 23:00:41 +00:00
d.Dialog.SetSensitive(false)
d.back.Hide()
d.stack.SetVisibleChildName("spinner")
d.spinner.Start()
2020-05-26 06:51:06 +00:00
gts.Async(func() (func(), error) {
s, err := auther.Authenticate(values)
return func() {
if err == nil {
d.Destroy()
d.onAuth(s)
return
}
d.spinner.Stop()
d.stack.SetVisibleChildName("leaflet")
d.back.Show()
d.Dialog.SetSensitive(true)
if nextStage := err.NextStage(); nextStage != nil {
d.setAuthers(nextStage)
} else {
request.SetError(err)
}
}, err
})
2020-05-26 06:51:06 +00:00
}