From b83e7c9fa6a0d187a0f20d98d522cff792053cdd Mon Sep 17 00:00:00 2001 From: Yash Srivastav Date: Fri, 7 Jun 2019 13:56:14 +0530 Subject: implements ability to view headers in message view --- widgets/msgviewer.go | 144 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 91 insertions(+), 53 deletions(-) (limited to 'widgets') diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go index 45a5ed0..b82fa8d 100644 --- a/widgets/msgviewer.go +++ b/widgets/msgviewer.go @@ -35,8 +35,9 @@ type MessageViewer struct { type PartSwitcher struct { ui.Invalidatable - parts []*PartViewer - selected int + parts []*PartViewer + selected int + showHeaders bool } func formatAddresses(addrs []*imap.Address) string { @@ -98,33 +99,10 @@ func NewMessageViewer(acct *AccountView, conf *config.AercConfig, }).At(2, 0).Span(1, 2) headers.AddChild(ui.NewFill(' ')).At(3, 0).Span(1, 2) - var err error switcher := &PartSwitcher{} - if len(msg.BodyStructure.Parts) == 0 { - pv, err := NewPartViewer(conf, store, msg, msg.BodyStructure, []int{1}) - if err != nil { - goto handle_error - } - switcher.parts = []*PartViewer{pv} - pv.OnInvalidate(func(_ ui.Drawable) { - switcher.Invalidate() - }) - } else { - switcher.parts, err = enumerateParts(conf, store, - msg, msg.BodyStructure, []int{}) - if err != nil { - goto handle_error - } - switcher.selected = -1 - for i, pv := range switcher.parts { - pv.OnInvalidate(func(_ ui.Drawable) { - switcher.Invalidate() - }) - // TODO: switch to user's preferred mimetype, if configured - if switcher.selected == -1 && pv.part.MIMEType != "multipart" { - switcher.selected = i - } - } + err := createSwitcher(switcher, conf, store, msg, conf.Viewer.ShowHeaders) + if err != nil { + goto handle_error } grid.AddChild(headers).At(0, 0) @@ -132,6 +110,7 @@ func NewMessageViewer(acct *AccountView, conf *config.AercConfig, return &MessageViewer{ acct: acct, + conf: conf, grid: grid, msg: msg, store: store, @@ -148,7 +127,7 @@ handle_error: func enumerateParts(conf *config.AercConfig, store *lib.MessageStore, msg *types.MessageInfo, body *imap.BodyStructure, - index []int) ([]*PartViewer, error) { + showHeaders bool, index []int) ([]*PartViewer, error) { var parts []*PartViewer for i, part := range body.Parts { @@ -158,14 +137,14 @@ func enumerateParts(conf *config.AercConfig, store *lib.MessageStore, pv := &PartViewer{part: part} parts = append(parts, pv) subParts, err := enumerateParts( - conf, store, msg, part, curindex) + conf, store, msg, part, showHeaders, curindex) if err != nil { return nil, err } parts = append(parts, subParts...) continue } - pv, err := NewPartViewer(conf, store, msg, part, curindex) + pv, err := NewPartViewer(conf, store, msg, part, showHeaders, curindex) if err != nil { return nil, err } @@ -174,6 +153,44 @@ func enumerateParts(conf *config.AercConfig, store *lib.MessageStore, return parts, nil } +func createSwitcher(switcher *PartSwitcher, conf *config.AercConfig, + store *lib.MessageStore, msg *types.MessageInfo, showHeaders bool) error { + var err error + switcher.showHeaders = showHeaders + + if showHeaders { + } + + if len(msg.BodyStructure.Parts) == 0 { + pv, err := NewPartViewer(conf, store, msg, msg.BodyStructure, + showHeaders, []int{1}) + if err != nil { + return err + } + switcher.parts = []*PartViewer{pv} + pv.OnInvalidate(func(_ ui.Drawable) { + switcher.Invalidate() + }) + } else { + switcher.parts, err = enumerateParts(conf, store, + msg, msg.BodyStructure, showHeaders, []int{}) + if err != nil { + return err + } + switcher.selected = -1 + for i, pv := range switcher.parts { + pv.OnInvalidate(func(_ ui.Drawable) { + switcher.Invalidate() + }) + // TODO: switch to user's preferred mimetype, if configured + if switcher.selected == -1 && pv.part.MIMEType != "multipart" { + switcher.selected = i + } + } + } + return nil +} + func (mv *MessageViewer) Draw(ctx *ui.Context) { if mv.err != nil { ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault) @@ -205,6 +222,15 @@ func (mv *MessageViewer) SelectedMessage() *types.MessageInfo { return mv.msg } +func (mv *MessageViewer) ToggleHeaders() { + switcher := mv.switcher + err := createSwitcher(switcher, mv.conf, mv.store, mv.msg, !switcher.showHeaders) + if err != nil { + mv.acct.Logger().Printf("warning: error during create switcher - %v", err) + } + switcher.Invalidate() +} + func (mv *MessageViewer) CurrentPart() *PartInfo { switcher := mv.switcher part := switcher.parts[switcher.selected] @@ -295,18 +321,19 @@ func (mv *MessageViewer) Focus(focus bool) { type PartViewer struct { ui.Invalidatable - err error - fetched bool - filter *exec.Cmd - index []int - msg *types.MessageInfo - pager *exec.Cmd - pagerin io.WriteCloser - part *imap.BodyStructure - sink io.WriteCloser - source io.Reader - store *lib.MessageStore - term *Terminal + err error + fetched bool + filter *exec.Cmd + index []int + msg *types.MessageInfo + pager *exec.Cmd + pagerin io.WriteCloser + part *imap.BodyStructure + showHeaders bool + sink io.WriteCloser + source io.Reader + store *lib.MessageStore + term *Terminal } type PartInfo struct { @@ -318,7 +345,8 @@ type PartInfo struct { func NewPartViewer(conf *config.AercConfig, store *lib.MessageStore, msg *types.MessageInfo, - part *imap.BodyStructure, index []int) (*PartViewer, error) { + part *imap.BodyStructure, showHeaders bool, + index []int) (*PartViewer, error) { var ( filter *exec.Cmd @@ -375,15 +403,16 @@ func NewPartViewer(conf *config.AercConfig, } pv := &PartViewer{ - filter: filter, - index: index, - msg: msg, - pager: pager, - pagerin: pagerin, - part: part, - sink: pipe, - store: store, - term: term, + filter: filter, + index: index, + msg: msg, + pager: pager, + pagerin: pagerin, + part: part, + showHeaders: showHeaders, + sink: pipe, + store: store, + term: term, } if term != nil { @@ -439,6 +468,15 @@ func (pv *PartViewer) attemptCopy() { }() } go func() { + if pv.showHeaders && pv.msg.RFC822Headers != nil { + fields := pv.msg.RFC822Headers.Fields() + for fields.Next() { + field := fmt.Sprintf("%s: %s\n", fields.Key(), fields.Value()) + pv.sink.Write([]byte(field)) + } + pv.sink.Write([]byte{'\n'}) + } + entity, err := message.New(header, pv.source) if err != nil { pv.err = err -- cgit v1.2.3