aboutsummaryrefslogtreecommitdiff
path: root/widgets
diff options
context:
space:
mode:
authorYash Srivastav <yash111998@gmail.com>2019-06-07 13:56:14 +0530
committerDrew DeVault <sir@cmpwn.com>2019-06-07 09:20:24 -0400
commitb83e7c9fa6a0d187a0f20d98d522cff792053cdd (patch)
tree4c3765b41d216e26406d21d3b045f340edabbadc /widgets
parent2279ac3ab3d19cd233600907bc8e3e8b4e57b350 (diff)
implements ability to view headers in message view
Diffstat (limited to 'widgets')
-rw-r--r--widgets/msgviewer.go144
1 files changed, 91 insertions, 53 deletions
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