aerc/commands/msg/read.go

147 lines
2.9 KiB
Go
Raw Normal View History

2019-06-09 18:55:34 +00:00
package msg
import (
"errors"
2019-12-22 11:05:28 +00:00
"sync"
2019-06-09 18:55:34 +00:00
"time"
"git.sr.ht/~sircmpwn/getopt"
2019-12-22 11:05:28 +00:00
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/models"
2019-06-09 18:55:34 +00:00
"git.sr.ht/~sircmpwn/aerc/widgets"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
type Read struct{}
2019-06-09 18:55:34 +00:00
func init() {
register(Read{})
}
func (Read) Aliases() []string {
return []string{"read", "unread"}
}
func (Read) Complete(aerc *widgets.Aerc, args []string) []string {
return nil
2019-06-09 18:55:34 +00:00
}
func (Read) Execute(aerc *widgets.Aerc, args []string) error {
opts, optind, err := getopt.Getopts(args, "t")
if err != nil {
return err
}
if optind != len(args) {
2019-07-23 18:46:32 +00:00
return errors.New("Usage: " + args[0] + " [-t]")
}
var toggle bool
for _, opt := range opts {
switch opt.Option {
case 't':
toggle = true
}
2019-06-09 18:55:34 +00:00
}
2019-12-22 11:05:28 +00:00
h := newHelper(aerc)
store, err := h.store()
if err != nil {
return err
}
2019-12-22 11:05:28 +00:00
if toggle {
2019-12-22 11:05:28 +00:00
// ignore commmand given, simply toggle all the read states
return submitToggle(aerc, store, h)
}
msgUids, err := h.markedOrSelectedUids()
2019-12-22 11:05:28 +00:00
if err != nil {
return err
}
switch args[0] {
case "read":
submitReadChange(aerc, store, msgUids, true)
case "unread":
submitReadChange(aerc, store, msgUids, false)
}
return nil
}
func splitMessages(msgs []*models.MessageInfo) (read []uint32, unread []uint32) {
for _, m := range msgs {
var seen bool
for _, flag := range m.Flags {
if flag == models.SeenFlag {
2019-12-22 11:05:28 +00:00
seen = true
break
}
}
2019-12-22 11:05:28 +00:00
if seen {
read = append(read, m.Uid)
} else {
unread = append(unread, m.Uid)
}
}
2019-12-22 11:05:28 +00:00
return read, unread
}
2019-06-09 18:55:34 +00:00
2019-12-22 11:05:28 +00:00
func submitReadChange(aerc *widgets.Aerc, store *lib.MessageStore,
uids []uint32, newState bool) {
store.Read(uids, newState, func(msg types.WorkerMessage) {
2019-06-09 18:55:34 +00:00
switch msg := msg.(type) {
case *types.Done:
2019-12-22 11:05:28 +00:00
aerc.PushStatus(msg_success, 10*time.Second)
2019-06-09 18:55:34 +00:00
case *types.Error:
2020-04-24 16:59:40 +00:00
aerc.PushError(" " + msg.Error.Error())
2019-06-09 18:55:34 +00:00
}
})
2019-12-22 11:05:28 +00:00
}
func submitReadChangeWg(aerc *widgets.Aerc, store *lib.MessageStore,
2020-05-06 22:36:52 +00:00
uids []uint32, newState bool, wg *sync.WaitGroup, success *bool) {
2019-12-22 11:05:28 +00:00
store.Read(uids, newState, func(msg types.WorkerMessage) {
wg.Add(1)
switch msg := msg.(type) {
case *types.Done:
wg.Done()
case *types.Error:
2020-04-24 16:59:40 +00:00
aerc.PushError(" " + msg.Error.Error())
2019-12-22 11:05:28 +00:00
*success = false
wg.Done()
}
})
}
func submitToggle(aerc *widgets.Aerc, store *lib.MessageStore, h *helper) error {
msgs, err := h.messages()
if err != nil {
return err
}
read, unread := splitMessages(msgs)
var wg sync.WaitGroup
success := true
if len(read) != 0 {
newState := false
2020-05-06 22:36:52 +00:00
submitReadChangeWg(aerc, store, read, newState, &wg, &success)
2019-12-22 11:05:28 +00:00
}
if len(unread) != 0 {
newState := true
2020-05-06 22:36:52 +00:00
submitReadChangeWg(aerc, store, unread, newState, &wg, &success)
2019-12-22 11:05:28 +00:00
}
// we need to do that in the background, else we block the main thread
go func() {
wg.Wait()
if success {
aerc.PushStatus(msg_success, 10*time.Second)
}
}()
2019-06-09 18:55:34 +00:00
return nil
2019-12-22 11:05:28 +00:00
2019-06-09 18:55:34 +00:00
}
2019-12-22 11:05:28 +00:00
const msg_success = "read state set successfully"