diff options
Diffstat (limited to 'worker/maildir/worker.go')
-rw-r--r-- | worker/maildir/worker.go | 62 |
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) { |