add pagination

Former-commit-id: 8ca367e69d32d36e90c101e2c59bd1609b9b7ac0 [formerly 8ca367e69d32d36e90c101e2c59bd1609b9b7ac0 [formerly c072643cade74f2f07698daffd7009579eade69d [formerly 7b8c08e0cf]]]
Former-commit-id: f924ab003eb325c4c754a3aac97eff81836fbb67
Former-commit-id: b8c5df995b0ec7f95b3457264433ea65567cc6f3 [formerly 6f120209f2a5531b584a246f3eb9aa4d23532866]
Former-commit-id: 9a63835ebcc7cbaa7e5a8896700d2c74d652b6d2
pull/15/head
Miguel Mota 6 years ago
parent d3cbd8b415
commit dd7ae7e4b1

@ -38,6 +38,8 @@ List of shortcuts:
|----|------| |----|------|
|`<up>`|navigate up| |`<up>`|navigate up|
|`<down>`|navigate down| |`<down>`|navigate down|
|`<right>`|next page|
|`<left>`|previous page|
|`<ctrl-u>`|page up| |`<ctrl-u>`|page up|
|`<ctrl-d>`|page down| |`<ctrl-d>`|page down|
|`<enter>`|visit highlighted coin on CoinMarketCap| |`<enter>`|visit highlighted coin on CoinMarketCap|

@ -1 +1 @@
8581fe52805451f3f959248757480db12e4a3b0d ed65aa79a4f28f144b4b21c2481224f0466a5181

@ -1 +1 @@
5a10db031042fc4de090c186e9870f60510e4d68 7410bf82087f7933ba1f4b27e49187dca72d6436

