aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--worker/maildir/worker.go62
1 files changed, 22 insertions, 40 deletions
diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go
index ded0faac..ba72432c 100644
--- a/worker/maildir/worker.go
+++ b/worker/maildir/worker.go
@@ -14,6 +14,7 @@ import (
"sort"
"strings"
"sync"
+ "time"
"github.com/emersion/go-maildir"
@@ -41,6 +42,8 @@ type Worker struct {
selectedInfo *models.DirectoryInfo
worker *types.Worker
watcher types.FSWatcher
+ watcherDebounce *time.Timer
+ fsEvents chan struct{}
currentSortCriteria []*types.SortCriterion
maildirpp bool // whether to use Maildir++ directory layout
capabilities *models.Capabilities
@@ -57,8 +60,9 @@ func NewWorker(worker *types.Worker) (types.Backend, error) {
Sort: true,
Thread: true,
},
- worker: worker,
- watcher: watch,
+ worker: worker,
+ watcher: watch,
+ fsEvents: make(chan struct{}),
}, nil
}
@@ -85,8 +89,17 @@ func (w *Worker) Run() {
select {
case action := <-w.worker.Actions:
w.handleAction(action)
- case ev := <-w.watcher.Events():
- w.handleFSEvent(ev)
+ case <-w.watcher.Events():
+ if w.watcherDebounce != nil {
+ w.watcherDebounce.Stop()
+ }
+ // Debounce FS changes
+ w.watcherDebounce = time.AfterFunc(50*time.Millisecond, func() {
+ defer log.PanicHandler()
+ w.fsEvents <- struct{}{}
+ })
+ case <-w.fsEvents:
+ w.handleFSEvent()
}
}
}
@@ -121,7 +134,7 @@ func (w *Worker) handleAction(action types.WorkerMessage) {
}
}
-func (w *Worker) handleFSEvent(ev *types.FSEvent) {
+func (w *Worker) handleFSEvent() {
// if there's not a selected directory to rescan, ignore
if w.selected == nil {
return
@@ -133,41 +146,10 @@ func (w *Worker) handleFSEvent(ev *types.FSEvent) {
}
w.selectedInfo = w.getDirectoryInfo(w.selectedName)
- dirInfoMsg := &types.DirectoryInfo{
- Info: w.selectedInfo,
- }
-
- base := filepath.Base(ev.Path)
- parts := strings.SplitN(base, ":", 2)
- if len(parts) != 2 {
- log.Errorf("Couldn't parse key from file: %s", ev.Path)
- return
- }
- msg := w.c.MessageFromKey(*w.selected, parts[0])
-
- switch ev.Operation {
- case types.FSCreate:
- // TODO for FSCreate we should send a new message type that
- // creates the message in the UI, does a binary search based on
- // current sort criteria and inserts message at proper index
- // For now, we just refetch the list.
- dirInfoMsg.Refetch = true
- case types.FSRename:
- msgInfo, err := msg.MessageInfo()
- if err != nil {
- log.Errorf(err.Error())
- return
- }
- w.worker.PostMessage(&types.MessageInfo{
- Info: msgInfo,
- }, nil)
- case types.FSRemove:
- w.worker.PostMessage(&types.MessagesDeleted{
- Uids: []uint32{msg.uid},
- }, nil)
- }
-
- w.worker.PostMessage(dirInfoMsg, nil)
+ w.worker.PostMessage(&types.DirectoryInfo{
+ Info: w.selectedInfo,
+ Refetch: true,
+ }, nil)
}
func (w *Worker) done(msg types.WorkerMessage) {