Fetch valid UIDs from server after opening dir
This commit is contained in:
parent
289e3b09ea
commit
b3896476a0
6 changed files with 141 additions and 100 deletions
|
@ -21,6 +21,7 @@ type AccountView struct {
|
|||
interactive ui.Interactive
|
||||
onInvalidate func(d ui.Drawable)
|
||||
runCmd func(cmd string) error
|
||||
msgStores map[string]*MessageStore
|
||||
statusline *StatusLine
|
||||
statusbar *ui.Stack
|
||||
worker *types.Worker
|
||||
|
@ -64,9 +65,10 @@ func NewAccountView(conf *config.AccountConfig,
|
|||
dirlist: dirlist,
|
||||
grid: grid,
|
||||
logger: logger,
|
||||
msgStores: make(map[string]*MessageStore),
|
||||
runCmd: runCmd,
|
||||
statusline: statusline,
|
||||
statusbar: statusbar,
|
||||
statusline: statusline,
|
||||
worker: worker,
|
||||
}
|
||||
|
||||
|
@ -157,10 +159,6 @@ func (acct *AccountView) connected(msg types.WorkerMessage) {
|
|||
Message: types.RespondTo(msg),
|
||||
Approved: true,
|
||||
}, acct.connected)
|
||||
case *types.Error:
|
||||
acct.logger.Printf("%v", msg.Error)
|
||||
acct.statusline.Set(fmt.Sprintf("%v", msg.Error)).
|
||||
Color(tcell.ColorRed, tcell.ColorDefault)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,5 +167,30 @@ func (acct *AccountView) Directories() *DirectoryList {
|
|||
}
|
||||
|
||||
func (acct *AccountView) onMessage(msg types.WorkerMessage) {
|
||||
// TODO
|
||||
switch msg := msg.(type) {
|
||||
case *types.Done:
|
||||
switch msg.InResponseTo().(type) {
|
||||
case *types.OpenDirectory:
|
||||
acct.worker.PostAction(&types.FetchDirectoryContents{},
|
||||
func(msg types.WorkerMessage) {
|
||||
// TODO: Do we care
|
||||
})
|
||||
}
|
||||
case *types.DirectoryInfo:
|
||||
if store, ok := acct.msgStores[msg.Name]; ok {
|
||||
store.Update(msg)
|
||||
} else {
|
||||
acct.msgStores[msg.Name] = NewMessageStore(msg)
|
||||
}
|
||||
case *types.DirectoryContents:
|
||||
store := acct.msgStores[acct.dirlist.selected]
|
||||
store.Update(msg)
|
||||
case *types.MessageInfo:
|
||||
store := acct.msgStores[acct.dirlist.selected]
|
||||
store.Update(msg)
|
||||
case *types.Error:
|
||||
acct.logger.Printf("%v", msg.Error)
|
||||
acct.statusline.Set(fmt.Sprintf("%v", msg.Error)).
|
||||
Color(tcell.ColorRed, tcell.ColorDefault)
|
||||
}
|
||||
}
|
||||
|
|
36
widgets/msglist.go
Normal file
36
widgets/msglist.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package widgets
|
||||
|
||||
import (
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
||||
)
|
||||
|
||||
type MessageStore struct {
|
||||
DirInfo types.DirectoryInfo
|
||||
Messages map[uint64]*types.MessageInfo
|
||||
}
|
||||
|
||||
func NewMessageStore(dirInfo *types.DirectoryInfo) *MessageStore {
|
||||
return &MessageStore{DirInfo: *dirInfo}
|
||||
}
|
||||
|
||||
func (store *MessageStore) Update(msg types.WorkerMessage) {
|
||||
switch msg := msg.(type) {
|
||||
case *types.DirectoryInfo:
|
||||
store.DirInfo = *msg
|
||||
break
|
||||
case *types.DirectoryContents:
|
||||
newMap := make(map[uint64]*types.MessageInfo)
|
||||
for _, uid := range msg.Uids {
|
||||
if msg, ok := store.Messages[uid]; ok {
|
||||
newMap[uid] = msg
|
||||
} else {
|
||||
newMap[uid] = nil
|
||||
}
|
||||
}
|
||||
store.Messages = newMap
|
||||
break
|
||||
case *types.MessageInfo:
|
||||
store.Messages[msg.Uid] = msg
|
||||
break
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package imap
|
||||
|
||||
import (
|
||||
"github.com/emersion/go-imap"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
||||
)
|
||||
|
||||
|
@ -18,3 +20,35 @@ func (imapw *IMAPWorker) handleOpenDirectory(msg *types.OpenDirectory) {
|
|||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (imapw *IMAPWorker) handleFetchDirectoryContents(
|
||||
msg *types.FetchDirectoryContents) {
|
||||
|
||||
imapw.worker.Logger.Printf("Fetching UID list")
|
||||
|
||||
go func() {
|
||||
seqSet := &imap.SeqSet{}
|
||||
seqSet.AddRange(1, imapw.selected.Messages)
|
||||
uid32, err := imapw.client.UidSearch(&imap.SearchCriteria{
|
||||
SeqNum: seqSet,
|
||||
})
|
||||
if err != nil {
|
||||
imapw.worker.PostMessage(&types.Error{
|
||||
Message: types.RespondTo(msg),
|
||||
Error: err,
|
||||
}, nil)
|
||||
} else {
|
||||
imapw.worker.Logger.Printf("Found %d UIDs", len(uid32))
|
||||
var uids []uint64
|
||||
for _, uid := range uid32 {
|
||||
uids = append(uids,
|
||||
(uint64(imapw.selected.UidValidity)<<32)|uint64(uid))
|
||||
}
|
||||
imapw.worker.PostMessage(&types.DirectoryContents{
|
||||
Message: types.RespondTo(msg),
|
||||
Uids: uids,
|
||||
}, nil)
|
||||
imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -29,9 +29,10 @@ type IMAPWorker struct {
|
|||
user *url.Userinfo
|
||||
}
|
||||
|
||||
worker *types.Worker
|
||||
client *imapClient
|
||||
selected imap.MailboxStatus
|
||||
updates chan client.Update
|
||||
worker *types.Worker
|
||||
}
|
||||
|
||||
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
|
||||
|
@ -151,6 +152,8 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
|
|||
w.handleListDirectories(msg)
|
||||
case *types.OpenDirectory:
|
||||
w.handleOpenDirectory(msg)
|
||||
case *types.FetchDirectoryContents:
|
||||
w.handleFetchDirectoryContents(msg)
|
||||
default:
|
||||
return errUnsupported
|
||||
}
|
||||
|
@ -162,6 +165,9 @@ func (w *IMAPWorker) handleImapUpdate(update client.Update) {
|
|||
switch update := update.(type) {
|
||||
case *client.MailboxUpdate:
|
||||
status := update.Mailbox
|
||||
if w.selected.Name == status.Name {
|
||||
w.selected = *status
|
||||
}
|
||||
w.worker.PostMessage(&types.DirectoryInfo{
|
||||
Flags: status.Flags,
|
||||
Name: status.Name,
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
package worker
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/config"
|
||||
)
|
||||
|
||||
type WorkerMessage interface {
|
||||
InResponseTo() WorkerMessage
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
inResponseTo WorkerMessage
|
||||
}
|
||||
|
||||
func RespondTo(msg WorkerMessage) Message {
|
||||
return Message{
|
||||
inResponseTo: msg,
|
||||
}
|
||||
}
|
||||
|
||||
func (m Message) InResponseTo() WorkerMessage {
|
||||
return m.inResponseTo
|
||||
}
|
||||
|
||||
// Meta-messages
|
||||
|
||||
type Done struct {
|
||||
Message
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Message
|
||||
Error error
|
||||
}
|
||||
|
||||
type Unsupported struct {
|
||||
Message
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
type ApproveCertificate struct {
|
||||
Message
|
||||
Approved bool
|
||||
}
|
||||
|
||||
type Configure struct {
|
||||
Message
|
||||
Config *config.AccountConfig
|
||||
}
|
||||
|
||||
type Connect struct {
|
||||
Message
|
||||
}
|
||||
|
||||
type Disconnect struct {
|
||||
Message
|
||||
}
|
||||
|
||||
type ListDirectories struct {
|
||||
Message
|
||||
}
|
||||
|
||||
type OpenDirectory struct {
|
||||
Message
|
||||
Directory string
|
||||
}
|
||||
|
||||
// Messages
|
||||
|
||||
type CertificateApprovalRequest struct {
|
||||
Message
|
||||
CertPool *x509.CertPool
|
||||
}
|
||||
|
||||
type Directory struct {
|
||||
Message
|
||||
Attributes []string
|
||||
Name string
|
||||
}
|
||||
|
||||
type DirectoryInfo struct {
|
||||
Message
|
||||
Flags []string
|
||||
Name string
|
||||
ReadOnly bool
|
||||
|
||||
Exists, Recent, Unseen int
|
||||
}
|
|
@ -2,6 +2,10 @@ package types
|
|||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"net/mail"
|
||||
"time"
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/config"
|
||||
)
|
||||
|
@ -68,6 +72,20 @@ type OpenDirectory struct {
|
|||
Directory string
|
||||
}
|
||||
|
||||
type FetchDirectoryContents struct {
|
||||
Message
|
||||
}
|
||||
|
||||
type FetchMessageHeaders struct {
|
||||
Message
|
||||
Uids imap.SeqSet
|
||||
}
|
||||
|
||||
type FetchMessageBodies struct {
|
||||
Message
|
||||
Uids imap.SeqSet
|
||||
}
|
||||
|
||||
// Messages
|
||||
|
||||
type CertificateApprovalRequest struct {
|
||||
|
@ -89,3 +107,18 @@ type DirectoryInfo struct {
|
|||
|
||||
Exists, Recent, Unseen int
|
||||
}
|
||||
|
||||
type DirectoryContents struct {
|
||||
Message
|
||||
Uids []uint64
|
||||
}
|
||||
|
||||
type MessageInfo struct {
|
||||
Message
|
||||
Envelope *imap.Envelope
|
||||
Flags []string
|
||||
InternalDate time.Time
|
||||
Mail *mail.Message
|
||||
Size uint32
|
||||
Uid uint64
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue