Lay out message list widget basic design
This commit is contained in:
parent
b3896476a0
commit
0f8b7a1203
|
@ -21,6 +21,7 @@ type AccountView struct {
|
||||||
interactive ui.Interactive
|
interactive ui.Interactive
|
||||||
onInvalidate func(d ui.Drawable)
|
onInvalidate func(d ui.Drawable)
|
||||||
runCmd func(cmd string) error
|
runCmd func(cmd string) error
|
||||||
|
msglist *MessageList
|
||||||
msgStores map[string]*MessageStore
|
msgStores map[string]*MessageStore
|
||||||
statusline *StatusLine
|
statusline *StatusLine
|
||||||
statusbar *ui.Stack
|
statusbar *ui.Stack
|
||||||
|
@ -41,9 +42,6 @@ func NewAccountView(conf *config.AccountConfig,
|
||||||
{ui.SIZE_EXACT, 20},
|
{ui.SIZE_EXACT, 20},
|
||||||
{ui.SIZE_WEIGHT, 1},
|
{ui.SIZE_WEIGHT, 1},
|
||||||
})
|
})
|
||||||
spinner := NewSpinner()
|
|
||||||
spinner.Start()
|
|
||||||
grid.AddChild(spinner).At(0, 1)
|
|
||||||
grid.AddChild(statusbar).At(1, 1)
|
grid.AddChild(statusbar).At(1, 1)
|
||||||
|
|
||||||
worker, err := worker.NewWorker(conf.Source, logger)
|
worker, err := worker.NewWorker(conf.Source, logger)
|
||||||
|
@ -60,11 +58,15 @@ func NewAccountView(conf *config.AccountConfig,
|
||||||
dirlist := NewDirectoryList(conf, logger, worker)
|
dirlist := NewDirectoryList(conf, logger, worker)
|
||||||
grid.AddChild(ui.NewBordered(dirlist, ui.BORDER_RIGHT)).Span(2, 1)
|
grid.AddChild(ui.NewBordered(dirlist, ui.BORDER_RIGHT)).Span(2, 1)
|
||||||
|
|
||||||
|
msglist := NewMessageList(logger, worker)
|
||||||
|
grid.AddChild(msglist).At(0, 1)
|
||||||
|
|
||||||
acct := &AccountView{
|
acct := &AccountView{
|
||||||
conf: conf,
|
conf: conf,
|
||||||
dirlist: dirlist,
|
dirlist: dirlist,
|
||||||
grid: grid,
|
grid: grid,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
msglist: msglist,
|
||||||
msgStores: make(map[string]*MessageStore),
|
msgStores: make(map[string]*MessageStore),
|
||||||
runCmd: runCmd,
|
runCmd: runCmd,
|
||||||
statusbar: statusbar,
|
statusbar: statusbar,
|
||||||
|
@ -173,7 +175,8 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
|
||||||
case *types.OpenDirectory:
|
case *types.OpenDirectory:
|
||||||
acct.worker.PostAction(&types.FetchDirectoryContents{},
|
acct.worker.PostAction(&types.FetchDirectoryContents{},
|
||||||
func(msg types.WorkerMessage) {
|
func(msg types.WorkerMessage) {
|
||||||
// TODO: Do we care
|
store := acct.msgStores[acct.dirlist.selected]
|
||||||
|
acct.msglist.SetStore(store)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case *types.DirectoryInfo:
|
case *types.DirectoryInfo:
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
package widgets
|
package widgets
|
||||||
|
|
||||||
import (
|
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"
|
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,3 +40,86 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
|
||||||
break
|
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() {
|
func (s *Spinner) Start() {
|
||||||
|
if s.IsRunning() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
s.frame = 0
|
s.frame = 0
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
|
@ -54,6 +58,10 @@ func (s *Spinner) Start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Spinner) Stop() {
|
func (s *Spinner) Stop() {
|
||||||
|
if !s.IsRunning() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
s.stop <- nil
|
s.stop <- nil
|
||||||
s.frame = -1
|
s.frame = -1
|
||||||
s.Invalidate()
|
s.Invalidate()
|
||||||
|
@ -64,6 +72,10 @@ func (s *Spinner) IsRunning() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Spinner) Draw(ctx *ui.Context) {
|
func (s *Spinner) Draw(ctx *ui.Context) {
|
||||||
|
if !s.IsRunning() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)
|
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)
|
||||||
col := ctx.Width()/2 - len(frames[0])/2 + 1
|
col := ctx.Width()/2 - len(frames[0])/2 + 1
|
||||||
ctx.Printf(col, 0, tcell.StyleDefault, "%s", frames[s.frame])
|
ctx.Printf(col, 0, tcell.StyleDefault, "%s", frames[s.frame])
|
||||||
|
|
Loading…
Reference in New Issue