From cf7dce2132bbc58f2a1df9a3f803dbfdad0e8cd4 Mon Sep 17 00:00:00 2001 From: "Sean E. Russell" Date: Sat, 12 Nov 2022 16:46:37 -0600 Subject: [PATCH] Adds QR code generation for sends --- go.mod | 1 + go.sum | 1 + ui/ui.go | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/go.mod b/go.mod index 8ad7f4d..19729f4 100644 --- a/go.mod +++ b/go.mod @@ -15,5 +15,6 @@ require ( golang.org/x/exp/shiny v0.0.0-20220827204233-334a2380cb91 google.golang.org/protobuf v1.27.1 // indirect nhooyr.io/websocket v1.8.7 // indirect + rsc.io/qr v0.2.0 salsa.debian.org/vasudev/gospake2 v0.0.0-20210510093858-d91629950ad1 // indirect ) diff --git a/go.sum b/go.sum index 60dd3bf..26ad409 100644 --- a/go.sum +++ b/go.sum @@ -676,6 +676,7 @@ nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0 nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= salsa.debian.org/vasudev/gospake2 v0.0.0-20180813171123-adcc69dd31d5/go.mod h1:soKzqXBAtqHTODjyA0VzH2iERtpzN1w65eZUfetn2cQ= salsa.debian.org/vasudev/gospake2 v0.0.0-20210510093858-d91629950ad1 h1:m65DhEZR/5zbgOGW4sQGDZmIwro+xBGIBQGWm43SlxM= diff --git a/ui/ui.go b/ui/ui.go index ad9cf7e..371658a 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -33,6 +33,7 @@ import ( "github.com/psanford/wormhole-william-mobile/internal/picker" "github.com/psanford/wormhole-william-mobile/ui/plog" "github.com/psanford/wormhole-william/wormhole" + "rsc.io/qr" ) type UI struct { @@ -225,6 +226,7 @@ func (ui *UI) loop(w *app.Window) error { case <-cancelChan: cancel() statusMsg = "Transfer mid-stream aborted" + qrSendTxtImg.Src = paint.NewImageOp(image.NewGray(image.Rect(0, 0, 0, 0))) textCodeTxt.SetText("") transferInProgress = false w.Invalidate() @@ -239,6 +241,17 @@ func (ui *UI) loop(w *app.Window) error { return } + qrText := fmt.Sprintf("wormhole:%s?code=%s", conf.RendezvousURL, code) + qrCode, err := qr.Encode(qrText, qr.M) + if err != nil { + statusMsg = fmt.Sprintf("Send err: %s", err) + plog.Printf("Send err: %s", err) + return + } + qrCode.Scale = 1 + qrSendTxtImg.Src = paint.NewImageOp(qrCode.Image()) + w.Invalidate() + statusMsg = "Waiting for receiver..." textCodeTxt.SetText(code) @@ -256,6 +269,7 @@ func (ui *UI) loop(w *app.Window) error { } else if s.OK { statusMsg = "OK!" } + qrSendTxtImg.Src = paint.NewImageOp(image.NewGray(image.Rect(0, 0, 0, 0))) textCodeTxt.SetText("") w.Invalidate() }() @@ -499,6 +513,17 @@ func (ui *UI) sendFile(ctx context.Context, w *app.Window, path, filename string return } + qrText := fmt.Sprintf("wormhole:%s?code=%s", ui.wormholeClient.RendezvousURL, code) + qrCode, err := qr.Encode(qrText, qr.M) + if err != nil { + statusMsg = fmt.Sprintf("Send err: %s", err) + plog.Printf("Send err: %s", err) + return + } + qrCode.Scale = 1 + qrSendFileImg.Src = paint.NewImageOp(qrCode.Image()) + w.Invalidate() + sendFileCodeTxt.SetText(code) statusMsg = "Waiting for receiver..." @@ -549,6 +574,9 @@ var ( recvCodeEditor = new(RichEditor) recvMsgBtn = new(widget.Clickable) + qrImage = new(widget.Image) + qrSendTxtImg = new(widget.Image) + qrSendFileImg = new(widget.Image) scanQRBtn = new(widget.Clickable) recvTxtMsg = new(Copyable) itemList = &layout.List{ @@ -686,6 +714,12 @@ var sendTextTab = Tab{ } return D{} }, + func(gtx C) D { + if transferInProgress || recvCodeEditor.Text() == "" { + gtx = gtx.Disabled() + } + return qrSendTxtImg.Layout(gtx) + }, func(gtx C) D { if transferInProgress || confirmInProgress { return material.Button(th, cancelBtn, "Cancel").Layout(gtx) @@ -796,6 +830,12 @@ var sendFileTab = Tab{ gtx.Constraints.Max.Y = gtx.Dp(400) return CopyField(th, sendFileCodeTxt).Layout(gtx) }, + func(gtx C) D { + if transferInProgress || recvCodeEditor.Text() == "" { + gtx = gtx.Disabled() + } + return qrSendFileImg.Layout(gtx) + }, func(gtx C) D { if transferInProgress || confirmInProgress { return material.Button(th, cancelBtn, "Cancel").Layout(gtx)