toggle all favorites key

Former-commit-id: c7c0dfa41e55f2bbc020b830e5fda31202f21665 [formerly c7c0dfa41e55f2bbc020b830e5fda31202f21665 [formerly 2987cbea49d6579ccc1a23836b3ca62663fdc1ad [formerly fa2061f891dcad0ef00007704c63b0e91a22cfb1]]]
Former-commit-id: 164a2951369f4098ed14734724a3b5fa97eca15c
Former-commit-id: b7b71b512703f138c33a8cfefefab71980d2e53d [formerly 0da5ddf5bfd603938a926448a8659af0090f88fc]
Former-commit-id: e6d54f8ac9f30141a01017d09d73c038f5ad94f6
pull/15/head
Miguel Mota 6 years ago
parent de3cd565f8
commit 510d761b51

@ -251,7 +251,7 @@ Action|Description
- Q: How often is the data polled?
- A: Data gets polled once every minute by default.
- A: Data gets polled once every minute by default. You can press <kbd>Ctrl</kbd>+<kbd>r</kbd> to force refresh.
- Q: I installed cointop without errors but the command is not found.
@ -269,6 +269,10 @@ Action|Description
- A: The default key to open search is <kbd>/</kbd>. Type the search query after the `/` in the field and hit <kbd>Enter</kbd>.
- Q: Does this work on the Raspberry Pi?
- A: Yes, cointop works on the Rasperry Pi?
## License
Released under the MIT license.

@ -17,6 +17,9 @@ func (ct *Cointop) updateChart() error {
}
coin := ct.selectedCoinName()
ct.chartPoints(maxX, coin)
if len(ct.chartpoints) != 0 {
ct.chartview.Clear()
}
for i := range ct.chartpoints {
var s string
for j := range ct.chartpoints[i] {
@ -25,6 +28,7 @@ func (ct *Cointop) updateChart() error {
}
fmt.Fprintln(ct.chartview, color.White(s))
}
return nil
}
@ -104,10 +108,7 @@ func (ct *Cointop) toggleCoinChart() error {
} else {
ct.selectedcoin = highlightedcoin
}
ct.update(func() {
ct.chartview.Clear()
ct.updateMarketbar()
ct.updateChart()
})
ct.updateChart()
ct.updateMarketbar()
return nil
}

