about summary refs log tree commit diff stats
path: root/widgets
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-03-14 21:37:00 -0400
committerDrew DeVault <sir@cmpwn.com>2019-03-14 21:37:00 -0400
commit0f8b7a1203309ebec0dc78baf3f195671eadac2d (patch)
treefce6d8148cdbfa5ecfb2030a902f5a0763bb3643 /widgets
parentb3896476a0e6978c0d7f6fedfb64588934a78f1e (diff)
downloadaerc-0f8b7a1203309ebec0dc78baf3f195671eadac2d.tar.gz
Lay out message list widget basic design
Diffstat (limited to 'widgets')
-rw-r--r--widgets/account.go11
-rw-r--r--widgets/msglist.go89
-rw-r--r--widgets/spinner.go12
3 files changed, 108 insertions, 4 deletions
diff --git a/widgets/account.go b/widgets/account.go
index 3085d27..8857535 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -21,6 +21,7 @@ type AccountView struct {
 	interactive  ui.Interactive
 	onInvalidate func(d ui.Drawable)
 	runCmd       func(cmd string) error
+	msglist      *MessageList
 	msgStores    map[string]*MessageStore
 	statusline   *StatusLine
 	statusbar    *ui.Stack
@@ -41,9 +42,6 @@ func NewAccountView(conf *config.AccountConfig,
 		{ui.SIZE_EXACT, 20},
 		{ui.SIZE_WEIGHT, 1},
 	})
-	spinner := NewSpinner()
-	spinner.Start()
-	grid.AddChild(spinner).At(0, 1)
 	grid.AddChild(statusbar).At(1, 1)
 
 	worker, err := worker.NewWorker(conf.Source, logger)
@@ -60,11 +58,15 @@ func NewAccountView(conf *config.AccountConfig,
 	dirlist := NewDirectoryList(conf, logger, worker)
 	grid.AddChild(ui.NewBordered(dirlist, ui.BORDER_RIGHT)).Span(2, 1)
 
+	msglist := NewMessageList(logger, worker)
+	grid.AddChild(msglist).At(0, 1)
+
 	acct := &AccountView{
 		conf:       conf,
 		dirlist:    dirlist,
 		grid:       grid,
 		logger:     logger,
+		msglist:    msglist,
 		msgStores:  make(map[string]*MessageStore),
 		runCmd:     runCmd,
 		statusbar:  statusbar,
@@ -173,7 +175,8 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
 		case *types.OpenDirectory:
 			acct.worker.PostAction(&types.FetchDirectoryContents{},
 				func(msg types.WorkerMessage) {
-					// TODO: Do we care
+					store := acct.msgStores[acct.dirlist.selected]
+					acct.msglist.SetStore(store)
 				})
 		}
 	case *types.DirectoryInfo:
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 370ba85..8e3c2eb 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -1,6 +1,12 @@
 package widgets
 
 import (
+	"log"
+
+	"github.com/gdamore/tcell"
+
+	"git.sr.ht/~sircmpwn/aerc2/config"
+	"git.sr.ht/~sircmpwn/aerc2/lib/ui"
 	"git.sr.ht/~sircmpwn/aerc2/worker/types"
 )
 
@@ -34,3 +40,86 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
 		break
 	}
 }
+
+type MessageList struct {
+	conf         *config.AercConfig
+	logger       *log.Logger
+	onInvalidate func(d ui.Drawable)
+	spinner      *Spinner
+	store        *MessageStore
+	worker       *types.Worker
+}
+
+// TODO: fish in config
+func NewMessageList(logger *log.Logger, worker *types.Worker) *MessageList {
+	ml := &MessageList{
+		logger:  logger,
+		spinner: NewSpinner(),
+		worker:  worker,
+	}
+	ml.spinner.OnInvalidate(func(_ ui.Drawable) {
+		ml.Invalidate()
+	})
+	// TODO: stop spinner, probably
+	ml.spinner.Start()
+	return ml
+}
+
+func (ml *MessageList) OnInvalidate(onInvalidate func(d ui.Drawable)) {
+	ml.onInvalidate = onInvalidate
+}
+
+func (ml *MessageList) Invalidate() {
+	if ml.onInvalidate != nil {
+		ml.onInvalidate(ml)
+	}
+}
+
+func (ml *MessageList) Draw(ctx *ui.Context) {
+	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)
+
+	if ml.store == nil {
+		ml.spinner.Draw(ctx)
+		return
+	}
+
+	var (
+		needsHeaders []uint64
+		row          int = 0
+	)
+
+	for uid, msg := range ml.store.Messages {
+		if row >= ctx.Height() {
+			break
+		}
+
+		if msg == nil {
+			needsHeaders = append(needsHeaders, uid)
+			ml.spinner.Draw(ctx.Subcontext(0, row, ctx.Width(), 1))
+		}
+
+		row += 1
+	}
+
+	if len(needsHeaders) != 0 {
+		ml.spinner.Start()
+	} else {
+		ml.spinner.Stop()
+	}
+
+	// TODO: Fetch these messages
+}
+
+func (ml *MessageList) SetStore(store *MessageStore) {
+	if ml.store == store {
+		return
+	}
+
+	ml.store = store
+	if store != nil {
+		ml.spinner.Stop()
+	} else {
+		ml.spinner.Start()
+	}
+	ml.Invalidate()
+}
diff --git a/widgets/spinner.go b/widgets/spinner.go
index 2e7e367..812fb2c 100644
--- a/widgets/spinner.go
+++ b/widgets/spinner.go
@@ -36,6 +36,10 @@ func NewSpinner() *Spinner {
 }
 
 func (s *Spinner) Start() {
+	if s.IsRunning() {
+		return
+	}
+
 	s.frame = 0
 	go func() {
 		for {
@@ -54,6 +58,10 @@ func (s *Spinner) Start() {
 }
 
 func (s *Spinner) Stop() {
+	if !s.IsRunning() {
+		return
+	}
+
 	s.stop <- nil
 	s.frame = -1
 	s.Invalidate()
@@ -64,6 +72,10 @@ func (s *Spinner) IsRunning() bool {
 }
 
 func (s *Spinner) Draw(ctx *ui.Context) {
+	if !s.IsRunning() {
+		return
+	}
+
 	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)
 	col := ctx.Width()/2 - len(frames[0])/2 + 1
 	ctx.Printf(col, 0, tcell.StyleDefault, "%s", frames[s.frame])