summary refs log tree commit diff stats
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 {