package ui import ( "gioui.org/layout" "gioui.org/unit" "gioui.org/widget" "gioui.org/widget/material" "git.wxccs.org/iceking2nd/winauth-go/internal/i18n" ) // vendor identifies which Add dialog should be opened next. type vendor int const ( vendorNone vendor = iota vendorGoogle vendorMicrosoft vendorOkta vendorHOTP vendorBattleNet vendorBattleNetRestore vendorSteam vendorScanQR ) // vendorMenu is the little popup shown after clicking the Add button. // It lets the user pick which kind of authenticator to enroll. Selecting // any entry returns that vendor via Pick(); Cancel returns vendorNone and // signals the menu should close. type vendorMenu struct { googleBtn widget.Clickable microsoftBtn widget.Clickable oktaBtn widget.Clickable hotpBtn widget.Clickable bnetBtn widget.Clickable bnetRestoreBtn widget.Clickable steamBtn widget.Clickable scanQRBtn widget.Clickable cancelBtn widget.Clickable } func newVendorMenu() *vendorMenu { return &vendorMenu{} } // Pick returns the vendor selected this frame (vendorNone if no click) and // whether the menu should close (true on any click, including Cancel). func (m *vendorMenu) Pick(gtx layout.Context) (vendor, bool) { switch { case m.googleBtn.Clicked(gtx): return vendorGoogle, true case m.microsoftBtn.Clicked(gtx): return vendorMicrosoft, true case m.oktaBtn.Clicked(gtx): return vendorOkta, true case m.hotpBtn.Clicked(gtx): return vendorHOTP, true case m.bnetBtn.Clicked(gtx): return vendorBattleNet, true case m.bnetRestoreBtn.Clicked(gtx): return vendorBattleNetRestore, true case m.steamBtn.Clicked(gtx): return vendorSteam, true case m.scanQRBtn.Clicked(gtx): return vendorScanQR, true case m.cancelBtn.Clicked(gtx): return vendorNone, true } return vendorNone, false } func (m *vendorMenu) Layout(gtx layout.Context, th *material.Theme) layout.Dimensions { fillBackground(gtx, activePalette.ScrimBg) row := func(btn *widget.Clickable, label string) layout.FlexChild { return layout.Rigid(func(gtx layout.Context) layout.Dimensions { return layout.Inset{Top: unit.Dp(4), Bottom: unit.Dp(4)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions { gtx.Constraints.Min.X = gtx.Constraints.Max.X return material.Button(th, btn, label).Layout(gtx) }) }) } return layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions { gtx.Constraints.Max.X = gtx.Dp(320) return widget.Border{ Color: activePalette.DialogBorder, CornerRadius: unit.Dp(4), Width: unit.Dp(1), }.Layout(gtx, func(gtx layout.Context) layout.Dimensions { fillBackground(gtx, activePalette.DialogBg) return layout.UniformInset(unit.Dp(16)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(material.H6(th, i18n.T("menu_choose_vendor")).Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(12)}.Layout), row(&m.googleBtn, i18n.T("vendor_google")), row(&m.microsoftBtn, i18n.T("vendor_microsoft")), row(&m.oktaBtn, i18n.T("vendor_okta")), row(&m.hotpBtn, i18n.T("vendor_hotp")), row(&m.bnetBtn, i18n.T("vendor_battlenet")), row(&m.bnetRestoreBtn, i18n.T("vendor_battlenet_restore")), row(&m.steamBtn, i18n.T("vendor_steam")), row(&m.scanQRBtn, i18n.T("vendor_scan_qr")), layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return layout.Flex{Axis: layout.Horizontal, Spacing: layout.SpaceStart}.Layout(gtx, layout.Rigid(material.Button(th, &m.cancelBtn, i18n.T("btn_cancel")).Layout), ) }), ) }) }) }) }