Lay out message list widget basic design
This commit is contained in:
parent
b3896476a0
commit
0f8b7a1203
3 changed files with 108 additions and 4 deletions
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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])
|
||||
|
|
Loading…
Reference in a new issue