summary refs log tree commit diff stats
path: root/commands
Commit message (Expand)AuthorAgeFilesLines
* Implement :pwd commandAmin Bandali2019-05-191-0/+25
* Fix scdoc & gofmt issuesDrew DeVault2019-05-185-17/+11
* s/aerc2/aerc/gDrew DeVault2019-05-1725-29/+29
* Remove debug loggingDrew DeVault2019-05-171-1/+0
* Refactor STARTTLS to prevent downgrade attacksDrew DeVault2019-05-171-23/+27
* s/Sent/Message sent/Drew DeVault2019-05-161-2/+2
* Improve reply-all recipient enumeration strategyDrew DeVault2019-05-161-0/+16
* Decode email when reading it for quotingDrew DeVault2019-05-161-2/+25
* Don't prefix Re: if prefix already presentDrew DeVault2019-05-161-1/+6
* Implement :reply -q and :reply -aDrew DeVault2019-05-161-19/+61
* Implement (basic form) of :replyDrew DeVault2019-05-161-0/+83
* Let caller pass in custom headers to composeDrew DeVault2019-05-161-2/+2
* Copy sent emails to the Sent folderDrew DeVault2019-05-152-15/+53
* Implement move, mv commandsDrew DeVault2019-05-141-0/+38
* Implement :copy (aka :cp)Drew DeVault2019-05-142-1/+51
* Implement abort commandCole Helbling2019-05-141-0/+23
* Update tab name as subject changesDrew DeVault2019-05-142-9/+10
* Add $EDITOR, internal config for composeDrew DeVault2019-05-141-1/+1
* Remove tab before going asyncDrew DeVault2019-05-141-1/+1
* Add distinct keybindings for each compose viewDrew DeVault2019-05-141-1/+1
* Send emails asyncronouslyDrew DeVault2019-05-141-47/+73
* Implement sending emails /o/Drew DeVault2019-05-141-6/+114
* Add :send-message, prepares & writes email to /tmpDrew DeVault2019-05-141-0/+29
* Populate "From" header from config for new emailsDrew DeVault2019-05-131-2/+2
* Implement :{next,prev}-field in compose viewDrew DeVault2019-05-122-0/+46
* Add initial compose widgetDrew DeVault2019-05-121-0/+28
* "Press any key to close" for completed processesDrew DeVault2019-05-111-1/+4
* Fix segfault on :select-message for unloaded messagesTom Lebreux2019-04-171-0/+3
* Fix segfault on :view-message for unloaded messageTom Lebreux2019-04-101-0/+6
* Make tab width of :pipe consistentDrew DeVault2019-03-311-5/+3
* Add basic filter implementationDrew DeVault2019-03-311-1/+1
* Rename FetchMessageBodies to FetchFullMessagesDrew DeVault2019-03-311-1/+1
* Make the message viewer real, part oneDrew DeVault2019-03-312-3/+27
* Don't parse mail in worker; send a reader insteadDrew DeVault2019-03-312-34/+2
* Add message view commands, :closeDrew DeVault2019-03-303-4/+38
* Add basic message viewer mockupDrew DeVault2019-03-303-8/+6
* Correct color of error messagesDrew DeVault2019-03-302-5/+5
* Implement :pipeDrew DeVault2019-03-302-0/+74
* Add body fetching support codeDrew DeVault2019-03-291-0/+29
* Add terminal command contextDrew DeVault2019-03-212-4/+19
* Add context-specific commandsDrew DeVault2019-03-2113-30/+72
* Implement :delete-messageDrew DeVault2019-03-201-0/+25
* s/:term-close/:close/gDrew DeVault2019-03-171-2/+3
* Wrap Terminal in TermHostDrew DeVault2019-03-172-19/+6
* Add :term-closeDrew DeVault2019-03-172-2/+40
* Handle terminal title, login shellDrew DeVault2019-03-171-5/+16
* Implement :next-tab, :prev-tabDrew DeVault2019-03-171-0/+42
* Move exline handling up to aerc, add :termDrew DeVault2019-03-171-0/+33
* commands: handle case where no account selectedDrew DeVault2019-03-174-0/+12
* Implement :select-messageDrew DeVault2019-03-151-0/+31
t-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
package widgets

import (
	"time"

	"github.com/gdamore/tcell"

	"git.sr.ht/~sircmpwn/aerc2/lib/ui"
)

type StatusLine struct {
	stack    []*StatusMessage
	fallback StatusMessage

	onInvalidate func(d ui.Drawable)
}

type StatusMessage struct {
	bg      tcell.Color
	fg      tcell.Color
	message string
}

func NewStatusLine() *StatusLine {
	return &StatusLine{
		fallback: StatusMessage{
			bg:      tcell.ColorWhite,
			fg:      tcell.ColorBlack,
			message: "Idle",
		},
	}
}

func (status *StatusLine) OnInvalidate(onInvalidate func(d ui.Drawable)) {
	status.onInvalidate = onInvalidate
}

func (status *StatusLine) Invalidate() {
	if status.onInvalidate != nil {
		status.onInvalidate(status)
	}
}

func (status *StatusLine) Draw(ctx *ui.Context) {
	line := &status.fallback
	if len(status.stack) != 0 {
		line = status.stack[len(status.stack)-1]
	}
	style := tcell.StyleDefault.Background(line.bg).Foreground(line.fg)
	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', style)
	ctx.Printf(0, 0, style, "%s", line.message)
}

func (status *StatusLine) Set(text string) *StatusMessage {
	status.fallback = StatusMessage{
		bg:      tcell.ColorWhite,
		fg:      tcell.ColorBlack,
		message: text,
	}
	status.Invalidate()
	return &status.fallback
}

func (status *StatusLine) Push(text string, expiry time.Duration) *StatusMessage {
	msg := &StatusMessage{
		bg:      tcell.ColorWhite,
		fg:      tcell.ColorBlack,
		message: text,
	}
	status.stack = append(status.stack, msg)
	go (func() {
		time.Sleep(expiry)
		for i, m := range status.stack {
			if m == msg {
				status.stack = append(status.stack[:i], status.stack[i+1:]...)
				break
			}
		}
		status.Invalidate()
	})()
	return msg
}

func (status *StatusLine) Expire() {
	status.stack = nil
}

func (msg *StatusMessage) Color(bg tcell.Color, fg tcell.Color) {
	msg.bg = bg
	msg.fg = fg
}