From 0abafa60e159f87595148c0d0fc4f5f46be2d400 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 31 Mar 2019 12:35:51 -0400 Subject: [PATCH] Make message viewer real, part two --- lib/msgstore.go | 2 +- widgets/account.go | 2 +- widgets/msgviewer.go | 32 ++++++++++++++++++++++---------- worker/imap/fetch.go | 25 ++++++++++++++----------- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/lib/msgstore.go b/lib/msgstore.go index 2e59be7..9d537fc 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -157,7 +157,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { } } update = true - case *types.MessageBody: + case *types.FullMessage: if _, ok := store.pendingBodies[msg.Uid]; ok { delete(store.pendingBodies, msg.Uid) if cbs, ok := store.bodyCallbacks[msg.Uid]; ok { diff --git a/widgets/account.go b/widgets/account.go index f26d838..f8abdc9 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -173,7 +173,7 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) { case *types.DirectoryContents: store := acct.msgStores[acct.dirlist.selected] store.Update(msg) - case *types.MessageBody: + case *types.FullMessage: store := acct.msgStores[acct.dirlist.selected] store.Update(msg) case *types.MessageInfo: diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go index 2c77aeb..c7ac44c 100644 --- a/widgets/msgviewer.go +++ b/widgets/msgviewer.go @@ -16,10 +16,11 @@ import ( ) type MessageViewer struct { - mail io.Reader - pipe io.Writer - grid *ui.Grid - term *Terminal + cmd *exec.Cmd + source io.Reader + sink io.WriteCloser + grid *ui.Grid + term *Terminal } func formatAddresses(addrs []*imap.Address) string { @@ -92,22 +93,33 @@ func NewMessageViewer(store *lib.MessageStore, grid.AddChild(body).At(1, 0) viewer := &MessageViewer{ - pipe: pipe, + cmd: cmd, + sink: pipe, grid: grid, term: term, } store.FetchBodyPart(msg.Uid, 0, func(reader io.Reader) { - viewer.mail = reader - go func() { - io.Copy(pipe, reader) - pipe.Close() - }() + viewer.source = reader + viewer.attemptCopy() }) + term.OnStart = func() { + viewer.attemptCopy() + } + return viewer } +func (mv *MessageViewer) attemptCopy() { + if mv.source != nil && mv.cmd.Process != nil { + go func() { + io.Copy(mv.sink, mv.source) + mv.sink.Close() + }() + } +} + func (mv *MessageViewer) Draw(ctx *ui.Context) { mv.grid.Draw(ctx) } diff --git a/worker/imap/fetch.go b/worker/imap/fetch.go index 89c0d99..af9d3b1 100644 --- a/worker/imap/fetch.go +++ b/worker/imap/fetch.go @@ -18,7 +18,7 @@ func (imapw *IMAPWorker) handleFetchMessageHeaders( imap.FetchUid, } - imapw.handleFetchMessages(msg, &msg.Uids, items) + imapw.handleFetchMessages(msg, &msg.Uids, items, nil) } func (imapw *IMAPWorker) handleFetchMessageBodyPart( @@ -26,11 +26,11 @@ func (imapw *IMAPWorker) handleFetchMessageBodyPart( imapw.worker.Logger.Printf("Fetching message part") section := &imap.BodySectionName{} - section.Path = []int{msg.Part} + section.Path = []int{msg.Part + 1} items := []imap.FetchItem{section.FetchItem()} uids := imap.SeqSet{} uids.AddNum(msg.Uid) - imapw.handleFetchMessages(msg, &uids, items) + imapw.handleFetchMessages(msg, &uids, items, section) } func (imapw *IMAPWorker) handleFetchFullMessages( @@ -39,11 +39,12 @@ func (imapw *IMAPWorker) handleFetchFullMessages( imapw.worker.Logger.Printf("Fetching full messages") section := &imap.BodySectionName{} items := []imap.FetchItem{section.FetchItem()} - imapw.handleFetchMessages(msg, &msg.Uids, items) + imapw.handleFetchMessages(msg, &msg.Uids, items, section) } func (imapw *IMAPWorker) handleFetchMessages( - msg types.WorkerMessage, uids *imap.SeqSet, items []imap.FetchItem) { + msg types.WorkerMessage, uids *imap.SeqSet, items []imap.FetchItem, + section *imap.BodySectionName) { go func() { messages := make(chan *imap.Message) @@ -52,12 +53,12 @@ func (imapw *IMAPWorker) handleFetchMessages( done <- imapw.client.UidFetch(uids, items, messages) }() go func() { - section := &imap.BodySectionName{} for _msg := range messages { imapw.seqMap[_msg.SeqNum-1] = _msg.Uid switch msg.(type) { case *types.FetchMessageHeaders: imapw.worker.PostMessage(&types.MessageInfo{ + Message: types.RespondTo(msg), BodyStructure: _msg.BodyStructure, Envelope: _msg.Envelope, Flags: _msg.Flags, @@ -66,15 +67,17 @@ func (imapw *IMAPWorker) handleFetchMessages( }, nil) case *types.FetchFullMessages: reader := _msg.GetBody(section) - imapw.worker.PostMessage(&types.MessageBody{ - Reader: reader, - Uid: _msg.Uid, + imapw.worker.PostMessage(&types.FullMessage{ + Message: types.RespondTo(msg), + Reader: reader, + Uid: _msg.Uid, }, nil) case *types.FetchMessageBodyPart: reader := _msg.GetBody(section) imapw.worker.PostMessage(&types.MessageBodyPart{ - Reader: reader, - Uid: _msg.Uid, + Message: types.RespondTo(msg), + Reader: reader, + Uid: _msg.Uid, }, nil) } }