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:
parent
c2f4404fca
commit
a953e4dbe9
4 changed files with 27 additions and 28 deletions
|
@ -52,9 +52,8 @@ func (Clear) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
if clearSelected {
|
if clearSelected {
|
||||||
defer store.Select(0)
|
defer store.Select(0)
|
||||||
} else {
|
} else {
|
||||||
defer store.Reselect(store.Selected())
|
store.SetReselect(store.Selected())
|
||||||
}
|
}
|
||||||
|
|
||||||
store.ApplyClear()
|
store.ApplyClear()
|
||||||
acct.SetStatus(statusline.SearchFilterClear())
|
acct.SetStatus(statusline.SearchFilterClear())
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ func (ToggleThreads) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer store.Reselect(store.Selected())
|
store.SetReselect(store.Selected())
|
||||||
store.SetThreadedView(!store.ThreadedView())
|
store.SetThreadedView(!store.ThreadedView())
|
||||||
acct.SetStatus(statusline.Threading(store.ThreadedView()))
|
acct.SetStatus(statusline.Threading(store.ThreadedView()))
|
||||||
acct.Messages().Invalidate()
|
acct.Messages().Invalidate()
|
||||||
|
|
|
@ -21,6 +21,7 @@ type MessageStore struct {
|
||||||
Threads []*types.Thread
|
Threads []*types.Thread
|
||||||
|
|
||||||
selected int
|
selected int
|
||||||
|
reselect *models.MessageInfo
|
||||||
bodyCallbacks map[uint32][]func(*types.FullMessage)
|
bodyCallbacks map[uint32][]func(*types.FullMessage)
|
||||||
headerCallbacks map[uint32][]func(*types.MessageInfo)
|
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) {
|
func (store *MessageStore) Update(msg types.WorkerMessage) {
|
||||||
update := false
|
update := false
|
||||||
directoryChange := false
|
directoryChange := false
|
||||||
|
if store.reselect == nil {
|
||||||
|
store.SetReselect(store.Selected())
|
||||||
|
}
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case *types.DirectoryInfo:
|
case *types.DirectoryInfo:
|
||||||
store.DirInfo = *msg.Info
|
store.DirInfo = *msg.Info
|
||||||
|
@ -363,6 +367,7 @@ func (store *MessageStore) SetThreadedView(thread bool) {
|
||||||
if store.threadedView {
|
if store.threadedView {
|
||||||
store.runThreadBuilder()
|
store.runThreadBuilder()
|
||||||
}
|
}
|
||||||
|
store.Reselect()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
store.Sort(store.sortCriteria, nil)
|
store.Sort(store.sortCriteria, nil)
|
||||||
|
@ -508,11 +513,11 @@ func (store *MessageStore) Select(index int) {
|
||||||
store.updateVisual()
|
store.updateVisual()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *MessageStore) Reselect(info *models.MessageInfo) {
|
func (store *MessageStore) Reselect() {
|
||||||
if info == nil {
|
if store.reselect == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uid := info.Uid
|
uid := store.reselect.Uid
|
||||||
newIdx := 0
|
newIdx := 0
|
||||||
for idx, uidStore := range store.Uids() {
|
for idx, uidStore := range store.Uids() {
|
||||||
if uidStore == uid {
|
if uidStore == uid {
|
||||||
|
@ -520,9 +525,14 @@ func (store *MessageStore) Reselect(info *models.MessageInfo) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
store.reselect = nil
|
||||||
store.Select(newIdx)
|
store.Select(newIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (store *MessageStore) SetReselect(info *models.MessageInfo) {
|
||||||
|
store.reselect = info
|
||||||
|
}
|
||||||
|
|
||||||
// Mark sets the marked state on a MessageInfo
|
// Mark sets the marked state on a MessageInfo
|
||||||
func (store *MessageStore) Mark(uid uint32) {
|
func (store *MessageStore) Mark(uid uint32) {
|
||||||
if store.visualMarkMode {
|
if store.visualMarkMode {
|
||||||
|
@ -718,11 +728,21 @@ func (store *MessageStore) SetFilter(args []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *MessageStore) ApplyClear() {
|
func (store *MessageStore) ApplyClear() {
|
||||||
|
if store.reselect == nil {
|
||||||
|
store.SetReselect(store.Selected())
|
||||||
|
}
|
||||||
store.filter = []string{"filter"}
|
store.filter = []string{"filter"}
|
||||||
|
store.results = nil
|
||||||
if store.onFilterChange != nil {
|
if store.onFilterChange != nil {
|
||||||
store.onFilterChange(store)
|
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) {
|
func (store *MessageStore) nextPrevResult(delta int) {
|
||||||
|
|
|
@ -345,27 +345,7 @@ func (ml *MessageList) storeUpdate(store *lib.MessageStore) {
|
||||||
if ml.Store() != store {
|
if ml.Store() != store {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uids := store.Uids()
|
store.Reselect()
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *MessageList) SetStore(store *lib.MessageStore) {
|
func (ml *MessageList) SetStore(store *lib.MessageStore) {
|
||||||
|
|
Loading…
Reference in a new issue