From e00efbc1956bf1f851e80d6439b45ce3cc463d66 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Tue, 20 Aug 2024 06:01:28 -0500 Subject: jmap: fetch created messages and set recent flag When a push notification arrives, automatically fetch any newly created messages. Set the Recent flag on these messages to trigger a notification in the UI. Signed-off-by: Tim Culverhouse Acked-by: Robin Jarry --- worker/jmap/push.go | 70 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 21 deletions(-) (limited to 'worker') diff --git a/worker/jmap/push.go b/worker/jmap/push.go index 0a85332e..bc90dd77 100644 --- a/worker/jmap/push.go +++ b/worker/jmap/push.go @@ -107,12 +107,14 @@ func (w *JMAPWorker) refresh(newState jmap.TypeState) error { mboxes[id] = mbox } } + emailUpdated := "" + emailCreated := "" if emailState != "" && newState["Email"] != emailState { callID := req.Invoke(&email.Changes{ Account: w.AccountId(), SinceState: emailState, }) - req.Invoke(&email.Get{ + emailUpdated = req.Invoke(&email.Get{ Account: w.AccountId(), Properties: headersProperties, ReferenceIDs: &jmap.ResultReference{ @@ -122,6 +124,16 @@ func (w *JMAPWorker) refresh(newState jmap.TypeState) error { }, }) + emailCreated = req.Invoke(&email.Get{ + Account: w.AccountId(), + Properties: headersProperties, + ReferenceIDs: &jmap.ResultReference{ + ResultOf: callID, + Name: "Email/changes", + Path: "/created", + }, + }) + for id := range mboxes { contents, err := w.cache.GetFolderContents(id) if err != nil { @@ -246,33 +258,49 @@ func (w *JMAPWorker) refresh(newState jmap.TypeState) error { } case *email.GetResponse: - selectedIds := make(map[jmap.ID]bool) - contents, ok := folderContents[w.selectedMbox] - if ok { - for _, id := range contents.MessageIDs { - selectedIds[id] = true + switch inv.CallID { + case emailUpdated: + selectedIds := make(map[jmap.ID]bool) + contents, ok := folderContents[w.selectedMbox] + if ok { + for _, id := range contents.MessageIDs { + selectedIds[id] = true + } } - } - emails, err := w.fetchEntireThreads(r.List) - if err != nil { - return err - } - - for _, m := range emails { - err = w.cache.PutEmail(m.ID, m) + for _, m := range r.List { + err = w.cache.PutEmail(m.ID, m) + if err != nil { + w.w.Warnf("PutEmail: %s", err) + } + if selectedIds[m.ID] { + w.w.PostMessage(&types.MessageInfo{ + Info: w.translateMsgInfo(m), + }, nil) + } + } + err = w.cache.PutEmailState(r.State) if err != nil { - w.w.Warnf("PutEmail: %s", err) + w.w.Warnf("PutEmailState: %s", err) } - if selectedIds[m.ID] { + case emailCreated: + for _, m := range r.List { + err = w.cache.PutEmail(m.ID, m) + if err != nil { + w.w.Warnf("PutEmail: %s", err) + } + info := w.translateMsgInfo(m) + // Set recent on created messages so we + // get a notification + info.Flags |= models.RecentFlag w.w.PostMessage(&types.MessageInfo{ - Info: w.translateMsgInfo(m), + Info: info, }, nil) } - } - err = w.cache.PutEmailState(r.State) - if err != nil { - w.w.Warnf("PutEmailState: %s", err) + err = w.cache.PutEmailState(r.State) + if err != nil { + w.w.Warnf("PutEmailState: %s", err) + } } case *jmap.MethodError: -- cgit