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
|
interactive ui.Interactive
|
||||||
onInvalidate func(d ui.Drawable)
|
onInvalidate func(d ui.Drawable)
|
||||||
runCmd func(cmd string) error
|
runCmd func(cmd string) error
|
||||||
|
msgStores map[string]*MessageStore
|
||||||
statusline *StatusLine
|
statusline *StatusLine
|
||||||
statusbar *ui.Stack
|
statusbar *ui.Stack
|
||||||
worker *types.Worker
|
worker *types.Worker
|
||||||
|
@ -64,9 +65,10 @@ func NewAccountView(conf *config.AccountConfig,
|
||||||
dirlist: dirlist,
|
dirlist: dirlist,
|
||||||
grid: grid,
|
grid: grid,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
msgStores: make(map[string]*MessageStore),
|
||||||
runCmd: runCmd,
|
runCmd: runCmd,
|
||||||
statusline: statusline,
|
|
||||||
statusbar: statusbar,
|
statusbar: statusbar,
|
||||||
|
statusline: statusline,
|
||||||
worker: worker,
|
worker: worker,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,10 +159,6 @@ func (acct *AccountView) connected(msg types.WorkerMessage) {
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
Approved: true,
|
Approved: true,
|
||||||
}, acct.connected)
|
}, 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) {
|
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
|
package imap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/emersion/go-imap"
|
||||||
|
|
||||||
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
"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
|
user *url.Userinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
worker *types.Worker
|
client *imapClient
|
||||||
client *imapClient
|
selected imap.MailboxStatus
|
||||||
updates chan client.Update
|
updates chan client.Update
|
||||||
|
worker *types.Worker
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
|
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
|
||||||
|
@ -151,6 +152,8 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
|
||||||
w.handleListDirectories(msg)
|
w.handleListDirectories(msg)
|
||||||
case *types.OpenDirectory:
|
case *types.OpenDirectory:
|
||||||
w.handleOpenDirectory(msg)
|
w.handleOpenDirectory(msg)
|
||||||
|
case *types.FetchDirectoryContents:
|
||||||
|
w.handleFetchDirectoryContents(msg)
|
||||||
default:
|
default:
|
||||||
return errUnsupported
|
return errUnsupported
|
||||||
}
|
}
|
||||||
|
@ -162,6 +165,9 @@ func (w *IMAPWorker) handleImapUpdate(update client.Update) {
|
||||||
switch update := update.(type) {
|
switch update := update.(type) {
|
||||||
case *client.MailboxUpdate:
|
case *client.MailboxUpdate:
|
||||||
status := update.Mailbox
|
status := update.Mailbox
|
||||||
|
if w.selected.Name == status.Name {
|
||||||
|
w.selected = *status
|
||||||
|
}
|
||||||
w.worker.PostMessage(&types.DirectoryInfo{
|
w.worker.PostMessage(&types.DirectoryInfo{
|
||||||
Flags: status.Flags,
|
Flags: status.Flags,
|
||||||
Name: status.Name,
|
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 (
|
import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"net/mail"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/emersion/go-imap"
|
||||||
|
|
||||||
"git.sr.ht/~sircmpwn/aerc2/config"
|
"git.sr.ht/~sircmpwn/aerc2/config"
|
||||||
)
|
)
|
||||||
|
@ -68,6 +72,20 @@ type OpenDirectory struct {
|
||||||
Directory string
|
Directory string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FetchDirectoryContents struct {
|
||||||
|
Message
|
||||||
|
}
|
||||||
|
|
||||||
|
type FetchMessageHeaders struct {
|
||||||
|
Message
|
||||||
|
Uids imap.SeqSet
|
||||||
|
}
|
||||||
|
|
||||||
|
type FetchMessageBodies struct {
|
||||||
|
Message
|
||||||
|
Uids imap.SeqSet
|
||||||
|
}
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
|
|
||||||
type CertificateApprovalRequest struct {
|
type CertificateApprovalRequest struct {
|
||||||
|
@ -89,3 +107,18 @@ type DirectoryInfo struct {
|
||||||
|
|
||||||
Exists, Recent, Unseen int
|
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