package ui import ( "image" "image/color" "gioui.org/app" "gioui.org/layout" "gioui.org/op/clip" "gioui.org/op/paint" "gioui.org/unit" "gioui.org/widget/material" "git.wxccs.org/iceking2nd/winauth-go/internal/global" "git.wxccs.org/iceking2nd/winauth-go/internal/i18n" "git.wxccs.org/iceking2nd/winauth-go/internal/win32" ) // copyCodeToClipboard pushes the current OTP onto the system clipboard // and pops a brief toast confirming the action. Errors are surfaced via // the same toast so the user actually sees them. func (st *appState) copyCodeToClipboard(en *entry, w *app.Window) { const fn = "internal.ui.appState.copyCodeToClipboard" if en == nil || en.Code == "" { return } if err := win32.SetClipboardText(en.Code); err != nil { global.Log.WithField("func", fn).WithError(err).Warn("clipboard copy failed") st.toast.Show(i18n.T("msg_copy_failed"), w) w.Invalidate() return } st.toast.Show(i18n.T("msg_copied"), w) w.Invalidate() } // drawEmptyPlaceholder paints the centered "no entries yet" hint shown // when the entries list is empty. func drawEmptyPlaceholder(gtx layout.Context, th *material.Theme) layout.Dimensions { return layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions { lbl := material.Body1(th, i18n.T("msg_empty_list")) lbl.Color = color.NRGBA{R: 0x80, G: 0x80, B: 0x80, A: 0xff} return layout.UniformInset(unit.Dp(8)).Layout(gtx, lbl.Layout) }) } // drawDivider paints a 1px-tall light-gray line across the available // horizontal space. Used between entries in the list. func drawDivider(gtx layout.Context) layout.Dimensions { h := gtx.Dp(unit.Dp(1)) size := image.Pt(gtx.Constraints.Max.X, h) defer clip.Rect{Max: size}.Push(gtx.Ops).Pop() paint.ColorOp{Color: color.NRGBA{R: 0xe0, G: 0xe0, B: 0xe0, A: 0xff}}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops) return layout.Dimensions{Size: size} }