@ -26,7 +26,7 @@ type Cointop struct {
api api.Interface
allcoins []*coin
coins []*coin
allcoinsmap map[string]coin
allcoinsmap map[string]*coin
page int
perpage int
refreshmux sync.Mutex
@ -53,10 +53,6 @@ func Run() {
forcerefresh: make(chan bool),
maxtablewidth: 175,
shortcutkeys: defaultShortcuts(),
favorites: map[string]bool{
"ETH": true,
"ADT": true,
},
}
_ = ct.setupConfig()
g, err := gocui.NewGui(gocui.Output256)
@ -65,7 +61,6 @@ func Run() {
}
ct.g = g
defer g.Close()
g.Cursor = true
g.Mouse = true
g.Highlight = true
g.SetManagerFunc(ct.layout)

@ -1,21 +1,7 @@
package cointop
func (ct *Cointop) toggleShowFavorites() error {
for _, v := range ct.allcoinsmap {
if ct.favorites[v.Symbol] {
v.Favorite = true
}
}
ct.filterByFavorites = !ct.filterByFavorites
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
//ct.updateCoins()
/*
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
ct.rowChanged()
*/
ct.updateTable()
return nil
}

@ -8,60 +8,60 @@ import (
)
func (ct *Cointop) updateHeaders() {
ct.update(func() {
cm := map[string]func(a ...interface{}) string{
"rank": color.Black,
"name": color.Black,
"symbol": color.Black,
"price": color.Black,
"marketcap": color.Black,
"24hvolume": color.Black,
"1hchange": color.Black,
"24hchange": color.Black,
"7dchange": color.Black,
"totalsupply": color.Black,
"availablesupply": color.Black,
"lastupdated": color.Black,
}
sm := map[string]string{
"rank": " ",
"name": " ",
"symbol": " ",
"price": " ",
"marketcap": " ",
"24hvolume": " ",
"1hchange": " ",
"24hchange": " ",
"7dchange": " ",
"totalsupply": " ",
"availablesupply": " ",
"lastupdated": " ",
}
for k := range cm {
if ct.sortby == k {
cm[k] = color.CyanBg
if ct.sortdesc {
sm[k] = "▼"
} else {
sm[k] = "▲"
}
cm := map[string]func(a ...interface{}) string{
"rank": color.Black,
"name": color.Black,
"symbol": color.Black,
"price": color.Black,
"marketcap": color.Black,
"24hvolume": color.Black,
"1hchange": color.Black,
"24hchange": color.Black,
"7dchange": color.Black,
"totalsupply": color.Black,
"availablesupply": color.Black,
"lastupdated": color.Black,
}
sm := map[string]string{
"rank": " ",
"name": " ",
"symbol": " ",
"price": " ",
"marketcap": " ",
"24hvolume": " ",
"1hchange": " ",
"24hchange": " ",
"7dchange": " ",
"totalsupply": " ",
"availablesupply": " ",
"lastupdated": " ",
}
for k := range cm {
if ct.sortby == k {
cm[k] = color.CyanBg
if ct.sortdesc {
sm[k] = "▼"
} else {
sm[k] = "▲"
}
}
headers := []string{
fmt.Sprintf("%s%s", cm["rank"](sm["rank"]+"[r]ank"), strings.Repeat(" ", 1)),
fmt.Sprintf("%s%s", cm["name"](sm["name"]+"[n]ame"), strings.Repeat(" ", 15)),
fmt.Sprintf("%s%s", cm["symbol"](sm["symbol"]+"[s]ymbol"), strings.Repeat(" ", 1)),
fmt.Sprintf("%s%s", strings.Repeat(" ", 1), cm["price"](sm["price"]+"[p]rice")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 5), cm["marketcap"](sm["marketcap"]+"[m]arket cap")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 3), cm["24hvolume"](sm["24hvolume"]+"24H [v]olume")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 4), cm["1hchange"](sm["1hchange"]+"[1]H%")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 3), cm["24hchange"](sm["24hchange"]+"[2]4H%")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 3), cm["7dchange"](sm["7dchange"]+"[7]DH%")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 6), cm["totalsupply"](sm["totalsupply"]+"[t]otal supply")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 1), cm["availablesupply"](sm["availablesupply"]+"[a]vailable supply")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 4), cm["lastupdated"](sm["lastupdated"]+"last [u]pdated")),
}
}
headers := []string{
fmt.Sprintf("%s%s", cm["rank"](sm["rank"]+"[r]ank"), strings.Repeat(" ", 1)),
fmt.Sprintf("%s%s", cm["name"](sm["name"]+"[n]ame"), strings.Repeat(" ", 15)),
fmt.Sprintf("%s%s", cm["symbol"](sm["symbol"]+"[s]ymbol"), strings.Repeat(" ", 1)),
fmt.Sprintf("%s%s", strings.Repeat(" ", 1), cm["price"](sm["price"]+"[p]rice")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 5), cm["marketcap"](sm["marketcap"]+"[m]arket cap")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 3), cm["24hvolume"](sm["24hvolume"]+"24H [v]olume")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 4), cm["1hchange"](sm["1hchange"]+"[1]H%")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 3), cm["24hchange"](sm["24hchange"]+"[2]4H%")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 3), cm["7dchange"](sm["7dchange"]+"[7]DH%")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 6), cm["totalsupply"](sm["totalsupply"]+"[t]otal supply")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 1), cm["availablesupply"](sm["availablesupply"]+"[a]vailable supply")),
fmt.Sprintf("%s%s", strings.Repeat(" ", 4), cm["lastupdated"](sm["lastupdated"]+"last [u]pdated")),
}
ct.update(func() {
ct.headersview.Clear()
fmt.Fprintln(ct.headersview, strings.Join(headers, ""))
})

