about summary refs log tree commit diff stats
path: root/commands
diff options
context:
space:
mode:
authorReto Brunner <reto@labrat.space>2021-01-24 18:00:23 +0100
committerReto Brunner <reto@labrat.space>2021-01-24 18:00:23 +0100
commit9385827cae7bab6534933718d21eeb489448c476 (patch)
tree142b539fd1ea31fbba7b0ba614f701070c98a8e9 /commands
parent3720c8623687d7a3fb978492ecd1ab2180823cf4 (diff)
downloadaerc-9385827cae7bab6534933718d21eeb489448c476.tar.gz
send: don't block the UI thread during the sending
Diffstat (limited to 'commands')
-rw-r--r--commands/compose/send.go69
1 files changed, 34 insertions, 35 deletions
diff --git a/commands/compose/send.go b/commands/compose/send.go
index 40d0ae3..2606d5f 100644
--- a/commands/compose/send.go
+++ b/commands/compose/send.go
@@ -13,7 +13,6 @@ import (
 	"github.com/emersion/go-sasl"
 	"github.com/emersion/go-smtp"
 	"github.com/google/shlex"
-	"github.com/miolini/datacounter"
 	"github.com/pkg/errors"
 
 	"git.sr.ht/~sircmpwn/aerc/lib"
@@ -91,47 +90,47 @@ func (Send) Execute(aerc *widgets.Aerc, args []string) error {
 		rcpts:    rcpts,
 	}
 
-	var sender io.WriteCloser
-	switch ctx.scheme {
-	case "smtp":
-		fallthrough
-	case "smtps":
-		sender, err = newSmtpSender(ctx)
-	case "":
-		sender, err = newSendmailSender(ctx)
-	default:
-		sender, err = nil, fmt.Errorf("unsupported scheme %v", ctx.scheme)
-	}
-	if err != nil {
-		return errors.Wrap(err, "send:")
-	}
-
-	// if we copy via the worker we need to know the count
-	counter := datacounter.NewWriterCounter(sender)
-	var writer io.Writer = counter
-	writer = counter
-
-	var copyBuf bytes.Buffer
-	if config.CopyTo != "" {
-		writer = io.MultiWriter(writer, &copyBuf)
-	}
-
+	// we don't want to block the UI thread while we are sending
+	// so we do everything in a goroutine and hide the composer from the user
 	aerc.RemoveTab(composer)
 	aerc.PushStatus("Sending...", 10*time.Second)
 
-	ch := make(chan error)
+	var copyBuf bytes.Buffer // for the Sent folder content if CopyTo is set
+
+	failCh := make(chan error)
+	//writer
 	go func() {
-		err := composer.WriteMessage(header, writer)
+		var sender io.WriteCloser
+		switch ctx.scheme {
+		case "smtp":
+			fallthrough
+		case "smtps":
+			sender, err = newSmtpSender(ctx)
+		case "":
+			sender, err = newSendmailSender(ctx)
+		default:
+			sender, err = nil, fmt.Errorf("unsupported scheme %v", ctx.scheme)
+		}
 		if err != nil {
-			ch <- err
+			failCh <- errors.Wrap(err, "send:")
+		}
+
+		var writer io.Writer = sender
+
+		if config.CopyTo != "" {
+			writer = io.MultiWriter(writer, &copyBuf)
+		}
+		err = composer.WriteMessage(header, writer)
+		if err != nil {
+			failCh <- err
 			return
 		}
-		ch <- sender.Close()
+		failCh <- sender.Close()
 	}()
 
-	// we don't want to block the UI thread while we are sending
+	//cleanup + copy to sent
 	go func() {
-		err = <-ch
+		err = <-failCh
 		if err != nil {
 			aerc.PushError(err.Error())
 			aerc.NewTab(composer, tabName)
@@ -139,9 +138,9 @@ func (Send) Execute(aerc *widgets.Aerc, args []string) error {
 		}
 		if config.CopyTo != "" {
 			aerc.PushStatus("Copying to "+config.CopyTo, 10*time.Second)
-			errCh := copyToSent(composer.Worker(), config.CopyTo,
-				int(counter.Count()), &copyBuf)
-			err = <-errCh
+			errch := copyToSent(composer.Worker(), config.CopyTo,
+				copyBuf.Len(), &copyBuf)
+			err = <-errch
 			if err != nil {
 				errmsg := fmt.Sprintf(
 					"message sent, but copying to %v failed: %v",