From a953e4dbe914def4275a6ddfc16e3046804fe03e Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Tue, 5 Jul 2022 14:48:41 -0500 Subject: [PATCH] threading: refactor reselect logic This patch refactors reselection of a message during certain operations (searching, filtering, clearing, deleting, moving, new message arrival). The addition of server-side filtering for threaded views broke the existing reselection logic. Signed-off-by: Tim Culverhouse Acked-by: Robin Jarry --- commands/account/clear.go | 3 +-- commands/msg/toggle-threads.go | 2 +- lib/msgstore.go | 28 ++++++++++++++++++++++++---- widgets/msglist.go | 22 +--------------------- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/commands/account/clear.go b/commands/account/clear.go index 69fac2d..5bab710 100644 --- a/commands/account/clear.go +++ b/commands/account/clear.go @@ -52,9 +52,8 @@ func (Clear) Execute(aerc *widgets.Aerc, args []string) error { if clearSelected { defer store.Select(0) } else { - defer store.Reselect(store.Selected()) + store.SetReselect(store.Selected()) } - store.ApplyClear() acct.SetStatus(statusline.SearchFilterClear()) diff --git a/commands/msg/toggle-threads.go b/commands/msg/toggle-threads.go index aa0e655..05c2c5e 100644 --- a/commands/msg/toggle-threads.go +++ b/commands/msg/toggle-threads.go @@ -34,7 +34,7 @@ func (ToggleThreads) Execute(aerc *widgets.Aerc, args []string) error { if err != nil { return err } - defer store.Reselect(store.Selected()) + store.SetReselect(store.Selected()) store.SetThreadedView(!store.ThreadedView()) acct.SetStatus(statusline.Threading(store.ThreadedView())) acct.Messages().Invalidate() diff --git a/lib/msgstore.go b/lib/msgstore.go index 2e77369..a54b20b 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -21,6 +21,7 @@ type MessageStore struct { Threads []*types.Thread selected int + reselect *models.MessageInfo bodyCallbacks map[uint32][]func(*types.FullMessage) headerCallbacks map[uint32][]func(*types.MessageInfo) @@ -196,6 +197,9 @@ func merge(to *models.MessageInfo, from *models.MessageInfo) { func (store *MessageStore) Update(msg types.WorkerMessage) { update := false directoryChange := false + if store.reselect == nil { + store.SetReselect(store.Selected()) + } switch msg := msg.(type) { case *types.DirectoryInfo: store.DirInfo = *msg.Info @@ -363,6 +367,7 @@ func (store *MessageStore) SetThreadedView(thread bool) { if store.threadedView { store.runThreadBuilder() } + store.Reselect() return } store.Sort(store.sortCriteria, nil) @@ -508,11 +513,11 @@ func (store *MessageStore) Select(index int) { store.updateVisual() } -func (store *MessageStore) Reselect(info *models.MessageInfo) { - if info == nil { +func (store *MessageStore) Reselect() { + if store.reselect == nil { return } - uid := info.Uid + uid := store.reselect.Uid newIdx := 0 for idx, uidStore := range store.Uids() { if uidStore == uid { @@ -520,9 +525,14 @@ func (store *MessageStore) Reselect(info *models.MessageInfo) { break } } + store.reselect = nil store.Select(newIdx) } +func (store *MessageStore) SetReselect(info *models.MessageInfo) { + store.reselect = info +} + // Mark sets the marked state on a MessageInfo func (store *MessageStore) Mark(uid uint32) { if store.visualMarkMode { @@ -718,11 +728,21 @@ func (store *MessageStore) SetFilter(args []string) { } func (store *MessageStore) ApplyClear() { + if store.reselect == nil { + store.SetReselect(store.Selected()) + } store.filter = []string{"filter"} + store.results = nil if store.onFilterChange != nil { store.onFilterChange(store) } - store.Sort(nil, nil) + cb := func(msg types.WorkerMessage) { + switch msg.(type) { + case *types.Done: + store.Reselect() + } + } + store.Sort(nil, cb) } func (store *MessageStore) nextPrevResult(delta int) { diff --git a/widgets/msglist.go b/widgets/msglist.go index 9e68f21..e9603ca 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -345,27 +345,7 @@ func (ml *MessageList) storeUpdate(store *lib.MessageStore) { if ml.Store() != store { return } - uids := store.Uids() - - if len(uids) > 0 { - // When new messages come in, advance the cursor accordingly - // Note that this assumes new messages are appended to the top, which - // isn't necessarily true once we implement SORT... ideally we'd look - // for the previously selected UID. - if len(uids) > ml.nmsgs && ml.nmsgs != 0 { - for i := 0; i < len(uids)-ml.nmsgs; i++ { - ml.Store().Next() - } - } - if len(uids) < ml.nmsgs && ml.nmsgs != 0 { - for i := 0; i < ml.nmsgs-len(uids); i++ { - ml.Store().Prev() - } - } - ml.nmsgs = len(uids) - } - - ml.Invalidate() + store.Reselect() } func (ml *MessageList) SetStore(store *lib.MessageStore) {