Make message viewer real, part two

This commit is contained in:
Drew DeVault 2019-03-31 12:35:51 -04:00
parent 95875b13f8
commit 0abafa60e1
4 changed files with 38 additions and 23 deletions

View file

@ -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 {

View file

@ -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:

View file

@ -16,8 +16,9 @@ import (
)
type MessageViewer struct {
mail io.Reader
pipe io.Writer
cmd *exec.Cmd
source io.Reader
sink io.WriteCloser
grid *ui.Grid
term *Terminal
}
@ -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)
}

View file

@ -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,13 +67,15 @@ func (imapw *IMAPWorker) handleFetchMessages(
}, nil)
case *types.FetchFullMessages:
reader := _msg.GetBody(section)
imapw.worker.PostMessage(&types.MessageBody{
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{
Message: types.RespondTo(msg),
Reader: reader,
Uid: _msg.Uid,
}, nil)