diff options
Diffstat (limited to 'widgets')
-rw-r--r-- | widgets/account.go | 12 | ||||
-rw-r--r-- | widgets/aerc.go | 18 | ||||
-rw-r--r-- | widgets/status.go | 95 | ||||
-rw-r--r-- | widgets/tabhost.go | 4 |
4 files changed, 71 insertions, 58 deletions
diff --git a/widgets/account.go b/widgets/account.go index 135afef2..5b5d4dcd 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -35,7 +35,7 @@ type AccountView struct { tab *ui.Tab msglist *MessageList worker *types.Worker - state *state.State + state state.AccountState newConn bool // True if this is a first run after a new connection/reconnection uiConf *config.UIConfig @@ -66,7 +66,6 @@ func NewAccountView( acct: acct, aerc: aerc, host: host, - state: state.NewState(acct.Name, len(config.Accounts) > 1), uiConf: acctUiConf, } @@ -117,14 +116,14 @@ func NewAccountView( func (acct *AccountView) SetStatus(setters ...state.SetStateFunc) { for _, fn := range setters { - fn(acct.state, acct.SelectedDirectory()) + fn(&acct.state, acct.SelectedDirectory()) } acct.UpdateStatus() } func (acct *AccountView) UpdateStatus() { if acct.isSelected() { - acct.host.SetStatus(acct.state.StatusLine(acct.SelectedDirectory())) + acct.host.UpdateStatus() } } @@ -157,9 +156,6 @@ func (acct *AccountView) Invalidate() { } func (acct *AccountView) Draw(ctx *ui.Context) { - if acct.state.SetWidth(ctx.Width()) { - acct.UpdateStatus() - } acct.grid.Draw(ctx) } @@ -480,7 +476,7 @@ func (acct *AccountView) CheckMailTimer(d time.Duration) { go func() { defer log.PanicHandler() for range acct.ticker.C { - if !acct.state.Connected() { + if !acct.state.Connected { continue } acct.CheckMail() diff --git a/widgets/aerc.go b/widgets/aerc.go index b8be1100..572a123c 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -60,7 +60,7 @@ func NewAerc( tabs := ui.NewTabs(config.Ui) statusbar := ui.NewStack(config.Ui) - statusline := NewStatusLine(config.Ui) + statusline := &StatusLine{} statusbar.Push(statusline) grid := ui.NewGrid().Rows([]ui.GridSpec{ @@ -538,24 +538,16 @@ func (aerc *Aerc) SelectPreviousTab() bool { return aerc.tabs.SelectPrevious() } -func (aerc *Aerc) SetStatus(status string) *StatusMessage { - return aerc.statusline.Set(status) -} - func (aerc *Aerc) UpdateStatus() { if acct := aerc.SelectedAccount(); acct != nil { - acct.UpdateStatus() + aerc.statusline.Update(acct) } else { - aerc.ClearStatus() + aerc.statusline.Clear() } } -func (aerc *Aerc) ClearStatus() { - aerc.statusline.Set("") -} - -func (aerc *Aerc) SetError(status string) *StatusMessage { - return aerc.statusline.SetError(status) +func (aerc *Aerc) SetError(err string) { + aerc.statusline.SetError(err) } func (aerc *Aerc) PushStatus(text string, expiry time.Duration) *StatusMessage { diff --git a/widgets/status.go b/widgets/status.go index 67667016..00877ee2 100644 --- a/widgets/status.go +++ b/widgets/status.go @@ -1,20 +1,24 @@ package widgets import ( + "bytes" "time" "github.com/gdamore/tcell/v2" "github.com/mattn/go-runewidth" "git.sr.ht/~rjarry/aerc/config" + "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" ) type StatusLine struct { - stack []*StatusMessage - fallback StatusMessage - aerc *Aerc + stack []*StatusMessage + aerc *Aerc + acct *AccountView + err string } type StatusMessage struct { @@ -22,51 +26,72 @@ type StatusMessage struct { message string } -func NewStatusLine(uiConfig *config.UIConfig) *StatusLine { - return &StatusLine{ - fallback: StatusMessage{ - style: uiConfig.GetStyle(config.STYLE_STATUSLINE_DEFAULT), - message: "Idle", - }, - } -} - func (status *StatusLine) Invalidate() { ui.Invalidate() } func (status *StatusLine) Draw(ctx *ui.Context) { - line := &status.fallback - if len(status.stack) != 0 { - line = status.stack[len(status.stack)-1] - } - ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', line.style) - pendingKeys := "" - if status.aerc != nil { - for _, pendingKey := range status.aerc.pendingKeys { - pendingKeys += string(pendingKey.Rune) + style := status.uiConfig().GetStyle(config.STYLE_STATUSLINE_DEFAULT) + ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', style) + switch { + case len(status.stack) != 0: + line := status.stack[len(status.stack)-1] + msg := runewidth.Truncate(line.message, ctx.Width(), "") + msg = runewidth.FillRight(msg, ctx.Width()) + ctx.Printf(0, 0, line.style, "%s", msg) + case status.err != "": + msg := runewidth.Truncate(status.err, ctx.Width(), "") + msg = runewidth.FillRight(msg, ctx.Width()) + style := status.uiConfig().GetStyle(config.STYLE_STATUSLINE_ERROR) + ctx.Printf(0, 0, style, "%s", msg) + case status.aerc != nil && status.acct != nil: + var data state.TemplateData + data.SetPendingKeys(status.aerc.pendingKeys) + data.SetState(&status.acct.state) + data.SetAccount(status.acct.acct) + data.SetFolder(status.acct.Directories().Selected()) + msg, _ := status.acct.SelectedMessage() + data.SetInfo(msg, 0, false) + table := ui.NewTable( + ctx.Height(), + config.Statusline.StatusColumns, + config.Statusline.ColumnSeparator, + nil, + func(*ui.Table, int) tcell.Style { return style }, + ) + var buf bytes.Buffer + cells := make([]string, len(table.Columns)) + for c, col := range table.Columns { + err := templates.Render(col.Def.Template, &buf, &data) + if err != nil { + log.Errorf("%s", err) + cells[c] = err.Error() + } else { + cells[c] = buf.String() + } + buf.Reset() } + table.AddRow(cells, nil) + table.Draw(ctx) } - message := runewidth.FillRight(line.message, ctx.Width()-len(pendingKeys)-5) - ctx.Printf(0, 0, line.style, "%s%s", message, pendingKeys) } -func (status *StatusLine) Set(text string) *StatusMessage { - status.fallback = StatusMessage{ - style: status.uiConfig().GetStyle(config.STYLE_STATUSLINE_DEFAULT), - message: text, - } +func (status *StatusLine) Update(acct *AccountView) { + status.acct = acct status.Invalidate() - return &status.fallback } -func (status *StatusLine) SetError(text string) *StatusMessage { - status.fallback = StatusMessage{ - style: status.uiConfig().GetStyle(config.STYLE_STATUSLINE_ERROR), - message: text, +func (status *StatusLine) SetError(err string) { + prev := status.err + status.err = err + if prev != status.err { + status.Invalidate() } - status.Invalidate() - return &status.fallback +} + +func (status *StatusLine) Clear() { + status.SetError("") + status.acct = nil } func (status *StatusLine) Push(text string, expiry time.Duration) *StatusMessage { diff --git a/widgets/tabhost.go b/widgets/tabhost.go index 28c9be02..c0a9dd53 100644 --- a/widgets/tabhost.go +++ b/widgets/tabhost.go @@ -6,8 +6,8 @@ import ( type TabHost interface { BeginExCommand(cmd string) - SetStatus(status string) *StatusMessage - SetError(err string) *StatusMessage + UpdateStatus() + SetError(err string) PushStatus(text string, expiry time.Duration) *StatusMessage PushError(text string) *StatusMessage PushSuccess(text string) *StatusMessage |