mirror of
https://git.sr.ht/~rjarry/aerc
synced 2025-02-22 23:23:57 +01:00

Split the compose commands into two categories: edit and review. Some commands can belong to both categories and be available whether the text editor or the review screen is visible. Update man page to reflect that. Remove duplicate (and misplaced) :save command from the COMPOSE section. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Bence Ferdinandy <bence@ferdinandy.com>
149 lines
3.1 KiB
Go
149 lines
3.1 KiB
Go
package compose
|
|
|
|
import (
|
|
"bytes"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"git.sr.ht/~rjarry/aerc/app"
|
|
"git.sr.ht/~rjarry/aerc/commands"
|
|
"git.sr.ht/~rjarry/aerc/lib/log"
|
|
"git.sr.ht/~rjarry/aerc/models"
|
|
"git.sr.ht/~rjarry/aerc/worker/types"
|
|
)
|
|
|
|
type Postpone struct {
|
|
Folder string `opt:"-t" complete:"CompleteFolder" desc:"Override the target folder."`
|
|
}
|
|
|
|
func init() {
|
|
commands.Register(Postpone{})
|
|
}
|
|
|
|
func (Postpone) Description() string {
|
|
return "Save the current state of the message to the postpone folder."
|
|
}
|
|
|
|
func (Postpone) Context() commands.CommandContext {
|
|
return commands.COMPOSE_REVIEW
|
|
}
|
|
|
|
func (Postpone) Aliases() []string {
|
|
return []string{"postpone"}
|
|
}
|
|
|
|
func (*Postpone) CompleteFolder(arg string) []string {
|
|
return commands.GetFolders(arg)
|
|
}
|
|
|
|
func (p Postpone) Execute(args []string) error {
|
|
acct := app.SelectedAccount()
|
|
if acct == nil {
|
|
return errors.New("No account selected")
|
|
}
|
|
store := acct.Store()
|
|
if store == nil {
|
|
return errors.New("No message store selected")
|
|
}
|
|
tab := app.SelectedTab()
|
|
if tab == nil {
|
|
return errors.New("No tab selected")
|
|
}
|
|
composer, _ := tab.Content.(*app.Composer)
|
|
config := composer.Config()
|
|
tabName := tab.Name
|
|
|
|
targetFolder := config.Postpone
|
|
if composer.RecalledFrom() != "" {
|
|
targetFolder = composer.RecalledFrom()
|
|
}
|
|
if p.Folder != "" {
|
|
targetFolder = p.Folder
|
|
}
|
|
if targetFolder == "" {
|
|
return errors.New("No Postpone location configured")
|
|
}
|
|
|
|
log.Tracef("Postponing mail")
|
|
|
|
header, err := composer.PrepareHeader()
|
|
if err != nil {
|
|
return errors.Wrap(err, "PrepareHeader")
|
|
}
|
|
header.SetContentType("text/plain", map[string]string{"charset": "UTF-8"})
|
|
header.Set("Content-Transfer-Encoding", "quoted-printable")
|
|
worker := composer.Worker()
|
|
dirs := acct.Directories().List()
|
|
alreadyCreated := false
|
|
for _, dir := range dirs {
|
|
if dir == targetFolder {
|
|
alreadyCreated = true
|
|
break
|
|
}
|
|
}
|
|
|
|
errChan := make(chan string)
|
|
|
|
// run this as a goroutine so we can make other progress. The message
|
|
// will be saved once the directory is created.
|
|
go func() {
|
|
defer log.PanicHandler()
|
|
|
|
errStr := <-errChan
|
|
if errStr != "" {
|
|
app.PushError(errStr)
|
|
return
|
|
}
|
|
|
|
handleErr := func(err error) {
|
|
app.PushError(err.Error())
|
|
log.Errorf("Postponing failed: %v", err)
|
|
app.NewTab(composer, tabName)
|
|
}
|
|
|
|
app.RemoveTab(composer, false)
|
|
buf := &bytes.Buffer{}
|
|
|
|
err = composer.WriteMessage(header, buf)
|
|
if err != nil {
|
|
handleErr(errors.Wrap(err, "WriteMessage"))
|
|
return
|
|
}
|
|
store.Append(
|
|
targetFolder,
|
|
models.SeenFlag|models.DraftFlag,
|
|
time.Now(),
|
|
buf,
|
|
buf.Len(),
|
|
func(msg types.WorkerMessage) {
|
|
switch msg := msg.(type) {
|
|
case *types.Done:
|
|
app.PushStatus("Message postponed.", 10*time.Second)
|
|
composer.SetPostponed()
|
|
composer.Close()
|
|
case *types.Error:
|
|
handleErr(msg.Error)
|
|
}
|
|
},
|
|
)
|
|
}()
|
|
|
|
if !alreadyCreated {
|
|
// to synchronise the creating of the directory
|
|
worker.PostAction(&types.CreateDirectory{
|
|
Directory: targetFolder,
|
|
}, func(msg types.WorkerMessage) {
|
|
switch msg := msg.(type) {
|
|
case *types.Done:
|
|
errChan <- ""
|
|
case *types.Error:
|
|
errChan <- msg.Error.Error()
|
|
}
|
|
})
|
|
} else {
|
|
errChan <- ""
|
|
}
|
|
|
|
return nil
|
|
}
|