@ -266,7 +266,6 @@ func (ct *Cointop) keybindings(g *gocui.Gui) error {
view = ""
case "show_favorites":
fn = ct.keyfn(ct.toggleShowFavorites)
view = ""
case "quit":
fn = ct.keyfn(ct.quit)
view = ""

@ -56,7 +56,6 @@ func (ct *Cointop) layout(g *gocui.Gui) error {
ct.tableview.SelFgColor = gocui.ColorBlack
ct.updateCoins()
ct.updateTable()
ct.rowChanged()
}
if v, err := g.SetView("statusbar", 0, maxY-2, ct.maxtablewidth, maxY); err != nil {
@ -102,71 +101,6 @@ func (ct *Cointop) setActiveView(v string) error {
return nil
}
func (ct *Cointop) updateCoins() error {
list := []*coin{}
allcoinsmap, err := ct.api.GetAllCoinData()
if err != nil {
return err
}
if len(ct.allcoinsmap) == 0 {
ct.allcoinsmap = map[string]coin{}
}
for k, v := range allcoinsmap {
ct.allcoinsmap[k] = coin{
ID: v.ID,
Name: v.Name,
Symbol: v.Symbol,
Rank: v.Rank,
PriceUSD: v.PriceUSD,
PriceBTC: v.PriceBTC,
USD24HVolume: v.USD24HVolume,
MarketCapUSD: v.MarketCapUSD,
AvailableSupply: v.AvailableSupply,
TotalSupply: v.TotalSupply,
PercentChange1H: v.PercentChange1H,
PercentChange24H: v.PercentChange24H,
PercentChange7D: v.PercentChange7D,
LastUpdated: v.LastUpdated,
}
}
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 {
// TODO: improve this
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) intervalFetchData() {
go func() {
for {

@ -0,0 +1,70 @@
package cointop
func (ct *Cointop) updateCoins() error {
list := []*coin{}
allcoinsmap, err := ct.api.GetAllCoinData()
if err != nil {
return err
}
if len(ct.allcoinsmap) == 0 {
ct.allcoinsmap = map[string]*coin{}
}
for k, v := range allcoinsmap {
last := ct.allcoinsmap[k]
ct.allcoinsmap[k] = &coin{
ID: v.ID,
Name: v.Name,
Symbol: v.Symbol,
Rank: v.Rank,
PriceUSD: v.PriceUSD,
PriceBTC: v.PriceBTC,
USD24HVolume: v.USD24HVolume,
MarketCapUSD: v.MarketCapUSD,
AvailableSupply: v.AvailableSupply,
TotalSupply: v.TotalSupply,
PercentChange1H: v.PercentChange1H,
PercentChange24H: v.PercentChange24H,
PercentChange7D: v.PercentChange7D,
LastUpdated: v.LastUpdated,
}
if last != nil {
ct.allcoinsmap[k].Favorite = last.Favorite
}
}
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 {
// TODO: improve this
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
c.Favorite = cm.Favorite
}
}
}
}
return nil
}

@ -240,6 +240,5 @@ func (ct *Cointop) goToGlobalIndex(idx int) error {
rowIndex := (idx % perpage)
ct.highlightRow(rowIndex)
ct.updateTable()
ct.rowChanged()
return nil
}

@ -67,12 +67,7 @@ func (ct *Cointop) sortfn(sortby string, desc bool) func(g *gocui.Gui, v *gocui.
}
ct.sort(sortby, desc, ct.coins)
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
ct.rowChanged()
ct.updateTable()
return nil
}
}
@ -89,22 +84,14 @@ func (ct *Cointop) getSortColIndex() int {
func (ct *Cointop) sortAsc() error {
ct.sortdesc = false
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
ct.rowChanged()
ct.updateTable()
return nil
}
func (ct *Cointop) sortDesc() error {
ct.sortdesc = true
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
ct.rowChanged()
ct.updateTable()
return nil
}
@ -117,11 +104,7 @@ func (ct *Cointop) sortPrevCol() error {
}
nextsortby = colorder[k]
ct.sort(nextsortby, ct.sortdesc, ct.coins)
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
ct.rowChanged()
ct.updateTable()
return nil
}
@ -135,10 +118,6 @@ func (ct *Cointop) sortNextCol() error {
}
nextsortby = colorder[k]
ct.sort(nextsortby, ct.sortdesc, ct.coins)
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
ct.rowChanged()
ct.updateTable()
return nil
}

