package ui import ( "gioui.org/layout" "gioui.org/widget" "gioui.org/widget/material" "git.wxccs.org/iceking2nd/winauth-go/internal/i18n" ) // passwordDialog asks the user for the password to decrypt an existing // config. The dialog is shown at startup when the config file is found // to be encrypted; on submit it calls onDone with the entered passphrase. // Cancel returns an empty passphrase and signals abort. type passwordDialog struct { prompt string // optional explanatory line above the field errorMsg string pwEd widget.Editor okBtn widget.Clickable cancelBtn widget.Clickable } func newPasswordDialog(prompt string) *passwordDialog { d := &passwordDialog{prompt: prompt} d.pwEd.SingleLine = true d.pwEd.Mask = '*' return d } // SetError lets the caller surface a "wrong password" message after a // failed Load attempt, so the same dialog can be reused for a retry loop. func (d *passwordDialog) SetError(msg string) { d.errorMsg = msg } // Layout takes onDone(password, ok). ok=true on submit; ok=false on cancel. // On ok the password slice is freshly allocated (the editor's underlying // buffer is not retained). func (d *passwordDialog) Layout( gtx layout.Context, th *material.Theme, onDone func(password []byte, ok bool), ) layout.Dimensions { if d.okBtn.Clicked(gtx) { pw := []byte(d.pwEd.Text()) onDone(pw, true) return layout.Dimensions{Size: gtx.Constraints.Max} } if d.cancelBtn.Clicked(gtx) { onDone(nil, false) return layout.Dimensions{Size: gtx.Constraints.Max} } body := func(gtx layout.Context) layout.Dimensions { children := []layout.FlexChild{} if d.prompt != "" { children = append(children, layout.Rigid(material.Body2(th, d.prompt).Layout), layout.Rigid(layout.Spacer{Height: 8}.Layout), ) } children = append(children, layout.Rigid(labeledEditor(th, i18n.T("label_password"), &d.pwEd, "")), layout.Rigid(errorLabel(th, d.errorMsg)), ) return layout.Flex{Axis: layout.Vertical}.Layout(gtx, children...) } return modalCard(gtx, th, i18n.T("dialog_password_title"), i18n.T("btn_ok"), i18n.T("btn_cancel"), &d.okBtn, &d.cancelBtn, body) }