aboutsummaryrefslogtreecommitdiffstats
path: root/commands/account/sort.go
blob: b41d49208be6bf3cd0768daec1b9805b7a423f87 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package account

import (
	"errors"

	"git.sr.ht/~rjarry/aerc/app"
	"git.sr.ht/~rjarry/aerc/commands"
	"git.sr.ht/~rjarry/aerc/lib/sort"
	"git.sr.ht/~rjarry/aerc/lib/state"
	"git.sr.ht/~rjarry/aerc/worker/types"
)

type Sort struct {
	Unused struct{} `opt:"-"`
	// these fields are only used for completion
	Reverse  bool     `opt:"-r"`
	Criteria []string `opt:"criteria" complete:"CompleteCriteria"`
}

func init() {
	commands.Register(Sort{})
}

func (Sort) Context() commands.CommandContext {
	return commands.MESSAGE_LIST
}

func (Sort) Aliases() []string {
	return []string{"sort"}
}

var supportedCriteria = []string{
	"arrival",
	"cc",
	"date",
	"from",
	"read",
	"size",
	"subject",
	"to",
	"flagged",
}

func (*Sort) CompleteCriteria(arg string) []string {
	return commands.FilterList(supportedCriteria, arg, commands.QuoteSpace)
}

func (Sort) 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("Messages still loading.")
	}

	if c := store.Capabilities(); c != nil {
		if !c.Sort {
			return errors.New("Sorting is not available for this backend.")
		}
	}

	var err error
	var sortCriteria []*types.SortCriterion
	if len(args[1:]) == 0 {
		sortCriteria = acct.GetSortCriteria()
	} else {
		sortCriteria, err = sort.GetSortCriteria(args[1:])
		if err != nil {
			return err
		}
	}

	acct.SetStatus(state.Sorting(true))
	store.Sort(sortCriteria, func(msg types.WorkerMessage) {
		if _, ok := msg.(*types.Done); ok {
			acct.SetStatus(state.Sorting(false))
		}
	})
	return nil
}