From dd7ae7e4b13026d7074e97da781073e748dbb879 Mon Sep 17 00:00:00 2001 From: Miguel Mota Date: Mon, 2 Apr 2018 09:39:11 -0700 Subject: [PATCH] add pagination Former-commit-id: 8ca367e69d32d36e90c101e2c59bd1609b9b7ac0 [formerly 8ca367e69d32d36e90c101e2c59bd1609b9b7ac0 [formerly c072643cade74f2f07698daffd7009579eade69d [formerly 7b8c08e0cf85cf662f0abfe88c1f146f6983ccb1]]] Former-commit-id: f924ab003eb325c4c754a3aac97eff81836fbb67 Former-commit-id: b8c5df995b0ec7f95b3457264433ea65567cc6f3 [formerly 6f120209f2a5531b584a246f3eb9aa4d23532866] Former-commit-id: 9a63835ebcc7cbaa7e5a8896700d2c74d652b6d2 --- README.md | 2 ++ bin/cointop32.REMOVED.git-id | 2 +- bin/cointop64.REMOVED.git-id | 2 +- cointop/cointop.go | 9 ++++- cointop/keybindings.go | 2 ++ cointop/layout.go | 67 +++++++++++++++++++++++++++++++----- cointop/navigation.go | 18 +++++++++- cointop/sort.go | 11 +++--- cointop/status.go | 2 +- cointop/table.go | 12 +++++-- 10 files changed, 106 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 103bf2c..2808680 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ List of shortcuts: |----|------| |``|navigate up| |``|navigate down| +|``|next page| +|``|previous page| |``|page up| |``|page down| |``|visit highlighted coin on CoinMarketCap| diff --git a/bin/cointop32.REMOVED.git-id b/bin/cointop32.REMOVED.git-id index 81b0fd7..0ef2d3b 100644 --- a/bin/cointop32.REMOVED.git-id +++ b/bin/cointop32.REMOVED.git-id @@ -1 +1 @@ -8581fe52805451f3f959248757480db12e4a3b0d \ No newline at end of file +ed65aa79a4f28f144b4b21c2481224f0466a5181 \ No newline at end of file diff --git a/bin/cointop64.REMOVED.git-id b/bin/cointop64.REMOVED.git-id index ffea376..3e34b1f 100644 --- a/bin/cointop64.REMOVED.git-id +++ b/bin/cointop64.REMOVED.git-id @@ -1 +1 @@ -5a10db031042fc4de090c186e9870f60510e4d68 \ No newline at end of file +7410bf82087f7933ba1f4b27e49187dca72d6436 \ No newline at end of file diff --git a/cointop/cointop.go b/cointop/cointop.go index 5abb6fd..bceabcb 100644 --- a/cointop/cointop.go +++ b/cointop/cointop.go @@ -34,8 +34,11 @@ type Cointop struct { sortdesc bool sortby string api api.Interface + allcoins []*apitypes.Coin coins []*apitypes.Coin - coinsmap map[string]apitypes.Coin + allcoinsmap map[string]apitypes.Coin + page int + perpage int refreshmux sync.Mutex refreshticker *time.Ticker } @@ -54,6 +57,10 @@ func Run() { g: g, api: api.NewCMC(), refreshticker: time.NewTicker(1 * time.Minute), + sortby: "rank", + sortdesc: false, + page: 0, + perpage: 100, } g.SetManagerFunc(ct.layout) if err := ct.keybindings(g); err != nil { diff --git a/cointop/keybindings.go b/cointop/keybindings.go index 7aac75d..496d70f 100644 --- a/cointop/keybindings.go +++ b/cointop/keybindings.go @@ -21,6 +21,8 @@ func (ct *Cointop) setKeybinding(key interface{}, callback func(g *gocui.Gui, v } func (ct *Cointop) keybindings(g *gocui.Gui) error { + ct.setKeybinding(gocui.KeyArrowRight, ct.nextPage) + ct.setKeybinding(gocui.KeyArrowLeft, ct.prevPage) ct.setKeybinding(gocui.KeyArrowDown, ct.cursorDown) ct.setKeybinding('j', ct.cursorDown) ct.setKeybinding(gocui.KeyArrowUp, ct.cursorUp) diff --git a/cointop/layout.go b/cointop/layout.go index a900263..0bd673e 100644 --- a/cointop/layout.go +++ b/cointop/layout.go @@ -1,6 +1,8 @@ package cointop import ( + "math" + "github.com/jroimartin/gocui" apitypes "github.com/miguelmota/cointop/pkg/api/types" "github.com/miguelmota/cointop/pkg/pad" @@ -75,8 +77,8 @@ func (ct *Cointop) layout(g *gocui.Gui) error { ct.tableview.Highlight = true ct.tableview.SelBgColor = gocui.ColorCyan ct.tableview.SelFgColor = gocui.ColorBlack + ct.updateCoins() ct.updateTable() - ct.sort("rank", false) ct.rowChanged() } @@ -95,21 +97,67 @@ func (ct *Cointop) layout(g *gocui.Gui) error { return nil } -func (ct *Cointop) updateTable() error { +func (ct *Cointop) updateCoins() error { list := []*apitypes.Coin{} - coinsmap, err := ct.api.GetAllCoinData() + allcoinsmap, err := ct.api.GetAllCoinData() if err != nil { return err } - ct.coinsmap = coinsmap - for i := range ct.coinsmap { - coin := ct.coinsmap[i] - list = append(list, &coin) + ct.allcoinsmap = allcoinsmap + if len(ct.allcoins) == 0 { + for i := range ct.allcoinsmap { + coin := ct.allcoinsmap[i] + list = append(list, &coin) + } + ct.allcoins = list + ct.sort(ct.sortby, ct.sortdesc, ct.allcoins) + } else { + // update list in place without changing order + for i := range ct.allcoinsmap { + cm := ct.allcoinsmap[i] + for k := range ct.allcoins { + c := ct.allcoins[k] + if c.ID == cm.ID { + /* + if c.ID == "ethereum" { + // test + cm.PriceUSD = float64(time.Now().Unix()) + } + */ + c.ID = cm.ID + c.Name = cm.Name + c.Symbol = cm.Symbol + c.Rank = cm.Rank + c.PriceUSD = cm.PriceUSD + c.PriceBTC = cm.PriceBTC + c.USD24HVolume = cm.USD24HVolume + c.MarketCapUSD = cm.MarketCapUSD + c.AvailableSupply = cm.AvailableSupply + c.TotalSupply = cm.TotalSupply + c.PercentChange1H = cm.PercentChange1H + c.PercentChange24H = cm.PercentChange24H + c.PercentChange7D = cm.PercentChange7D + c.LastUpdated = cm.LastUpdated + } + } + } + } + return nil +} + +func (ct *Cointop) updateTable() error { + start := ct.page * ct.perpage + end := start + ct.perpage + if end >= len(ct.allcoins)-1 { + start = int(math.Floor(float64(start/100)) * 100) + + end = len(ct.allcoins) - 1 } - ct.coins = list - ct.sort(ct.sortby, ct.sortdesc) + sliced := ct.allcoins[start:end] + ct.coins = sliced + ct.sort(ct.sortby, ct.sortdesc, ct.coins) ct.refreshTable() return nil } @@ -120,6 +168,7 @@ func (ct *Cointop) intervalFetchData() { select { case <-ct.refreshticker.C: ct.refreshmux.Lock() + ct.updateCoins() ct.updateTable() ct.updateMarket() ct.updateChart() diff --git a/cointop/navigation.go b/cointop/navigation.go index 2868917..3290219 100644 --- a/cointop/navigation.go +++ b/cointop/navigation.go @@ -50,7 +50,7 @@ func (ct *Cointop) pageDown(g *gocui.Gui, v *gocui.View) error { numRows := len(ct.coins) - 1 _, sy := ct.tableview.Size() rows := sy - if (cy + y + rows) > numRows { + if (cy + +y + rows) > numRows { // go to last row ct.tableview.SetCursor(cx, numRows) ox, _ := ct.tableview.Origin() @@ -88,3 +88,19 @@ func (ct *Cointop) pageUp(g *gocui.Gui, v *gocui.View) error { ct.rowChanged() return nil } + +func (ct *Cointop) prevPage(g *gocui.Gui, v *gocui.View) error { + if (ct.page - 1) >= 0 { + ct.page = ct.page - 1 + } + ct.updateTable() + return nil +} + +func (ct *Cointop) nextPage(g *gocui.Gui, v *gocui.View) error { + if ((ct.page + 1) * ct.perpage) <= len(ct.allcoins) { + ct.page = ct.page + 1 + } + ct.updateTable() + return nil +} diff --git a/cointop/sort.go b/cointop/sort.go index 566ede1..37c5b92 100644 --- a/cointop/sort.go +++ b/cointop/sort.go @@ -3,17 +3,18 @@ package cointop import ( "github.com/bradfitz/slice" "github.com/jroimartin/gocui" + apitypes "github.com/miguelmota/cointop/pkg/api/types" ) -func (ct *Cointop) sort(sortby string, desc bool) { +func (ct *Cointop) sort(sortby string, desc bool, list []*apitypes.Coin) { ct.sortby = sortby ct.sortdesc = desc - slice.Sort(ct.coins[:], func(i, j int) bool { + slice.Sort(list[:], func(i, j int) bool { if ct.sortdesc { i, j = j, i } - a := ct.coins[i] - b := ct.coins[j] + a := list[i] + b := list[j] switch sortby { case "rank": return a.Rank < b.Rank @@ -51,7 +52,7 @@ func (ct *Cointop) sortfn(sortby string, desc bool) func(g *gocui.Gui, v *gocui. desc = !desc } - ct.sort(sortby, desc) + ct.sort(sortby, desc, ct.coins) ct.g.Update(func(g *gocui.Gui) error { ct.tableview.Clear() ct.updateTable() diff --git a/cointop/status.go b/cointop/status.go index 94e97e4..9c2920b 100644 --- a/cointop/status.go +++ b/cointop/status.go @@ -10,7 +10,7 @@ import ( func (ct *Cointop) updateStatus(s string) { maxX, _ := ct.g.Size() ct.statusview.Clear() - fmt.Fprintln(ct.statusview, pad.Right(fmt.Sprintf("[q]uit %s", s), maxX, " ")) + fmt.Fprintln(ct.statusview, pad.Right(fmt.Sprintf("[q]uit [← →]page %s", s), maxX, " ")) } func (ct *Cointop) showLink() { diff --git a/cointop/table.go b/cointop/table.go index 2257162..b5a9adb 100644 --- a/cointop/table.go +++ b/cointop/table.go @@ -89,11 +89,19 @@ func (ct *Cointop) refreshTable() error { func (ct *Cointop) selectedRowIndex() int { _, y := ct.tableview.Origin() _, cy := ct.tableview.Cursor() - return y + cy + idx := y + cy + if idx < 0 { + idx = 0 + } + if idx >= len(ct.coins) { + idx = len(ct.coins) - 1 + } + return idx } func (ct *Cointop) selectedCoin() *apitypes.Coin { - return ct.coins[ct.selectedRowIndex()] + idx := ct.selectedRowIndex() + return ct.coins[idx] } func (ct *Cointop) rowLink() string {