@ -18,7 +18,5 @@ func (ct *Cointop) updateStatusbar(s string) {
func (ct *Cointop) refreshRowLink() {
url := ct.rowLink()
ct.update(func() {
ct.updateStatusbar(fmt.Sprintf("[↵]%s", url))
})
ct.updateStatusbar(fmt.Sprintf("[↵]%s", url))
}

@ -31,10 +31,14 @@ func (ct *Cointop) refreshTable() error {
for _, coin := range ct.coins {
unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64)
lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02")
namecolor := color.White
colorprice := color.Cyan
color1h := color.White
color24h := color.White
color7d := color.White
if coin.Favorite {
namecolor = color.Yellow
}
if coin.PercentChange1H > 0 {
color1h = color.Green
}
@ -61,7 +65,7 @@ func (ct *Cointop) refreshTable() error {
}
ct.table.AddRow(
color.White(fmt.Sprintf("%7v ", coin.Rank)),
color.White(fmt.Sprintf("%.22s", name)),
namecolor(fmt.Sprintf("%.22s", name)),
color.White(fmt.Sprintf("%.6s", coin.Symbol)),
colorprice(fmt.Sprintf("%12s", humanize.Commaf(coin.PriceUSD))),
color.White(fmt.Sprintf("%17s", humanize.Commaf(coin.MarketCapUSD))),
@ -85,26 +89,55 @@ func (ct *Cointop) refreshTable() error {
}
func (ct *Cointop) updateTable() error {
sliced := []*coin{}
for i := range ct.allcoinsmap {
v := ct.allcoinsmap[i]
if ct.favorites[v.Symbol] {
v.Favorite = true
}
}
if ct.filterByFavorites {
for i := range ct.allcoins {
coin := ct.allcoins[i]
if coin.Favorite {
sliced = append(sliced, coin)
}
}
ct.coins = sliced
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
ct.refreshTable()
return nil
}
start := ct.page * ct.perpage
end := start + ct.perpage
if start >= len(ct.allCoins())-1 {
allcoins := ct.allCoins()
size := len(allcoins)
if start < 0 {
start = 0
}
if end >= len(ct.allCoins())-1 {
if end >= size-1 {
start = int(math.Floor(float64(start/100)) * 100)
end = len(ct.allCoins()) - 1
end = size - 1
}
if start < 0 {
start = 0
}
if end >= len(ct.allCoins()) {
end = len(ct.allCoins()) - 1
if end >= size {
end = size - 1
}
if end < 0 {
end = 0
}
if end > 0 {
sliced = allcoins[start:end]
}
sliced := ct.allCoins()[start:end]
ct.coins = sliced
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
ct.refreshTable()
ct.rowChanged()
return nil
}
@ -123,11 +156,18 @@ func (ct *Cointop) highlightedRowIndex() int {
func (ct *Cointop) highlightedRowCoin() *coin {
idx := ct.highlightedRowIndex()
if len(ct.coins) == 0 {
return nil
}
return ct.coins[idx]
}
func (ct *Cointop) rowLink() string {
slug := strings.ToLower(strings.Replace(ct.highlightedRowCoin().Name, " ", "-", -1))
coin := ct.highlightedRowCoin()
if coin == nil {
return ""
}
slug := strings.ToLower(strings.Replace(coin.Name, " ", "-", -1))
return fmt.Sprintf("https://coinmarketcap.com/currencies/%s", slug)
}

@ -9,6 +9,8 @@ var (
White = color.New(color.FgWhite).SprintFunc()
// WhiteBold bold
WhiteBold = color.New(color.FgWhite, color.Bold).SprintFunc()
// Yellow color
Yellow = color.New(color.FgYellow).SprintFunc()
// Green color
Green = color.New(color.FgGreen).SprintFunc()
// GreenBg color

Loading…
Cancel
Save