@ -34,8 +34,11 @@ type Cointop struct {
sortdesc bool sortdesc bool
sortby string sortby string
api api.Interface api api.Interface
allcoins []*apitypes.Coin
coins []*apitypes.Coin coins []*apitypes.Coin
coinsmap map[string]apitypes.Coin allcoinsmap map[string]apitypes.Coin
page int
perpage int
refreshmux sync.Mutex refreshmux sync.Mutex
refreshticker *time.Ticker refreshticker *time.Ticker
} }
@ -54,6 +57,10 @@ func Run() {
g: g, g: g,
api: api.NewCMC(), api: api.NewCMC(),
refreshticker: time.NewTicker(1 * time.Minute), refreshticker: time.NewTicker(1 * time.Minute),
sortby: "rank",
sortdesc: false,
page: 0,
perpage: 100,
} }
g.SetManagerFunc(ct.layout) g.SetManagerFunc(ct.layout)
if err := ct.keybindings(g); err != nil { if err := ct.keybindings(g); err != nil {

@ -21,6 +21,8 @@ func (ct *Cointop) setKeybinding(key interface{}, callback func(g *gocui.Gui, v
} }
func (ct *Cointop) keybindings(g *gocui.Gui) error { 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(gocui.KeyArrowDown, ct.cursorDown)
ct.setKeybinding('j', ct.cursorDown) ct.setKeybinding('j', ct.cursorDown)
ct.setKeybinding(gocui.KeyArrowUp, ct.cursorUp) ct.setKeybinding(gocui.KeyArrowUp, ct.cursorUp)

@ -1,6 +1,8 @@
package cointop package cointop
import ( import (
"math"
"github.com/jroimartin/gocui" "github.com/jroimartin/gocui"
apitypes "github.com/miguelmota/cointop/pkg/api/types" apitypes "github.com/miguelmota/cointop/pkg/api/types"
"github.com/miguelmota/cointop/pkg/pad" "github.com/miguelmota/cointop/pkg/pad"
@ -75,8 +77,8 @@ func (ct *Cointop) layout(g *gocui.Gui) error {
ct.tableview.Highlight = true ct.tableview.Highlight = true
ct.tableview.SelBgColor = gocui.ColorCyan ct.tableview.SelBgColor = gocui.ColorCyan
ct.tableview.SelFgColor = gocui.ColorBlack ct.tableview.SelFgColor = gocui.ColorBlack
ct.updateCoins()
ct.updateTable() ct.updateTable()
ct.sort("rank", false)
ct.rowChanged() ct.rowChanged()
} }
@ -95,21 +97,67 @@ func (ct *Cointop) layout(g *gocui.Gui) error {
return nil return nil
} }
func (ct *Cointop) updateTable() error { func (ct *Cointop) updateCoins() error {
list := []*apitypes.Coin{} list := []*apitypes.Coin{}
coinsmap, err := ct.api.GetAllCoinData() allcoinsmap, err := ct.api.GetAllCoinData()
if err != nil { if err != nil {
return err return err
} }
ct.coinsmap = coinsmap ct.allcoinsmap = allcoinsmap
for i := range ct.coinsmap { if len(ct.allcoins) == 0 {
coin := ct.coinsmap[i] for i := range ct.allcoinsmap {
list = append(list, &coin) 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 sliced := ct.allcoins[start:end]
ct.sort(ct.sortby, ct.sortdesc) ct.coins = sliced
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
ct.refreshTable() ct.refreshTable()
return nil return nil
} }
@ -120,6 +168,7 @@ func (ct *Cointop) intervalFetchData() {
select { select {
case <-ct.refreshticker.C: case <-ct.refreshticker.C:
ct.refreshmux.Lock() ct.refreshmux.Lock()
ct.updateCoins()
ct.updateTable() ct.updateTable()
ct.updateMarket() ct.updateMarket()
ct.updateChart() ct.updateChart()

@ -50,7 +50,7 @@ func (ct *Cointop) pageDown(g *gocui.Gui, v *gocui.View) error {
numRows := len(ct.coins) - 1 numRows := len(ct.coins) - 1
_, sy := ct.tableview.Size() _, sy := ct.tableview.Size()
rows := sy rows := sy
if (cy + y + rows) > numRows { if (cy + +y + rows) > numRows {
// go to last row // go to last row
ct.tableview.SetCursor(cx, numRows) ct.tableview.SetCursor(cx, numRows)
ox, _ := ct.tableview.Origin() ox, _ := ct.tableview.Origin()
@ -88,3 +88,19 @@ func (ct *Cointop) pageUp(g *gocui.Gui, v *gocui.View) error {
ct.rowChanged() ct.rowChanged()
return nil 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
}

@ -3,17 +3,18 @@ package cointop
import ( import (
"github.com/bradfitz/slice" "github.com/bradfitz/slice"
"github.com/jroimartin/gocui" "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.sortby = sortby
ct.sortdesc = desc ct.sortdesc = desc
slice.Sort(ct.coins[:], func(i, j int) bool { slice.Sort(list[:], func(i, j int) bool {
if ct.sortdesc { if ct.sortdesc {
i, j = j, i i, j = j, i
} }
a := ct.coins[i] a := list[i]
b := ct.coins[j] b := list[j]
switch sortby { switch sortby {
case "rank": case "rank":
return a.Rank < b.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 desc = !desc
} }
ct.sort(sortby, desc) ct.sort(sortby, desc, ct.coins)
ct.g.Update(func(g *gocui.Gui) error { ct.g.Update(func(g *gocui.Gui) error {
ct.tableview.Clear() ct.tableview.Clear()
ct.updateTable() ct.updateTable()

@ -10,7 +10,7 @@ import (
func (ct *Cointop) updateStatus(s string) { func (ct *Cointop) updateStatus(s string) {
maxX, _ := ct.g.Size() maxX, _ := ct.g.Size()
ct.statusview.Clear() 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() { func (ct *Cointop) showLink() {

@ -89,11 +89,19 @@ func (ct *Cointop) refreshTable() error {
func (ct *Cointop) selectedRowIndex() int { func (ct *Cointop) selectedRowIndex() int {
_, y := ct.tableview.Origin() _, y := ct.tableview.Origin()
_, cy := ct.tableview.Cursor() _, 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 { func (ct *Cointop) selectedCoin() *apitypes.Coin {
return ct.coins[ct.selectedRowIndex()] idx := ct.selectedRowIndex()
return ct.coins[idx]
} }
func (ct *Cointop) rowLink() string { func (ct *Cointop) rowLink() string {

Loading…
Cancel
Save