Make message viewer real, part two
This commit is contained in:
parent
95875b13f8
commit
0abafa60e1
4 changed files with 38 additions and 23 deletions
|
@ -157,7 +157,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update = true
|
update = true
|
||||||
case *types.MessageBody:
|
case *types.FullMessage:
|
||||||
if _, ok := store.pendingBodies[msg.Uid]; ok {
|
if _, ok := store.pendingBodies[msg.Uid]; ok {
|
||||||
delete(store.pendingBodies, msg.Uid)
|
delete(store.pendingBodies, msg.Uid)
|
||||||
if cbs, ok := store.bodyCallbacks[msg.Uid]; ok {
|
if cbs, ok := store.bodyCallbacks[msg.Uid]; ok {
|
||||||
|
|
|
@ -173,7 +173,7 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
|
||||||
case *types.DirectoryContents:
|
case *types.DirectoryContents:
|
||||||
store := acct.msgStores[acct.dirlist.selected]
|
store := acct.msgStores[acct.dirlist.selected]
|
||||||
store.Update(msg)
|
store.Update(msg)
|
||||||
case *types.MessageBody:
|
case *types.FullMessage:
|
||||||
store := acct.msgStores[acct.dirlist.selected]
|
store := acct.msgStores[acct.dirlist.selected]
|
||||||
store.Update(msg)
|
store.Update(msg)
|
||||||
case *types.MessageInfo:
|
case *types.MessageInfo:
|
||||||
|
|
|
@ -16,10 +16,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageViewer struct {
|
type MessageViewer struct {
|
||||||
mail io.Reader
|
cmd *exec.Cmd
|
||||||
pipe io.Writer
|
source io.Reader
|
||||||
grid *ui.Grid
|
sink io.WriteCloser
|
||||||
term *Terminal
|
grid *ui.Grid
|
||||||
|
term *Terminal
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatAddresses(addrs []*imap.Address) string {
|
func formatAddresses(addrs []*imap.Address) string {
|
||||||
|
@ -92,22 +93,33 @@ func NewMessageViewer(store *lib.MessageStore,
|
||||||
grid.AddChild(body).At(1, 0)
|
grid.AddChild(body).At(1, 0)
|
||||||
|
|
||||||
viewer := &MessageViewer{
|
viewer := &MessageViewer{
|
||||||
pipe: pipe,
|
cmd: cmd,
|
||||||
|
sink: pipe,
|
||||||
grid: grid,
|
grid: grid,
|
||||||
term: term,
|
term: term,
|
||||||
}
|
}
|
||||||
|
|
||||||
store.FetchBodyPart(msg.Uid, 0, func(reader io.Reader) {
|
store.FetchBodyPart(msg.Uid, 0, func(reader io.Reader) {
|
||||||
viewer.mail = reader
|
viewer.source = reader
|
||||||
go func() {
|
viewer.attemptCopy()
|
||||||
io.Copy(pipe, reader)
|
|
||||||
pipe.Close()
|
|
||||||
}()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
term.OnStart = func() {
|
||||||
|
viewer.attemptCopy()
|
||||||
|
}
|
||||||
|
|
||||||
return viewer
|
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) {
|
func (mv *MessageViewer) Draw(ctx *ui.Context) {
|
||||||
mv.grid.Draw(ctx)
|
mv.grid.Draw(ctx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ func (imapw *IMAPWorker) handleFetchMessageHeaders(
|
||||||
imap.FetchUid,
|
imap.FetchUid,
|
||||||
}
|
}
|
||||||
|
|
||||||
imapw.handleFetchMessages(msg, &msg.Uids, items)
|
imapw.handleFetchMessages(msg, &msg.Uids, items, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (imapw *IMAPWorker) handleFetchMessageBodyPart(
|
func (imapw *IMAPWorker) handleFetchMessageBodyPart(
|
||||||
|
@ -26,11 +26,11 @@ func (imapw *IMAPWorker) handleFetchMessageBodyPart(
|
||||||
|
|
||||||
imapw.worker.Logger.Printf("Fetching message part")
|
imapw.worker.Logger.Printf("Fetching message part")
|
||||||
section := &imap.BodySectionName{}
|
section := &imap.BodySectionName{}
|
||||||
section.Path = []int{msg.Part}
|
section.Path = []int{msg.Part + 1}
|
||||||
items := []imap.FetchItem{section.FetchItem()}
|
items := []imap.FetchItem{section.FetchItem()}
|
||||||
uids := imap.SeqSet{}
|
uids := imap.SeqSet{}
|
||||||
uids.AddNum(msg.Uid)
|
uids.AddNum(msg.Uid)
|
||||||
imapw.handleFetchMessages(msg, &uids, items)
|
imapw.handleFetchMessages(msg, &uids, items, section)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (imapw *IMAPWorker) handleFetchFullMessages(
|
func (imapw *IMAPWorker) handleFetchFullMessages(
|
||||||
|
@ -39,11 +39,12 @@ func (imapw *IMAPWorker) handleFetchFullMessages(
|
||||||
imapw.worker.Logger.Printf("Fetching full messages")
|
imapw.worker.Logger.Printf("Fetching full messages")
|
||||||
section := &imap.BodySectionName{}
|
section := &imap.BodySectionName{}
|
||||||
items := []imap.FetchItem{section.FetchItem()}
|
items := []imap.FetchItem{section.FetchItem()}
|
||||||
imapw.handleFetchMessages(msg, &msg.Uids, items)
|
imapw.handleFetchMessages(msg, &msg.Uids, items, section)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (imapw *IMAPWorker) handleFetchMessages(
|
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() {
|
go func() {
|
||||||
messages := make(chan *imap.Message)
|
messages := make(chan *imap.Message)
|
||||||
|
@ -52,12 +53,12 @@ func (imapw *IMAPWorker) handleFetchMessages(
|
||||||
done <- imapw.client.UidFetch(uids, items, messages)
|
done <- imapw.client.UidFetch(uids, items, messages)
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
section := &imap.BodySectionName{}
|
|
||||||
for _msg := range messages {
|
for _msg := range messages {
|
||||||
imapw.seqMap[_msg.SeqNum-1] = _msg.Uid
|
imapw.seqMap[_msg.SeqNum-1] = _msg.Uid
|
||||||
switch msg.(type) {
|
switch msg.(type) {
|
||||||
case *types.FetchMessageHeaders:
|
case *types.FetchMessageHeaders:
|
||||||
imapw.worker.PostMessage(&types.MessageInfo{
|
imapw.worker.PostMessage(&types.MessageInfo{
|
||||||
|
Message: types.RespondTo(msg),
|
||||||
BodyStructure: _msg.BodyStructure,
|
BodyStructure: _msg.BodyStructure,
|
||||||
Envelope: _msg.Envelope,
|
Envelope: _msg.Envelope,
|
||||||
Flags: _msg.Flags,
|
Flags: _msg.Flags,
|
||||||
|
@ -66,15 +67,17 @@ func (imapw *IMAPWorker) handleFetchMessages(
|
||||||
}, nil)
|
}, nil)
|
||||||
case *types.FetchFullMessages:
|
case *types.FetchFullMessages:
|
||||||
reader := _msg.GetBody(section)
|
reader := _msg.GetBody(section)
|
||||||
imapw.worker.PostMessage(&types.MessageBody{
|
imapw.worker.PostMessage(&types.FullMessage{
|
||||||
Reader: reader,
|
Message: types.RespondTo(msg),
|
||||||
Uid: _msg.Uid,
|
Reader: reader,
|
||||||
|
Uid: _msg.Uid,
|
||||||
}, nil)
|
}, nil)
|
||||||
case *types.FetchMessageBodyPart:
|
case *types.FetchMessageBodyPart:
|
||||||
reader := _msg.GetBody(section)
|
reader := _msg.GetBody(section)
|
||||||
imapw.worker.PostMessage(&types.MessageBodyPart{
|
imapw.worker.PostMessage(&types.MessageBodyPart{
|
||||||
Reader: reader,
|
Message: types.RespondTo(msg),
|
||||||
Uid: _msg.Uid,
|
Reader: reader,
|
||||||
|
Uid: _msg.Uid,
|
||||||
}, nil)
|
}, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue