Handle incoming emails gracefully
This commit is contained in:
parent
bb46b2b7e1
commit
026e8a17ca
|
@ -1,6 +1,7 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -140,6 +141,11 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
|
|||
switch msg := msg.(type) {
|
||||
case *types.DirectoryInfo:
|
||||
store.DirInfo = *msg
|
||||
fmt.Printf("got dirinfo, %d exists, %d known\n",
|
||||
store.DirInfo.Exists, len(store.Uids))
|
||||
if store.DirInfo.Exists != len(store.Uids) {
|
||||
store.worker.PostAction(&types.FetchDirectoryContents{}, nil)
|
||||
}
|
||||
update = true
|
||||
case *types.DirectoryContents:
|
||||
newMap := make(map[uint32]*types.MessageInfo)
|
||||
|
|
|
@ -161,17 +161,17 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
|
|||
} else {
|
||||
acct.msglist.SetStore(nil)
|
||||
}
|
||||
acct.worker.PostAction(&types.FetchDirectoryContents{},
|
||||
func(msg types.WorkerMessage) {
|
||||
store := acct.msgStores[acct.dirlist.selected]
|
||||
acct.msglist.SetStore(store)
|
||||
})
|
||||
}
|
||||
case *types.DirectoryInfo:
|
||||
if store, ok := acct.msgStores[msg.Name]; ok {
|
||||
store.Update(msg)
|
||||
} else {
|
||||
acct.msgStores[msg.Name] = lib.NewMessageStore(acct.worker, msg)
|
||||
store = lib.NewMessageStore(acct.worker, msg)
|
||||
acct.msgStores[msg.Name] = store
|
||||
store.OnUpdate(func(_ *lib.MessageStore) {
|
||||
store.OnUpdate(nil)
|
||||
acct.msglist.SetStore(store)
|
||||
})
|
||||
}
|
||||
case *types.DirectoryContents:
|
||||
store := acct.msgStores[acct.dirlist.selected]
|
||||
|
|
|
@ -109,6 +109,7 @@ func (ml *MessageList) Height() int {
|
|||
}
|
||||
|
||||
func (ml *MessageList) storeUpdate(store *lib.MessageStore) {
|
||||
ml.logger.Println("message store updated")
|
||||
if ml.Store() != store {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ func (imapw *IMAPWorker) handleOpenDirectory(msg *types.OpenDirectory) {
|
|||
}, nil)
|
||||
} else {
|
||||
imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
|
||||
if imapw.idleStop == nil {
|
||||
imapw.idleStop = make(chan struct{})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ var errUnsupported = fmt.Errorf("unsupported command")
|
|||
|
||||
type imapClient struct {
|
||||
*client.Client
|
||||
*idle.IdleClient
|
||||
idle *idle.IdleClient
|
||||
}
|
||||
|
||||
type IMAPWorker struct {
|
||||
|
@ -30,6 +30,8 @@ type IMAPWorker struct {
|
|||
}
|
||||
|
||||
client *imapClient
|
||||
idleStop chan struct{}
|
||||
idleDone chan error
|
||||
selected imap.MailboxStatus
|
||||
updates chan client.Update
|
||||
worker *types.Worker
|
||||
|
@ -39,6 +41,7 @@ type IMAPWorker struct {
|
|||
|
||||
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
|
||||
return &IMAPWorker{
|
||||
idleDone: make(chan error),
|
||||
updates: make(chan client.Update, 50),
|
||||
worker: worker,
|
||||
}
|
||||
|
@ -80,6 +83,13 @@ func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
|
|||
}
|
||||
|
||||
func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
|
||||
if w.idleStop != nil {
|
||||
close(w.idleStop)
|
||||
if err := <-w.idleDone; err != nil {
|
||||
w.worker.PostMessage(&types.Error{Error: err}, nil)
|
||||
}
|
||||
}
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case *types.Unsupported:
|
||||
// No-op
|
||||
|
@ -167,6 +177,13 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
|
|||
default:
|
||||
return errUnsupported
|
||||
}
|
||||
|
||||
if w.idleStop != nil {
|
||||
w.idleStop = make(chan struct{})
|
||||
go func() {
|
||||
w.idleDone <- w.client.idle.IdleWithFallback(w.idleStop, 0)
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue