summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/aerc/main.go20
-rw-r--r--ui/account.go31
-rw-r--r--ui/helpers.go30
-rw-r--r--ui/types.go15
-rw-r--r--ui/ui.go15
-rw-r--r--worker/imap/worker.go9
-rw-r--r--worker/types/messages.go2
-rw-r--r--worker/worker.go2
8 files changed, 86 insertions, 38 deletions
diff --git a/cmd/aerc/main.go b/cmd/aerc/main.go
index 420d7a8..e33f158 100644
--- a/cmd/aerc/main.go
+++ b/cmd/aerc/main.go
@@ -5,8 +5,6 @@ import (
"git.sr.ht/~sircmpwn/aerc2/config"
"git.sr.ht/~sircmpwn/aerc2/ui"
- "git.sr.ht/~sircmpwn/aerc2/worker"
- "git.sr.ht/~sircmpwn/aerc2/worker/types"
)
func main() {
@@ -19,27 +17,15 @@ func main() {
panic(err)
}
defer _ui.Close()
- var workers []worker.Worker
for _, account := range conf.Accounts {
- work, err := worker.NewWorker(account.Source)
+ tab, err := ui.NewAccountTab(&account)
if err != nil {
panic(err)
}
- go work.Run()
- work.PostAction(types.Configure{Config: account})
- workers = append(workers, work)
- // TODO: Give tabs ownership over their workers
- _ui.AddTab(ui.NewAccountTab(&account, &work))
+ _ui.AddTab(tab)
}
for !_ui.Exit {
- activity := false
- for _, worker := range workers {
- if msg := worker.GetMessage(); msg != nil {
- activity = true
- }
- }
- activity = _ui.Tick() || activity
- if !activity {
+ if !_ui.Tick() {
time.Sleep(100 * time.Millisecond)
}
}
diff --git a/ui/account.go b/ui/account.go
index 9c16cc5..50f41e4 100644
--- a/ui/account.go
+++ b/ui/account.go
@@ -1,25 +1,35 @@
package ui
import (
+ "fmt"
+
tb "github.com/nsf/termbox-go"
"git.sr.ht/~sircmpwn/aerc2/config"
"git.sr.ht/~sircmpwn/aerc2/worker"
+ "git.sr.ht/~sircmpwn/aerc2/worker/types"
)
type AccountTab struct {
Config *config.AccountConfig
- Worker *worker.Worker
+ Worker worker.Worker
Parent *UIState
counter int
+ log []string
}
-func NewAccountTab(conf *config.AccountConfig, work *worker.Worker) *AccountTab {
+func NewAccountTab(conf *config.AccountConfig) (*AccountTab, error) {
+ work, err := worker.NewWorker(conf.Source)
+ if err != nil {
+ return nil, err
+ }
+ go work.Run()
+ work.PostAction(types.Configure{Config: conf})
return &AccountTab{
Config: conf,
Worker: work,
- }
+ }, nil
}
func (acc *AccountTab) Name() string {
@@ -32,13 +42,26 @@ func (acc *AccountTab) SetParent(parent *UIState) {
func (acc *AccountTab) Render(at Geometry) {
cell := tb.Cell{
+ Ch: ' ',
Fg: tb.ColorDefault,
Bg: tb.ColorDefault,
}
- TPrintf(&at, cell, "%s %d", acc.Name(), acc.counter)
+ TFill(at, cell)
+ TPrintf(&at, cell, "%s %d\n", acc.Name(), acc.counter)
+ for _, str := range acc.log {
+ TPrintf(&at, cell, "%s\n", str)
+ }
acc.counter++
if acc.counter%10000 == 0 {
acc.counter = 0
}
acc.Parent.InvalidateFrom(acc)
}
+
+func (acc *AccountTab) GetChannel() chan types.WorkerMessage {
+ return acc.Worker.GetMessages()
+}
+
+func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) {
+ acc.log = append(acc.log, fmt.Sprintf("<- %T", msg))
+}
diff --git a/ui/helpers.go b/ui/helpers.go
index 0b8789e..f2b2adf 100644
--- a/ui/helpers.go
+++ b/ui/helpers.go
@@ -9,13 +9,33 @@ import (
func TPrintf(geo *Geometry, ref tb.Cell, format string, a ...interface{}) {
str := fmt.Sprintf(format, a...)
_geo := *geo
+ newline := func() {
+ // TODO: Abort when out of room?
+ geo.Col = _geo.Col
+ geo.Row++
+ }
for _, ch := range str {
- tb.SetCell(geo.Col, geo.Row, ch, ref.Fg, ref.Bg)
- geo.Col++
- if geo.Col == _geo.Col+geo.Width {
- // TODO: Abort when out of room?
+ switch ch {
+ case '\n':
+ newline()
+ case '\r':
geo.Col = _geo.Col
- geo.Row++
+ default:
+ tb.SetCell(geo.Col, geo.Row, ch, ref.Fg, ref.Bg)
+ geo.Col++
+ if geo.Col == _geo.Col+geo.Width {
+ newline()
+ }
+ }
+ }
+}
+
+func TFill(geo Geometry, ref tb.Cell) {
+ _geo := geo
+ for ; geo.Row < geo.Height; geo.Row++ {
+ for ; geo.Col < geo.Width; geo.Col++ {
+ tb.SetCell(geo.Col, geo.Row, ref.Ch, ref.Fg, ref.Bg)
}
+ geo.Col = _geo.Col
}
}
diff --git a/ui/types.go b/ui/types.go
index 14a91c3..5437642 100644
--- a/ui/types.go
+++ b/ui/types.go
@@ -4,20 +4,19 @@ import (
tb "github.com/nsf/termbox-go"
"git.sr.ht/~sircmpwn/aerc2/config"
+ "git.sr.ht/~sircmpwn/aerc2/worker/types"
)
const (
Valid = 0
InvalidateTabList = 1 << iota
InvalidateTabView
- InvalidateSidebar
InvalidateStatusBar
)
const (
InvalidateAll = InvalidateTabList |
InvalidateTabView |
- InvalidateSidebar |
InvalidateStatusBar
)
@@ -34,6 +33,16 @@ type AercTab interface {
SetParent(parent *UIState)
}
+type WorkerListener interface {
+ GetChannel() chan types.WorkerMessage
+ HandleMessage(msg types.WorkerMessage)
+}
+
+type wrappedMessage struct {
+ msg types.WorkerMessage
+ listener WorkerListener
+}
+
type UIState struct {
Config *config.AercConfig
Exit bool
@@ -57,4 +66,6 @@ type UIState struct {
}
tbEvents chan tb.Event
+ // Aggregate channel for all worker messages
+ workerEvents chan wrappedMessage
}
diff --git a/ui/ui.go b/ui/ui.go
index f01af08..db31696 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -11,7 +11,8 @@ func Initialize(conf *config.AercConfig) (*UIState, error) {
Config: conf,
InvalidPanes: InvalidateAll,
- tbEvents: make(chan tb.Event, 10),
+ tbEvents: make(chan tb.Event, 10),
+ workerEvents: make(chan wrappedMessage),
}
if err := tb.Init(); err != nil {
return nil, err
@@ -33,6 +34,16 @@ func (state *UIState) Close() {
func (state *UIState) AddTab(tab AercTab) {
tab.SetParent(state)
state.Tabs = append(state.Tabs, tab)
+ if listener, ok := tab.(WorkerListener); ok {
+ go (func() {
+ for msg := range listener.GetChannel() {
+ state.workerEvents <- wrappedMessage{
+ msg: msg,
+ listener: listener,
+ }
+ }
+ })()
+ }
}
func (state *UIState) Invalidate(what uint) {
@@ -67,6 +78,8 @@ func (state *UIState) Tick() bool {
case tb.EventResize:
state.Invalidate(InvalidateAll)
}
+ case msg := <-state.workerEvents:
+ msg.listener.HandleMessage(msg.msg)
default:
// no-op
break
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index 14e4004..080927d 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -18,13 +18,8 @@ func NewIMAPWorker() *IMAPWorker {
}
}
-func (w *IMAPWorker) GetMessage() types.WorkerMessage {
- select {
- case msg := <-w.messages:
- return msg
- default:
- return nil
- }
+func (w *IMAPWorker) GetMessages() chan types.WorkerMessage {
+ return w.messages
}
func (w *IMAPWorker) PostAction(msg types.WorkerMessage) {
diff --git a/worker/types/messages.go b/worker/types/messages.go
index 845bb86..a4d8ddb 100644
--- a/worker/types/messages.go
+++ b/worker/types/messages.go
@@ -33,7 +33,7 @@ type Ping struct {
type Configure struct {
Message
- Config config.AccountConfig
+ Config *config.AccountConfig
}
type Connect struct {
diff --git a/worker/worker.go b/worker/worker.go
index da7928e..c8ec622 100644
--- a/worker/worker.go
+++ b/worker/worker.go
@@ -9,7 +9,7 @@ import (
)
type Worker interface {
- GetMessage() types.WorkerMessage
+ GetMessages() chan types.WorkerMessage
PostAction(types.WorkerMessage)
Run()
}