aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/indexformat.go4
-rw-r--r--lib/msgstore.go37
-rw-r--r--models/models.go52
-rw-r--r--widgets/account.go9
-rw-r--r--widgets/dirlist.go2
-rw-r--r--widgets/msglist.go4
-rw-r--r--widgets/msgviewer.go16
-rw-r--r--widgets/providesmessage.go4
-rw-r--r--worker/imap/fetch.go41
-rw-r--r--worker/imap/list.go9
-rw-r--r--worker/imap/worker.go29
-rw-r--r--worker/types/messages.go25
12 files changed, 146 insertions, 86 deletions
diff --git a/lib/indexformat.go b/lib/indexformat.go
index 9e7a805..43d2ef8 100644
--- a/lib/indexformat.go
+++ b/lib/indexformat.go
@@ -9,11 +9,11 @@ import (
"github.com/emersion/go-imap"
"git.sr.ht/~sircmpwn/aerc/config"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
func ParseIndexFormat(conf *config.AercConfig, number int,
- msg *types.MessageInfo) (string, []interface{}, error) {
+ msg *models.MessageInfo) (string, []interface{}, error) {
format := conf.Ui.IndexFormat
retval := make([]byte, 0, len(format))
diff --git a/lib/msgstore.go b/lib/msgstore.go
index 09cf31f..77160ae 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -6,14 +6,15 @@ import (
"github.com/emersion/go-imap"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
// Accesses to fields must be guarded by MessageStore.Lock/Unlock
type MessageStore struct {
Deleted map[uint32]interface{}
- DirInfo types.DirectoryInfo
- Messages map[uint32]*types.MessageInfo
+ DirInfo models.DirectoryInfo
+ Messages map[uint32]*models.MessageInfo
// Ordered list of known UIDs
Uids []uint32
@@ -33,7 +34,7 @@ type MessageStore struct {
}
func NewMessageStore(worker *types.Worker,
- dirInfo *types.DirectoryInfo) *MessageStore {
+ dirInfo *models.DirectoryInfo) *MessageStore {
return &MessageStore{
Deleted: make(map[uint32]interface{}),
@@ -106,11 +107,11 @@ func (store *MessageStore) FetchBodyPart(
if !ok {
return
}
- cb(msg.Reader)
+ cb(msg.Part.Reader)
})
}
-func merge(to *types.MessageInfo, from *types.MessageInfo) {
+func merge(to *models.MessageInfo, from *models.MessageInfo) {
if from.BodyStructure != nil {
to.BodyStructure = from.BodyStructure
}
@@ -131,11 +132,11 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
update := false
switch msg := msg.(type) {
case *types.DirectoryInfo:
- store.DirInfo = *msg
+ store.DirInfo = *msg.Info
store.worker.PostAction(&types.FetchDirectoryContents{}, nil)
update = true
case *types.DirectoryContents:
- newMap := make(map[uint32]*types.MessageInfo)
+ newMap := make(map[uint32]*models.MessageInfo)
for _, uid := range msg.Uids {
if msg, ok := store.Messages[uid]; ok {
newMap[uid] = msg
@@ -147,14 +148,14 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
store.Uids = msg.Uids
update = true
case *types.MessageInfo:
- if existing, ok := store.Messages[msg.Uid]; ok && existing != nil {
- merge(existing, msg)
+ if existing, ok := store.Messages[msg.Info.Uid]; ok && existing != nil {
+ merge(existing, msg.Info)
} else {
- store.Messages[msg.Uid] = msg
+ store.Messages[msg.Info.Uid] = msg.Info
}
- if _, ok := store.pendingHeaders[msg.Uid]; msg.Envelope != nil && ok {
- delete(store.pendingHeaders, msg.Uid)
- if cbs, ok := store.headerCallbacks[msg.Uid]; ok {
+ if _, ok := store.pendingHeaders[msg.Info.Uid]; msg.Info.Envelope != nil && ok {
+ delete(store.pendingHeaders, msg.Info.Uid)
+ if cbs, ok := store.headerCallbacks[msg.Info.Uid]; ok {
for _, cb := range cbs {
cb(msg)
}
@@ -162,11 +163,11 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
}
update = true
case *types.FullMessage:
- if _, ok := store.pendingBodies[msg.Uid]; ok {
- delete(store.pendingBodies, msg.Uid)
- if cbs, ok := store.bodyCallbacks[msg.Uid]; ok {
+ if _, ok := store.pendingBodies[msg.Content.Uid]; ok {
+ delete(store.pendingBodies, msg.Content.Uid)
+ if cbs, ok := store.bodyCallbacks[msg.Content.Uid]; ok {
for _, cb := range cbs {
- cb(msg.Reader)
+ cb(msg.Content.Reader)
}
}
}
@@ -283,7 +284,7 @@ func (store *MessageStore) Read(uids []uint32, read bool,
}, cb)
}
-func (store *MessageStore) Selected() *types.MessageInfo {
+func (store *MessageStore) Selected() *models.MessageInfo {
return store.Messages[store.Uids[len(store.Uids)-store.selected-1]]
}
diff --git a/models/models.go b/models/models.go
new file mode 100644
index 0000000..cff05b1
--- /dev/null
+++ b/models/models.go
@@ -0,0 +1,52 @@
+package models
+
+import (
+ "io"
+ "time"
+
+ "github.com/emersion/go-imap"
+ "github.com/emersion/go-message/mail"
+)
+
+type Directory struct {
+ Name string
+ Attributes []string
+}
+
+type DirectoryInfo struct {
+ Name string
+ Flags []string
+ ReadOnly bool
+
+ // The total number of messages in this mailbox.
+ Exists int
+
+ // The number of messages not seen since the last time the mailbox was opened.
+ Recent int
+
+ // The number of unread messages
+ Unseen int
+}
+
+// A MessageInfo holds information about the structure of a message
+type MessageInfo struct {
+ BodyStructure *imap.BodyStructure
+ Envelope *imap.Envelope
+ Flags []string
+ InternalDate time.Time
+ RFC822Headers *mail.Header
+ Size uint32
+ Uid uint32
+}
+
+// A MessageBodyPart can be displayed in the message viewer
+type MessageBodyPart struct {
+ Reader io.Reader
+ Uid uint32
+}
+
+// A FullMessage is the entire message
+type FullMessage struct {
+ Reader io.Reader
+ Uid uint32
+}
diff --git a/widgets/account.go b/widgets/account.go
index 0948c5c..e08a253 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -9,6 +9,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -169,7 +170,7 @@ func (acct *AccountView) SelectedAccount() *AccountView {
return acct
}
-func (acct *AccountView) SelectedMessage() *types.MessageInfo {
+func (acct *AccountView) SelectedMessage() *models.MessageInfo {
return acct.msglist.Selected()
}
@@ -195,11 +196,11 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
acct.dirlist.UpdateList(nil)
}
case *types.DirectoryInfo:
- if store, ok := acct.msgStores[msg.Name]; ok {
+ if store, ok := acct.msgStores[msg.Info.Name]; ok {
store.Update(msg)
} else {
- store = lib.NewMessageStore(acct.worker, msg)
- acct.msgStores[msg.Name] = store
+ store = lib.NewMessageStore(acct.worker, msg.Info)
+ acct.msgStores[msg.Info.Name] = store
store.OnUpdate(func(_ *lib.MessageStore) {
store.OnUpdate(nil)
acct.msglist.SetStore(store)
diff --git a/widgets/dirlist.go b/widgets/dirlist.go
index 4dc8fd2..c5e4a0c 100644
--- a/widgets/dirlist.go
+++ b/widgets/dirlist.go
@@ -55,7 +55,7 @@ func (dirlist *DirectoryList) UpdateList(done func(dirs []string)) {
switch msg := msg.(type) {
case *types.Directory:
- dirs = append(dirs, msg.Name)
+ dirs = append(dirs, msg.Dir.Name)
case *types.Done:
sort.Strings(dirs)
dirlist.store.Update(dirs)
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 211cbce..7051478 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -11,7 +11,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
type MessageList struct {
@@ -176,7 +176,7 @@ func (ml *MessageList) Empty() bool {
return store == nil || len(store.Uids) == 0
}
-func (ml *MessageList) Selected() *types.MessageInfo {
+func (ml *MessageList) Selected() *models.MessageInfo {
store := ml.Store()
return store.Messages[store.Uids[len(store.Uids)-ml.store.SelectedIndex()-1]]
}
diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go
index b0ae79e..6a645f9 100644
--- a/widgets/msgviewer.go
+++ b/widgets/msgviewer.go
@@ -20,7 +20,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
var ansi = regexp.MustCompile("^\x1B\\[[0-?]*[ -/]*[@-~]")
@@ -31,7 +31,7 @@ type MessageViewer struct {
conf *config.AercConfig
err error
grid *ui.Grid
- msg *types.MessageInfo
+ msg *models.MessageInfo
switcher *PartSwitcher
store *lib.MessageStore
}
@@ -44,7 +44,7 @@ type PartSwitcher struct {
}
func NewMessageViewer(acct *AccountView, conf *config.AercConfig,
- store *lib.MessageStore, msg *types.MessageInfo) *MessageViewer {
+ store *lib.MessageStore, msg *models.MessageInfo) *MessageViewer {
grid := ui.NewGrid().Rows([]ui.GridSpec{
{ui.SIZE_EXACT, 4}, // TODO: Based on number of header rows
@@ -112,7 +112,7 @@ handle_error:
}
func enumerateParts(conf *config.AercConfig, store *lib.MessageStore,
- msg *types.MessageInfo, body *imap.BodyStructure,
+ msg *models.MessageInfo, body *imap.BodyStructure,
showHeaders bool, index []int) ([]*PartViewer, error) {
var parts []*PartViewer
@@ -140,7 +140,7 @@ func enumerateParts(conf *config.AercConfig, store *lib.MessageStore,
}
func createSwitcher(switcher *PartSwitcher, conf *config.AercConfig,
- store *lib.MessageStore, msg *types.MessageInfo, showHeaders bool) error {
+ store *lib.MessageStore, msg *models.MessageInfo, showHeaders bool) error {
var err error
switcher.showHeaders = showHeaders
@@ -212,7 +212,7 @@ func (mv *MessageViewer) SelectedAccount() *AccountView {
return mv.acct
}
-func (mv *MessageViewer) SelectedMessage() *types.MessageInfo {
+func (mv *MessageViewer) SelectedMessage() *models.MessageInfo {
return mv.msg
}
@@ -321,7 +321,7 @@ type PartViewer struct {
fetched bool
filter *exec.Cmd
index []int
- msg *types.MessageInfo
+ msg *models.MessageInfo
pager *exec.Cmd
pagerin io.WriteCloser
part *imap.BodyStructure
@@ -333,7 +333,7 @@ type PartViewer struct {
}
func NewPartViewer(conf *config.AercConfig,
- store *lib.MessageStore, msg *types.MessageInfo,
+ store *lib.MessageStore, msg *models.MessageInfo,
part *imap.BodyStructure, showHeaders bool,
index []int) (*PartViewer, error) {
diff --git a/widgets/providesmessage.go b/widgets/providesmessage.go
index 4b71637..d8b1e77 100644
--- a/widgets/providesmessage.go
+++ b/widgets/providesmessage.go
@@ -5,7 +5,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
type PartInfo struct {
@@ -19,6 +19,6 @@ type ProvidesMessage interface {
ui.Drawable
Store() *lib.MessageStore
SelectedAccount() *AccountView
- SelectedMessage() *types.MessageInfo
+ SelectedMessage() *models.MessageInfo
SelectedMessagePart() *PartInfo
}
diff --git a/worker/imap/fetch.go b/worker/imap/fetch.go
index 7d1bfcf..d5bb9aa 100644
--- a/worker/imap/fetch.go
+++ b/worker/imap/fetch.go
@@ -8,6 +8,7 @@ import (
"github.com/emersion/go-message/mail"
"github.com/emersion/go-message/textproto"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -82,39 +83,49 @@ func (imapw *IMAPWorker) handleFetchMessages(
header = &mail.Header{message.Header{textprotoHeader}}
}
imapw.worker.PostMessage(&types.MessageInfo{
- Message: types.RespondTo(msg),
- BodyStructure: _msg.BodyStructure,
- Envelope: _msg.Envelope,
- Flags: _msg.Flags,
- InternalDate: _msg.InternalDate,
- RFC822Headers: header,
- Uid: _msg.Uid,
+ Message: types.RespondTo(msg),
+ Info: &models.MessageInfo{
+ BodyStructure: _msg.BodyStructure,
+ Envelope: _msg.Envelope,
+ Flags: _msg.Flags,
+ InternalDate: _msg.InternalDate,
+ RFC822Headers: header,
+ Uid: _msg.Uid,
+ },
}, nil)
case *types.FetchFullMessages:
reader := _msg.GetBody(section)
imapw.worker.PostMessage(&types.FullMessage{
Message: types.RespondTo(msg),
- Reader: reader,
- Uid: _msg.Uid,
+ Content: &models.FullMessage{
+ Reader: reader,
+ Uid: _msg.Uid,
+ },
}, nil)
// Update flags (to mark message as read)
imapw.worker.PostMessage(&types.MessageInfo{
Message: types.RespondTo(msg),
- Flags: _msg.Flags,
- Uid: _msg.Uid,
+ Info: &models.MessageInfo{
+ Flags: _msg.Flags,
+ Uid: _msg.Uid,
+ },
}, nil)
case *types.FetchMessageBodyPart:
reader := _msg.GetBody(section)
imapw.worker.PostMessage(&types.MessageBodyPart{
Message: types.RespondTo(msg),
- Reader: reader,
- Uid: _msg.Uid,
+ Part: &models.MessageBodyPart{
+ Reader: reader,
+ Uid: _msg.Uid,
+ },
}, nil)
// Update flags (to mark message as read)
imapw.worker.PostMessage(&types.MessageInfo{
Message: types.RespondTo(msg),
- Flags: _msg.Flags,
- Uid: _msg.Uid,
+ Info: &models.MessageInfo{
+ Flags: _msg.Flags,
+ Uid: _msg.Uid,
+ },
}, nil)
}
}
diff --git a/worker/imap/list.go b/worker/imap/list.go
index 708e70f..42be50e 100644
--- a/worker/imap/list.go
+++ b/worker/imap/list.go
@@ -3,6 +3,7 @@ package imap
import (
"github.com/emersion/go-imap"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -18,9 +19,11 @@ func (imapw *IMAPWorker) handleListDirectories(msg *types.ListDirectories) {
continue
}
imapw.worker.PostMessage(&types.Directory{
- Message: types.RespondTo(msg),
- Name: mbox.Name,
- Attributes: mbox.Attributes,
+ Message: types.RespondTo(msg),
+ Dir: &models.Directory{
+ Name: mbox.Name,
+ Attributes: mbox.Attributes,
+ },
}, nil)
}
done <- nil
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index 5005620..9ddaa47 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -10,6 +10,7 @@ import (
idle "github.com/emersion/go-imap-idle"
"github.com/emersion/go-imap/client"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -169,13 +170,15 @@ func (w *IMAPWorker) handleImapUpdate(update client.Update) {
w.selected = *status
}
w.worker.PostMessage(&types.DirectoryInfo{
- Flags: status.Flags,
- Name: status.Name,
- ReadOnly: status.ReadOnly,
-
- Exists: int(status.Messages),
- Recent: int(status.Recent),
- Unseen: int(status.Unseen),
+ Info: &models.DirectoryInfo{
+ Flags: status.Flags,
+ Name: status.Name,
+ ReadOnly: status.ReadOnly,
+
+ Exists: int(status.Messages),
+ Recent: int(status.Recent),
+ Unseen: int(status.Unseen),
+ },
}, nil)
case *client.MessageUpdate:
msg := update.Message
@@ -183,11 +186,13 @@ func (w *IMAPWorker) handleImapUpdate(update client.Update) {
msg.Uid = w.seqMap[msg.SeqNum-1]
}
w.worker.PostMessage(&types.MessageInfo{
- BodyStructure: msg.BodyStructure,
- Envelope: msg.Envelope,
- Flags: msg.Flags,
- InternalDate: msg.InternalDate,
- Uid: msg.Uid,
+ Info: &models.MessageInfo{
+ BodyStructure: msg.BodyStructure,
+ Envelope: msg.Envelope,
+ Flags: msg.Flags,
+ InternalDate: msg.InternalDate,
+ Uid: msg.Uid,
+ },
}, nil)
case *client.ExpungeUpdate:
i := update.SeqNum - 1
diff --git a/worker/types/messages.go b/worker/types/messages.go
index d9e911f..bb2505a 100644
--- a/worker/types/messages.go
+++ b/worker/types/messages.go
@@ -5,9 +5,9 @@ import (
"time"
"github.com/emersion/go-imap"
- "github.com/emersion/go-message/mail"
"git.sr.ht/~sircmpwn/aerc/config"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
type WorkerMessage interface {
@@ -139,17 +139,12 @@ type AppendMessage struct {
type Directory struct {
Message
- Attributes []string
- Name string
+ Dir *models.Directory
}
type DirectoryInfo struct {
Message
- Flags []string
- Name string
- ReadOnly bool
-
- Exists, Recent, Unseen int
+ Info *models.DirectoryInfo
}
type DirectoryContents struct {
@@ -164,25 +159,17 @@ type SearchResults struct {
type MessageInfo struct {
Message
- BodyStructure *imap.BodyStructure
- Envelope *imap.Envelope
- Flags []string
- InternalDate time.Time
- RFC822Headers *mail.Header
- Size uint32
- Uid uint32
+ Info *models.MessageInfo
}
type FullMessage struct {
Message
- Reader io.Reader
- Uid uint32
+ Content *models.FullMessage
}
type MessageBodyPart struct {
Message
- Reader io.Reader
- Uid uint32
+ Part *models.MessageBodyPart
}
type MessagesDeleted struct {