aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-02-02 00:48:51 +0100
committerRobin Jarry <robin@jarry.cc>2023-02-20 14:40:59 +0100
commit9fa296fb762231d386db88913d1c2ea521bd813c (patch)
tree445bf6554084bb37e6aed479c9942b5afecb2149 /widgets
parent28483808727fd288b95b9dd26a716f6cf7c02b5a (diff)
downloadaerc-9fa296fb762231d386db88913d1c2ea521bd813c.tar.gz
templates: unify data interface
Require that all aerc template data objects implement the same TemplateData interface. Implement that interface in two different places: 1) state.TemplateData (renamed/moved from templates.TemplateData). This structure (along with all its methods) needs to be decoupled from the templates package to break the import cycle with the config package. This allows much simpler construction of this object and ensure that values are calculated only when requested. 2) config.dummyData (extracted from templates). This is only used in the config package to validate user templates. Putting it here allows also to break an import cycle. Use state.TemplateData everywhere (including for account tabs title rendering). Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
Diffstat (limited to 'widgets')
-rw-r--r--widgets/account.go27
-rw-r--r--widgets/compose.go60
-rw-r--r--widgets/msglist.go24
3 files changed, 37 insertions, 74 deletions
diff --git a/widgets/account.go b/widgets/account.go
index 85043d1f..3176a2bf 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -13,7 +13,9 @@ import (
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/lib/marker"
"git.sr.ht/~rjarry/aerc/lib/sort"
+ "git.sr.ht/~rjarry/aerc/lib/state"
"git.sr.ht/~rjarry/aerc/lib/statusline"
+ "git.sr.ht/~rjarry/aerc/lib/templates"
"git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/log"
"git.sr.ht/~rjarry/aerc/models"
@@ -597,23 +599,14 @@ func (acct *AccountView) Vsplit(n int) error {
// setTitle executes the title template and sets the tab title
func (acct *AccountView) setTitle() {
- data := struct {
- Account string
- Recent int
- Unread int
- Exists int
- Folder string
- }{}
- data.Account = acct.Name()
- data.Folder = acct.SelectedDirectory()
- for _, name := range acct.dirlist.List() {
- r, u, e := acct.dirlist.GetRUECount(name)
- data.Recent += r
- data.Unread += u
- data.Exists += e
- }
- buf := bytes.NewBuffer(nil)
- err := acct.uiConf.TabTitleAccount.Execute(buf, data)
+ var data state.TemplateData
+
+ data.SetAccount(acct.acct)
+ data.SetFolder(acct.SelectedDirectory())
+ data.SetRUE(acct.dirlist.List(), acct.dirlist.GetRUECount)
+
+ var buf bytes.Buffer
+ err := templates.Render(acct.uiConf.TabTitleAccount, &buf, &data)
if err != nil {
acct.PushError(err)
return
diff --git a/widgets/compose.go b/widgets/compose.go
index 7311de7a..b74e1537 100644
--- a/widgets/compose.go
+++ b/widgets/compose.go
@@ -23,6 +23,7 @@ import (
"git.sr.ht/~rjarry/aerc/config"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/lib/format"
+ "git.sr.ht/~rjarry/aerc/lib/state"
"git.sr.ht/~rjarry/aerc/lib/templates"
"git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/log"
@@ -95,21 +96,11 @@ func NewComposer(
completer: nil,
}
- uiConfig := acct.UiConfig()
-
- templateData := templates.NewTemplateData(
- acct.acct.From,
- acct.acct.Aliases,
- acct.Name(),
- acct.Directories().Selected(),
- uiConfig.MessageViewTimestampFormat,
- uiConfig.MessageViewThisDayTimeFormat,
- uiConfig.MessageViewThisWeekTimeFormat,
- uiConfig.MessageViewThisYearTimeFormat,
- uiConfig.IconAttachment,
- )
- templateData.SetHeaders(h, orig)
- if err := c.AddTemplate(template, templateData); err != nil {
+ var data state.TemplateData
+ data.SetAccount(acct.acct)
+ data.SetFolder(acct.Directories().Selected())
+ data.SetHeaders(h, orig)
+ if err := c.AddTemplate(template, &data); err != nil {
return nil, err
}
c.AddSignature()
@@ -509,7 +500,7 @@ func (c *Composer) RemovePart(mimetype string) error {
return fmt.Errorf("%s part not found", mimetype)
}
-func (c *Composer) AddTemplate(template string, data interface{}) error {
+func (c *Composer) AddTemplate(template string, data models.TemplateData) error {
if template == "" {
return nil
}
@@ -1551,37 +1542,24 @@ 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()
+
+ var data state.TemplateData
+
+ header := c.header.Copy()
// 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"
+ header.SetSubject(subject.input.String())
}
- // 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")
+ if header.Get("subject") == "" {
+ header.SetSubject("New Email")
}
+ data.SetAccount(c.acctConfig)
+ data.SetFolder(c.acct.SelectedDirectory())
+ data.SetHeaders(&header, c.parent)
- buf := bytes.NewBuffer(nil)
- err := c.acct.UiConfig().TabTitleComposer.Execute(buf, data)
+ var buf bytes.Buffer
+ err := templates.Render(c.acct.UiConfig().TabTitleComposer, &buf, &data)
if err != nil {
c.acct.PushError(err)
return
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 85072d1e..4b2bf721 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -11,7 +11,7 @@ import (
"git.sr.ht/~rjarry/aerc/config"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/lib/iterator"
- "git.sr.ht/~rjarry/aerc/lib/templates"
+ "git.sr.ht/~rjarry/aerc/lib/state"
"git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/log"
"git.sr.ht/~rjarry/aerc/models"
@@ -87,19 +87,11 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
return
}
- data := templates.NewTemplateData(
- acct.acct.From,
- acct.acct.Aliases,
- acct.Name(),
- acct.Directories().Selected(),
- uiConfig.TimestampFormat,
- uiConfig.ThisDayTimeFormat,
- uiConfig.ThisWeekTimeFormat,
- uiConfig.ThisYearTimeFormat,
- uiConfig.IconAttachment,
- )
-
var needsHeaders []uint32
+ var data state.TemplateData
+
+ data.SetAccount(acct.acct)
+ data.SetFolder(acct.Directories().Selected())
customDraw := func(t *ui.Table, r int, c *ui.Context) bool {
row := &t.Rows[r]
@@ -175,7 +167,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
lastSubject = baseSubject
prevThread = thread
- if addMessage(store, thread.Uid, &table, data, uiConfig) {
+ if addMessage(store, thread.Uid, &table, &data, uiConfig) {
break threadLoop
}
}
@@ -187,7 +179,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
continue
}
uid := iter.Value().(uint32)
- if addMessage(store, uid, &table, data, uiConfig) {
+ if addMessage(store, uid, &table, &data, uiConfig) {
break
}
}
@@ -220,7 +212,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
func addMessage(
store *lib.MessageStore, uid uint32,
- table *ui.Table, data *templates.TemplateData,
+ table *ui.Table, data *state.TemplateData,
uiConfig *config.UIConfig,
) bool {
msg := store.Messages[uid]