From 2a0da301c51a8862c4e8a73b141adc0f416833a5 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Fri, 3 Feb 2023 13:23:08 -0600 Subject: tabs: use template for compose tabs Use a template for compose tabs. Other available values: Account string Subject string To []*mail.Address From []*mail.Address Cc []*mail.Address Bcc []*mail.Address OriginalFrom []*mail.Address When you use To, From, CC, BCC, or OriginalFrom the title will only be updated when an editing field has lost focus. This is so we don't end up calling "PrepareHeader" on every keystroke, which will likely error out anyways since it will be an invalid header. Subject still updates every keystroke. Signed-off-by: Tim Culverhouse Acked-by: Robin Jarry --- widgets/aerc.go | 10 +--------- widgets/compose.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 9 deletions(-) (limited to 'widgets') diff --git a/widgets/aerc.go b/widgets/aerc.go index e8d65539..8eec8823 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -748,15 +748,7 @@ func (aerc *Aerc) Mailto(addr *url.URL) error { if to == nil { composer.FocusEditor("to") } - tab := aerc.NewTab(composer, title) - composer.OnHeaderChange("Subject", func(subject string) { - if subject == "" { - tab.Name = "New email" - } else { - tab.Name = subject - } - ui.Invalidate() - }) + composer.Tab = aerc.NewTab(composer, title) for _, file := range attachments { composer.AddAttachment(file) diff --git a/widgets/compose.go b/widgets/compose.go index 5795ccba..94fd79d5 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -63,6 +63,7 @@ type Composer struct { width int textParts []*lib.Part + Tab *ui.Tab } func NewComposer( @@ -235,6 +236,15 @@ func (c *Composer) buildComposeHeader(aerc *Aerc, cmpl *completer.Completer) { default: c.focusable = append(c.focusable, e) } + e.OnChange(func() { + c.setTitle() + ui.Invalidate() + }) + e.OnFocusLost(func() { + c.PrepareHeader() //nolint:errcheck // tab title only, fine if it's not valid yet + c.setTitle() + ui.Invalidate() + }) } } @@ -606,6 +616,7 @@ func (c *Composer) OnClose(fn func(composer *Composer)) { } func (c *Composer) Draw(ctx *ui.Context) { + c.setTitle() c.width = ctx.Width() c.grid.Draw(ctx) } @@ -1517,3 +1528,46 @@ func (c *Composer) checkEncryptionKeys(_ string) bool { } return true } + +// setTitle executes the title template and sets the tab title +func (c *Composer) setTitle() { + if c.Tab == nil { + return + } + data := struct { + Account string + Subject string + To []*mail.Address + From []*mail.Address + Cc []*mail.Address + Bcc []*mail.Address + OriginalFrom []*mail.Address + }{} + data.Account = c.acct.Name() + // Get subject direct from the textinput + subject, ok := c.editors["subject"] + if ok { + data.Subject = subject.input.String() + } + if data.Subject == "" { + data.Subject = "New Email" + } + // Get address fields from header, which gets updated on focus lost of + // any headerEditor field + data.From, _ = c.header.AddressList("from") + data.To, _ = c.header.AddressList("to") + data.Cc, _ = c.header.AddressList("cc") + data.Bcc, _ = c.header.AddressList("bcc") + + if c.parent != nil && c.parent.RFC822Headers != nil { + data.OriginalFrom, _ = c.parent.RFC822Headers.AddressList("from") + } + + buf := bytes.NewBuffer(nil) + err := c.acct.UiConfig().TabTitleComposer.Execute(buf, data) + if err != nil { + c.acct.PushError(err) + return + } + c.Tab.SetTitle(buf.String()) +} -- cgit