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 <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Tim Culverhouse 2022-07-05 14:48:41 -05:00 committed by Robin Jarry
parent c2f4404fca
commit a953e4dbe9
4 changed files with 27 additions and 28 deletions

View file

@ -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())

View file

@ -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()

View file

@ -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) {

View file

@ -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) {