diff --git a/lib/msgstore.go b/lib/msgstore.go index d47c14f..2832346 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -53,7 +53,9 @@ type MessageStore struct { threadBuilderDebounce *time.Timer threadBuilderDelay time.Duration + threadCallback func() + // threads mutex protects the store.threads and store.threadCallback threadsMutex sync.Mutex } @@ -343,6 +345,8 @@ func (store *MessageStore) SetThreadedView(thread bool) { if store.buildThreads { if store.threadedView { store.runThreadBuilder() + } else if store.threadBuilderDebounce != nil { + store.threadBuilderDebounce.Stop() } return } @@ -376,35 +380,19 @@ func (store *MessageStore) runThreadBuilder() { } } store.threadBuilderDebounce = time.AfterFunc(store.threadBuilderDelay, func() { - // temporarily deactiviate the selector in the message list by - // setting SelectedUid to the MagicUid - oldUid := store.SelectedUid() - store.Select(MagicUid) - - // Get the current index (we want to stay at that position in - // the updated uid list to provide a similar scrolling - // experience to the user as in the regular view - idx := store.FindIndexByUid(oldUid) - // build new threads th := store.builder.Threads(store.uids) - // try to select the same index in the updated uid list; if - // index is out of bound, stay at the selected message - rebuildUids := store.builder.Uids() - if idx >= 0 && idx < len(rebuildUids) { - store.Select(rebuildUids[idx]) - } else { - store.Select(oldUid) - } - - // save local threads to the message store variable + // save local threads to the message store variable and + // run callback if defined (callback should reposition cursor) store.threadsMutex.Lock() store.threads = th + if store.threadCallback != nil { + store.threadCallback() + } store.threadsMutex.Unlock() - // invalidate message list so that it is redrawn with the new - // threads and selected message + // invalidate message list if store.onUpdate != nil { store.onUpdate(store) } @@ -543,6 +531,11 @@ func (store *MessageStore) SelectedUid() uint32 { } func (store *MessageStore) Select(uid uint32) { + store.threadsMutex.Lock() + if store.threadCallback != nil { + store.threadCallback = nil + } + store.threadsMutex.Unlock() store.selectedUid = uid if store.marker != nil { store.marker.UpdateVisualMark() @@ -572,6 +565,16 @@ func (store *MessageStore) NextPrev(delta int) { store.Select(uids[newIdx]) + if store.BuildThreads() && store.ThreadedView() { + store.threadsMutex.Lock() + store.threadCallback = func() { + if uids := store.Uids(); len(uids) > newIdx { + store.selectedUid = uids[newIdx] + } + } + store.threadsMutex.Unlock() + } + if store.marker != nil { store.marker.UpdateVisualMark() } @@ -672,6 +675,7 @@ func (store *MessageStore) Sort(criteria []*types.SortCriterion, cb func(types.W store.Sorting = true handle_return := func(msg types.WorkerMessage) { + store.Select(store.SelectedUid()) store.Sorting = false if cb != nil { cb(msg) diff --git a/widgets/msglist.go b/widgets/msglist.go index 935566f..ba09a8e 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -70,9 +70,11 @@ func (ml *MessageList) Draw(ctx *ui.Context) { ml.UpdateScroller(ml.height, len(store.Uids())) if store := ml.Store(); store != nil && len(store.Uids()) > 0 { - if idx := store.FindIndexByUid(store.SelectedUid()); idx >= 0 { - ml.EnsureScroll(len(store.Uids()) - idx - 1) + idx := store.FindIndexByUid(store.SelectedUid()) + if idx < 0 { + idx = len(store.Uids()) - 1 } + ml.EnsureScroll(len(store.Uids()) - idx - 1) } textWidth := ctx.Width()