about summary refs log tree commit diff stats
path: root/widgets
diff options
context:
space:
mode:
authorRay Ganardi <ray@ganardi.xyz>2020-05-19 13:06:49 +0200
committerDrew DeVault <sir@cmpwn.com>2020-05-25 09:30:20 -0400
commita31d184ba53a9a61b8a0eed42cee52f9b1f2dc51 (patch)
tree36d261e41182a7d39c7ff1a93e95cb9d38acbcc7 /widgets
parent94e8d8f7bf5d4efb72dffb15e46a2a7d07bf4afb (diff)
downloadaerc-a31d184ba53a9a61b8a0eed42cee52f9b1f2dc51.tar.gz
aerc: Refactor getpasswd dialog
Previously there's a hack for showing and hiding the dialog.

Change it to use channels to emulate async/await
Diffstat (limited to 'widgets')
-rw-r--r--widgets/aerc.go83
-rw-r--r--widgets/pgpinfo.go13
2 files changed, 56 insertions, 40 deletions
diff --git a/widgets/aerc.go b/widgets/aerc.go
index eb037df..829873a 100644
--- a/widgets/aerc.go
+++ b/widgets/aerc.go
@@ -36,7 +36,7 @@ type Aerc struct {
 	tabs        *ui.Tabs
 	ui          *ui.UI
 	beep        func() error
-	getpasswd   *GetPasswd
+	dialog      ui.DrawableInteractive
 }
 
 type Choice struct {
@@ -170,8 +170,8 @@ func (aerc *Aerc) Focus(focus bool) {
 
 func (aerc *Aerc) Draw(ctx *ui.Context) {
 	aerc.grid.Draw(ctx)
-	if aerc.getpasswd != nil {
-		aerc.getpasswd.Draw(ctx.Subcontext(4, ctx.Height()/2-2,
+	if aerc.dialog != nil {
+		aerc.dialog.Draw(ctx.Subcontext(4, ctx.Height()/2-2,
 			ctx.Width()-8, 4))
 	}
 }
@@ -212,8 +212,8 @@ func (aerc *Aerc) simulate(strokes []config.KeyStroke) {
 }
 
 func (aerc *Aerc) Event(event tcell.Event) bool {
-	if aerc.getpasswd != nil {
-		return aerc.getpasswd.Event(event)
+	if aerc.dialog != nil {
+		return aerc.dialog.Event(event)
 	}
 
 	if aerc.focused != nil {
@@ -537,16 +537,42 @@ func (aerc *Aerc) CloseBackends() error {
 	return returnErr
 }
 
-func (aerc *Aerc) GetPassword(title string, prompt string, cb func(string, error)) {
-	aerc.getpasswd = NewGetPasswd(title, prompt, func(pw string, err error) {
-		aerc.getpasswd = nil
-		aerc.Invalidate()
-		cb(pw, err)
-	})
-	aerc.getpasswd.OnInvalidate(func(_ ui.Drawable) {
+func (aerc *Aerc) AddDialog(d ui.DrawableInteractive) {
+	aerc.dialog = d
+	aerc.dialog.OnInvalidate(func(_ ui.Drawable) {
 		aerc.Invalidate()
 	})
 	aerc.Invalidate()
+	return
+}
+
+func (aerc *Aerc) CloseDialog() {
+	aerc.dialog = nil
+	aerc.Invalidate()
+	return
+}
+
+
+func (aerc *Aerc) GetPassword(title string, prompt string) (chText chan string, chErr chan error) {
+	chText = make(chan string, 1)
+	chErr = make(chan error, 1)
+	getPasswd := NewGetPasswd(title, prompt, func(pw string, err error) {
+		defer func() {
+			close(chErr)
+			close(chText)
+			aerc.CloseDialog()
+		}()
+		if err != nil {
+			chErr <- err
+			return
+		}
+		chErr <- nil
+		chText <- pw
+		return
+	})
+	aerc.AddDialog(getPasswd)
+
+	return
 }
 
 func (aerc *Aerc) Initialize(ui *ui.UI) {
@@ -554,27 +580,24 @@ func (aerc *Aerc) Initialize(ui *ui.UI) {
 }
 
 func (aerc *Aerc) DecryptKeys(keys []openpgp.Key, symmetric bool) (b []byte, err error) {
-	// HACK HACK HACK
 	for _, key := range keys {
-		var ident *openpgp.Identity
-		for _, ident = range key.Entity.Identities {
-			break
-		}
-		aerc.GetPassword("Decrypt PGP private key",
+		ident := key.Entity.PrimaryIdentity()
+		chPass, chErr := aerc.GetPassword("Decrypt PGP private key",
 			fmt.Sprintf("Enter password for %s (%8X)\nPress <ESC> to cancel",
-				ident.Name, key.PublicKey.KeyId),
-			func(pass string, e error) {
-				if e != nil {
-					err = e
-					return
-				}
-				e = key.PrivateKey.Decrypt([]byte(pass))
-				if e != nil {
-					err = e
+				ident.Name, key.PublicKey.KeyId))
+
+		for {
+			select {
+			case err = <-chErr:
+				if err != nil {
+					return nil, err
 				}
-			})
-		for aerc.getpasswd != nil {
-			aerc.ui.Tick()
+				pass := <-chPass
+				err = key.PrivateKey.Decrypt([]byte(pass))
+				return nil, err
+			default:
+				aerc.ui.Tick()
+			}
 		}
 	}
 	return nil, err
diff --git a/widgets/pgpinfo.go b/widgets/pgpinfo.go
index dc03cf6..5da9141 100644
--- a/widgets/pgpinfo.go
+++ b/widgets/pgpinfo.go
@@ -41,11 +41,8 @@ func (p *PGPInfo) DrawSignature(ctx *ui.Context) {
 			p.details.SignatureError.Error())
 	} else {
 		entity := p.details.SignedBy.Entity
-		var ident *openpgp.Identity
-		// TODO: Pick identity more intelligently
-		for _, ident = range entity.Identities {
-			break
-		}
+		ident := entity.PrimaryIdentity()
+
 		x := ctx.Printf(0, 0, validStyle, "✓ Authentic ")
 		x += ctx.Printf(x, 0, tcell.StyleDefault,
 			"Signature from %s (%8X)",
@@ -56,11 +53,7 @@ func (p *PGPInfo) DrawSignature(ctx *ui.Context) {
 func (p *PGPInfo) DrawEncryption(ctx *ui.Context, y int) {
 	validStyle := tcell.StyleDefault.Foreground(tcell.ColorGreen).Bold(true)
 	entity := p.details.DecryptedWith.Entity
-	var ident *openpgp.Identity
-	// TODO: Pick identity more intelligently
-	for _, ident = range entity.Identities {
-		break
-	}
+	ident := entity.PrimaryIdentity()
 
 	x := ctx.Printf(0, y, validStyle, "✓ Encrypted ")
 	x += ctx.Printf(x, y, tcell.StyleDefault,