diff --git a/commands/account/next-result.go b/commands/account/next-result.go index 78d437d..fe835ea 100644 --- a/commands/account/next-result.go +++ b/commands/account/next-result.go @@ -34,13 +34,13 @@ func (NextPrevResult) Execute(aerc *widgets.Aerc, args []string) error { if store != nil { store.PrevResult() } - acct.Messages().Scroll() + acct.Messages().Invalidate() } else { store := acct.Store() if store != nil { store.NextResult() } - acct.Messages().Scroll() + acct.Messages().Invalidate() } return nil } diff --git a/commands/account/next.go b/commands/account/next.go index 5e4838e..427f563 100644 --- a/commands/account/next.go +++ b/commands/account/next.go @@ -65,13 +65,13 @@ func ExecuteNextPrevMessage(args []string, acct *widgets.AccountView, pct bool, store := acct.Store() if store != nil { store.NextPrev(-n) - acct.Messages().Scroll() + acct.Messages().Invalidate() } } else { store := acct.Store() if store != nil { store.NextPrev(n) - acct.Messages().Scroll() + acct.Messages().Invalidate() } } return nil diff --git a/commands/account/search.go b/commands/account/search.go index 1d2e7a2..607dc24 100644 --- a/commands/account/search.go +++ b/commands/account/search.go @@ -45,7 +45,7 @@ func (SearchFilter) Execute(aerc *widgets.Aerc, args []string) error { acct.Logger().Printf("Search results: %v", uids) store.ApplySearch(uids) // TODO: Remove when stores have multiple OnUpdate handlers - acct.Messages().Scroll() + acct.Messages().Invalidate() } } store.Search(args, cb) diff --git a/commands/msg/archive.go b/commands/msg/archive.go index 5561674..07de13f 100644 --- a/commands/msg/archive.go +++ b/commands/msg/archive.go @@ -53,7 +53,7 @@ func (Archive) Execute(aerc *widgets.Aerc, args []string) error { } archiveDir := acct.AccountConfig().Archive store.Next() - acct.Messages().Scroll() + acct.Messages().Invalidate() var uidMap map[string][]uint32 switch args[1] { diff --git a/commands/msg/delete.go b/commands/msg/delete.go index 4bda8b9..e74bf10 100644 --- a/commands/msg/delete.go +++ b/commands/msg/delete.go @@ -62,7 +62,7 @@ func (Delete) Execute(aerc *widgets.Aerc, args []string) error { // no more messages in the list if next == nil { aerc.RemoveTab(h.msgProvider) - acct.Messages().Scroll() + acct.Messages().Invalidate() return nil } lib.NewMessageStoreView(next, store, aerc.DecryptKeys, @@ -76,7 +76,7 @@ func (Delete) Execute(aerc *widgets.Aerc, args []string) error { }) } } - acct.Messages().Scroll() + acct.Messages().Invalidate() return nil } diff --git a/commands/msg/move.go b/commands/msg/move.go index 830e752..41f61da 100644 --- a/commands/msg/move.go +++ b/commands/msg/move.go @@ -62,7 +62,7 @@ func (Move) Execute(aerc *widgets.Aerc, args []string) error { aerc.RemoveTab(h.msgProvider) } store.Next() - acct.Messages().Scroll() + acct.Messages().Invalidate() joinedArgs := strings.Join(args[optind:], " ") store.Move(uids, joinedArgs, createParents, func( msg types.WorkerMessage) { diff --git a/widgets/msglist.go b/widgets/msglist.go index 5aedb44..38b6369 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -63,6 +63,8 @@ func (ml *MessageList) Draw(ctx *ui.Context) { } } + ml.ensureScroll() + var ( needsHeaders []uint32 row int = 0 @@ -179,12 +181,12 @@ func (ml *MessageList) MouseEvent(localX int, localY int, event tcell.Event) { if ml.store != nil { ml.store.Next() } - ml.Scroll() + ml.Invalidate() case tcell.WheelUp: if ml.store != nil { ml.store.Prev() } - ml.Scroll() + ml.Invalidate() } } } @@ -225,7 +227,6 @@ func (ml *MessageList) storeUpdate(store *lib.MessageStore) { ml.nmsgs = len(uids) } - ml.Scroll() ml.Invalidate() } @@ -266,25 +267,40 @@ func (ml *MessageList) Selected() *models.MessageInfo { func (ml *MessageList) Select(index int) { store := ml.Store() store.Select(index) - ml.Scroll() + ml.Invalidate() } -func (ml *MessageList) Scroll() { +func (ml *MessageList) ensureScroll() { store := ml.Store() - if store == nil || len(store.Uids()) == 0 { return } - if ml.Height() != 0 { - // I'm too lazy to do the math right now - for store.SelectedIndex()-ml.scroll >= ml.Height() { - ml.scroll += 1 - } - for store.SelectedIndex()-ml.scroll < 0 { - ml.scroll -= 1 - } + + h := ml.Height() + + maxScroll := len(store.Uids()) - h + if maxScroll < 0 { + maxScroll = 0 + } + + selectedIndex := store.SelectedIndex() + + if selectedIndex >= ml.scroll && selectedIndex < ml.scroll+h { + if ml.scroll > maxScroll { + ml.scroll = maxScroll + } + return + } + + if selectedIndex >= ml.scroll+h { + ml.scroll = selectedIndex - h + 1 + } else if selectedIndex < ml.scroll { + ml.scroll = selectedIndex + } + + if ml.scroll > maxScroll { + ml.scroll = maxScroll } - ml.Invalidate() } func (ml *MessageList) drawEmptyMessage(ctx *ui.Context) {