dirlist: skip unnecessary change-folder action

when traversing the directory list, aerc will fetch the contents for
every directory even though the user might just move on to the next.
This causes an unnecessary delay (and load on the worker) and can be
avoided by skipping the old change-folder action when a newer one
arrives within a predefined time interval.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
This commit is contained in:
Koni Marti 2022-01-23 10:31:41 +01:00 committed by Robin Jarry
parent eafb537081
commit cb3090956c
1 changed files with 55 additions and 39 deletions

View File

@ -6,6 +6,7 @@ import (
"math" "math"
"regexp" "regexp"
"sort" "sort"
"time"
"github.com/gdamore/tcell/v2" "github.com/gdamore/tcell/v2"
"github.com/mattn/go-runewidth" "github.com/mattn/go-runewidth"
@ -20,27 +21,29 @@ import (
type DirectoryList struct { type DirectoryList struct {
ui.Invalidatable ui.Invalidatable
aercConf *config.AercConfig aercConf *config.AercConfig
acctConf *config.AccountConfig acctConf *config.AccountConfig
store *lib.DirStore store *lib.DirStore
dirs []string dirs []string
logger *log.Logger logger *log.Logger
selecting string selecting string
selected string selected string
scroll int scroll int
spinner *Spinner spinner *Spinner
worker *types.Worker worker *types.Worker
skipSelect chan bool
} }
func NewDirectoryList(conf *config.AercConfig, acctConf *config.AccountConfig, func NewDirectoryList(conf *config.AercConfig, acctConf *config.AccountConfig,
logger *log.Logger, worker *types.Worker) *DirectoryList { logger *log.Logger, worker *types.Worker) *DirectoryList {
dirlist := &DirectoryList{ dirlist := &DirectoryList{
aercConf: conf, aercConf: conf,
acctConf: acctConf, acctConf: acctConf,
logger: logger, logger: logger,
store: lib.NewDirStore(), store: lib.NewDirStore(),
worker: worker, worker: worker,
skipSelect: make(chan bool),
} }
uiConf := dirlist.UiConfig() uiConf := dirlist.UiConfig()
dirlist.spinner = NewSpinner(&uiConf) dirlist.spinner = NewSpinner(&uiConf)
@ -87,32 +90,45 @@ func (dirlist *DirectoryList) UpdateList(done func(dirs []string)) {
func (dirlist *DirectoryList) Select(name string) { func (dirlist *DirectoryList) Select(name string) {
dirlist.selecting = name dirlist.selecting = name
dirlist.worker.PostAction(&types.OpenDirectory{Directory: name},
func(msg types.WorkerMessage) { close(dirlist.skipSelect)
switch msg.(type) { dirlist.skipSelect = make(chan bool)
case *types.Error:
dirlist.selecting = "" go func() {
case *types.Done: select {
dirlist.selected = dirlist.selecting case <-time.After(1 * time.Second):
dirlist.filterDirsByFoldersConfig() dirlist.worker.PostAction(&types.OpenDirectory{Directory: name},
hasSelected := false func(msg types.WorkerMessage) {
for _, d := range dirlist.dirs { switch msg.(type) {
if d == dirlist.selected { case *types.Error:
hasSelected = true dirlist.selecting = ""
break dirlist.selected = ""
case *types.Done:
dirlist.selected = dirlist.selecting
dirlist.filterDirsByFoldersConfig()
hasSelected := false
for _, d := range dirlist.dirs {
if d == dirlist.selected {
hasSelected = true
break
}
}
if !hasSelected && dirlist.selected != "" {
dirlist.dirs = append(dirlist.dirs, dirlist.selected)
}
if dirlist.acctConf.EnableFoldersSort {
sort.Strings(dirlist.dirs)
}
dirlist.sortDirsByFoldersSortConfig()
} }
} dirlist.Invalidate()
if !hasSelected && dirlist.selected != "" { })
dirlist.dirs = append(dirlist.dirs, dirlist.selected)
}
if dirlist.acctConf.EnableFoldersSort {
sort.Strings(dirlist.dirs)
}
dirlist.sortDirsByFoldersSortConfig()
}
dirlist.Invalidate() dirlist.Invalidate()
}) case <-dirlist.skipSelect:
dirlist.Invalidate() dirlist.logger.Println("dirlist: skip", name)
return
}
}()
} }
func (dirlist *DirectoryList) Selected() string { func (dirlist *DirectoryList) Selected() string {