diff --git a/lib/msgstore.go b/lib/msgstore.go index a545f62..58c5fab 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -48,6 +48,10 @@ type MessageStore struct { pendingHeaders map[uint32]interface{} worker *types.Worker + needsFlags []uint32 + fetchFlagsDebounce *time.Timer + fetchFlagsDelay time.Duration + triggerNewEmail func(*models.MessageInfo) triggerDirectoryChange func() @@ -91,6 +95,9 @@ func NewMessageStore(worker *types.Worker, pendingHeaders: make(map[uint32]interface{}), worker: worker, + needsFlags: []uint32{}, + fetchFlagsDelay: 50 * time.Millisecond, + triggerNewEmail: triggerNewEmail, triggerDirectoryChange: triggerDirectoryChange, @@ -251,6 +258,10 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { } else if msg.Info.Envelope != nil { store.Messages[msg.Info.Uid] = msg.Info } + if msg.NeedsFlags { + store.needsFlags = append(store.needsFlags, msg.Info.Uid) + store.fetchFlags() + } seen := false recent := false for _, flag := range msg.Info.Flags { @@ -752,3 +763,15 @@ func (store *MessageStore) Capabilities() *models.Capabilities { func (store *MessageStore) SelectedIndex() int { return store.FindIndexByUid(store.selectedUid) } + +func (store *MessageStore) fetchFlags() { + if store.fetchFlagsDebounce != nil { + store.fetchFlagsDebounce.Stop() + } + store.fetchFlagsDebounce = time.AfterFunc(store.fetchFlagsDelay, func() { + store.worker.PostAction(&types.FetchMessageFlags{ + Uids: store.needsFlags, + }, nil) + store.needsFlags = []uint32{} + }) +} diff --git a/worker/imap/cache.go b/worker/imap/cache.go index 3c807c5..17a622d 100644 --- a/worker/imap/cache.go +++ b/worker/imap/cache.go @@ -85,7 +85,7 @@ func (w *IMAPWorker) cacheHeader(mi *models.MessageInfo) { func (w *IMAPWorker) getCachedHeaders(msg *types.FetchMessageHeaders) []uint32 { logging.Debugf("Retrieving headers from cache: %v", msg.Uids) - var need, found []uint32 + var need []uint32 uv := fmt.Sprintf("%d", w.selected.UidValidity) for _, uid := range msg.Uids { u := fmt.Sprintf("%d", uid) @@ -118,17 +118,11 @@ func (w *IMAPWorker) getCachedHeaders(msg *types.FetchMessageHeaders) []uint32 { Uid: ch.Uid, RFC822Headers: hdr, } - found = append(found, uid) logging.Debugf("located cached header %s.%s", uv, u) w.worker.PostMessage(&types.MessageInfo{ - Message: types.RespondTo(msg), - Info: mi, - }, nil) - } - if len(found) > 0 { - // Post in a separate goroutine to prevent deadlocking - go w.worker.PostAction(&types.FetchMessageFlags{ - Uids: found, + Message: types.RespondTo(msg), + Info: mi, + NeedsFlags: true, }, nil) } return need diff --git a/worker/types/messages.go b/worker/types/messages.go index acd515f..9194cbe 100644 --- a/worker/types/messages.go +++ b/worker/types/messages.go @@ -212,7 +212,8 @@ type SearchResults struct { type MessageInfo struct { Message - Info *models.MessageInfo + Info *models.MessageInfo + NeedsFlags bool } type FullMessage struct {