aboutsummaryrefslogtreecommitdiff
path: root/commands
diff options
context:
space:
mode:
Diffstat (limited to 'commands')
-rw-r--r--commands/msg/read.go103
1 files changed, 86 insertions, 17 deletions
diff --git a/commands/msg/read.go b/commands/msg/read.go
index 0da664b..ef07523 100644
--- a/commands/msg/read.go
+++ b/commands/msg/read.go
@@ -2,12 +2,14 @@ package msg
import (
"errors"
+ "sync"
"time"
"git.sr.ht/~sircmpwn/getopt"
"github.com/gdamore/tcell"
+ "git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/widgets"
"git.sr.ht/~sircmpwn/aerc/worker/types"
@@ -44,38 +46,105 @@ func (Read) Execute(aerc *widgets.Aerc, args []string) error {
}
}
- widget := aerc.SelectedTab().(widgets.ProvidesMessage)
- store := widget.Store()
- if store == nil {
- return errors.New("Cannot perform action. Messages still loading")
- }
- msg, err := widget.SelectedMessage()
+ h := newHelper(aerc)
+ store, err := h.store()
if err != nil {
return err
}
- newReadState := true
+
if toggle {
- newReadState = true
- for _, flag := range msg.Flags {
+ // ignore commmand given, simply toggle all the read states
+ return submitToggle(aerc, store, h)
+ }
+ msgUids, err := h.messageUids()
+ 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 {
- newReadState = false
+ seen = true
+ break
}
}
- } else if args[0] == "read" {
- newReadState = true
- } else if args[0] == "unread" {
- newReadState = false
+ if seen {
+ read = append(read, m.Uid)
+ } else {
+ unread = append(unread, m.Uid)
+ }
}
- store.Read([]uint32{msg.Uid}, newReadState, func(
- msg types.WorkerMessage) {
+ return read, unread
+}
+func submitReadChange(aerc *widgets.Aerc, store *lib.MessageStore,
+ uids []uint32, newState bool) {
+ store.Read(uids, newState, func(msg types.WorkerMessage) {
switch msg := msg.(type) {
case *types.Done:
- aerc.PushStatus("Messages updated.", 10*time.Second)
+ aerc.PushStatus(msg_success, 10*time.Second)
case *types.Error:
aerc.PushStatus(" "+msg.Error.Error(), 10*time.Second).
Color(tcell.ColorDefault, tcell.ColorRed)
}
})
+}
+
+func submitReadChangeWg(aerc *widgets.Aerc, store *lib.MessageStore,
+ uids []uint32, newState bool, wg sync.WaitGroup, success *bool) {
+ store.Read(uids, newState, func(msg types.WorkerMessage) {
+ wg.Add(1)
+ switch msg := msg.(type) {
+ case *types.Done:
+ wg.Done()
+ case *types.Error:
+ aerc.PushStatus(" "+msg.Error.Error(), 10*time.Second).
+ Color(tcell.ColorDefault, tcell.ColorRed)
+ *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
+ submitReadChangeWg(aerc, store, read, newState, wg, &success)
+ }
+
+ if len(unread) != 0 {
+ newState := true
+ submitReadChangeWg(aerc, store, unread, newState, wg, &success)
+ }
+ // 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)
+ }
+ }()
return nil
+
}
+
+const msg_success = "read state set successfully"