update readme

Former-commit-id: ccea1b0ad248391b508bc6dac0e894ed994491ae [formerly ccea1b0ad248391b508bc6dac0e894ed994491ae [formerly c5c47d529e0cf90f3b07da2090d74b9c4609eebe [formerly c887d55c837c8230cce47ba1a583b4c833822556]]]
Former-commit-id: 5fbc1e75381842caee7efab123e972ea77b8507c
Former-commit-id: 1ec1f2f5342405fb8eca886b37714c0a728c3c67 [formerly f602aebf3502f6d633f0ea5d51eed52fa9d8c139]
Former-commit-id: 85eab98aafbb804b179cf4acb381a764e0f95767
pull/15/head
Miguel Mota 6 years ago
parent 222d4c6804
commit 4892bd2fad

@ -5,7 +5,6 @@ import (
"time"
"github.com/gizak/termui"
"github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/pkg/color"
)
@ -98,14 +97,14 @@ func (ct *Cointop) selectedCoinName() string {
return ""
}
func (ct *Cointop) toggleCoinChart(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) toggleCoinChart() error {
highlightedcoin := ct.highlightedRowCoin()
if ct.selectedcoin == highlightedcoin {
ct.selectedcoin = nil
} else {
ct.selectedcoin = highlightedcoin
}
ct.Update(func() {
ct.update(func() {
ct.chartview.Clear()
ct.updateMarketbar()
ct.updateChart()

@ -37,6 +37,7 @@ type Cointop struct {
maxtablewidth int
shortcutkeys map[string]string
config config // toml config
searchfield *gocui.View
}
// Run runs cointop
@ -71,11 +72,6 @@ func Run() {
}
}
func (ct *Cointop) quit(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) quit() error {
return gocui.ErrQuit
}
func (ct *Cointop) refresh(g *gocui.Gui, v *gocui.View) error {
ct.forcerefresh <- true
return nil
}

@ -8,7 +8,7 @@ import (
)
func (ct *Cointop) updateHeaders() {
ct.Update(func() {
ct.update(func() {
cm := map[string]func(a ...interface{}) string{
"rank": color.Black,
"name": color.Black,

@ -1,12 +1,11 @@
package cointop
import (
"github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/pkg/open"
)
// TODO: create a help menu
func (ct *Cointop) openHelp(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) openHelp() error {
open.URL(ct.helpLink())
return nil
}

@ -192,41 +192,43 @@ func (ct *Cointop) keybindings(g *gocui.Gui) error {
v = strings.TrimSpace(strings.ToLower(v))
var fn func(g *gocui.Gui, v *gocui.View) error
key, mod := ct.parseKeys(k)
view := "table"
switch v {
case "move_up":
fn = ct.cursorUp
fn = ct.keyfn(ct.cursorUp)
case "move_down":
fn = ct.cursorDown
fn = ct.keyfn(ct.cursorDown)
case "previous_page":
fn = ct.prevPage
fn = ct.keyfn(ct.prevPage)
case "next_page":
fn = ct.nextPage
fn = ct.keyfn(ct.nextPage)
case "page_down":
fn = ct.pageDown
fn = ct.keyfn(ct.pageDown)
case "page_up":
fn = ct.pageUp
fn = ct.keyfn(ct.pageUp)
case "sort_column_symbol":
fn = ct.sortfn("symbol", false)
case "move_to_page_first_row":
fn = ct.navigateFirstLine
fn = ct.keyfn(ct.navigateFirstLine)
case "move_to_page_last_row":
fn = ct.navigateLastLine
fn = ct.keyfn(ct.navigateLastLine)
case "open_link":
fn = ct.openLink
fn = ct.keyfn(ct.openLink)
case "refresh":
fn = ct.refresh
fn = ct.keyfn(ct.refresh)
case "sort_column_asc":
fn = ct.sortAsc
fn = ct.keyfn(ct.sortAsc)
case "sort_column_desc":
fn = ct.sortDesc
fn = ct.keyfn(ct.sortDesc)
case "sort_left_column":
fn = ct.sortPrevCol
fn = ct.keyfn(ct.sortPrevCol)
case "sort_right_column":
fn = ct.sortNextCol
fn = ct.keyfn(ct.sortNextCol)
case "help":
fn = ct.openHelp
fn = ct.keyfn(ct.openHelp)
view = ""
case "first_page":
fn = ct.firstPage
fn = ct.keyfn(ct.firstPage)
case "sort_column_1h_change":
fn = ct.sortfn("1hchange", true)
case "sort_column_24h_change":
@ -236,15 +238,15 @@ func (ct *Cointop) keybindings(g *gocui.Gui) error {
case "sort_column_available_supply":
fn = ct.sortfn("availablesupply", true)
case "toggle_row_chart":
fn = ct.toggleCoinChart
fn = ct.keyfn(ct.toggleCoinChart)
case "move_to_page_visible_first_row":
fn = ct.navigatePageFirstLine
fn = ct.keyfn(ct.navigatePageFirstLine)
case "move_to_page_visible_last_row":
fn = ct.navigatePageLastLine
fn = ct.keyfn(ct.navigatePageLastLine)
case "sort_column_market_cap":
fn = ct.sortfn("marketcap", true)
case "move_to_page_visible_middle_row":
fn = ct.navigatePageMiddleLine
fn = ct.keyfn(ct.navigatePageMiddleLine)
case "sort_column_name":
fn = ct.sortfn("name", true)
case "sort_column_price":
@ -258,30 +260,42 @@ func (ct *Cointop) keybindings(g *gocui.Gui) error {
case "sort_column_24h_volume":
fn = ct.sortfn("24hvolume", true)
case "last_page":
fn = ct.lastPage
fn = ct.keyfn(ct.lastPage)
case "quit":
fn = ct.quit
fn = ct.keyfn(ct.quit)
view = ""
case "open_search":
fn = ct.keyfn(ct.openSearch)
view = ""
default:
fn = keynoop
fn = ct.keyfn(ct.noop)
}
ct.setKeybindingMod(key, mod, fn)
ct.setKeybindingMod(key, mod, fn, view)
}
ct.setKeybindingMod(gocui.KeyEnter, gocui.ModNone, ct.keyfn(ct.doSearch), "searchfield")
ct.setKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.keyfn(ct.cancelSearch), "searchfield")
return nil
}
func (ct *Cointop) setKeybindingMod(key interface{}, mod gocui.Modifier, callback func(g *gocui.Gui, v *gocui.View) error) error {
func (ct *Cointop) setKeybindingMod(key interface{}, mod gocui.Modifier, callback func(g *gocui.Gui, v *gocui.View) error, view string) error {
var err error
switch t := key.(type) {
case gocui.Key:
err = ct.g.SetKeybinding("", t, mod, callback)
err = ct.g.SetKeybinding(view, t, mod, callback)
case rune:
err = ct.g.SetKeybinding("", t, mod, callback)
err = ct.g.SetKeybinding(view, t, mod, callback)
}
return err
}
func keynoop(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) keyfn(fn func() error) func(g *gocui.Gui, v *gocui.View) error {
return func(g *gocui.Gui, v *gocui.View) error {
return fn()
}
}
func (ct *Cointop) noop() error {
return nil
}

@ -1,6 +1,7 @@
package cointop
import (
"fmt"
"math"
"github.com/jroimartin/gocui"
@ -71,7 +72,35 @@ func (ct *Cointop) layout(g *gocui.Gui) error {
ct.updateStatusbar("")
}
ct.intervalFetchData()
if v, err := g.SetView("searchfield", 0, maxY-2, ct.maxtablewidth, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.searchfield = v
ct.searchfield.Editable = true
ct.searchfield.Wrap = true
ct.searchfield.Frame = false
ct.searchfield.FgColor = gocui.ColorWhite
// run only once on init
ct.g = g
g.SetViewOnBottom("searchfield")
ct.setActiveView("table")
ct.intervalFetchData()
}
return nil
}
func (ct *Cointop) setActiveView(v string) error {
ct.g.SetViewOnTop(v)
ct.g.SetCurrentView(v)
if v == "searchfield" {
ct.searchfield.Clear()
ct.searchfield.SetCursor(1, 0)
fmt.Fprintf(ct.searchfield, "%s", "/")
} else if v == "table" {
ct.g.SetViewOnTop("statusbar")
}
return nil
}

@ -19,7 +19,7 @@ func (ct *Cointop) updateMarketbar() error {
if chartname == "" {
chartname = "Global"
}
ct.Update(func() {
ct.update(func() {
ct.marketview.Clear()
fmt.Fprintln(
ct.marketview,

@ -1,9 +1,5 @@
package cointop
import (
"github.com/jroimartin/gocui"
)
func (ct *Cointop) getCurrentPage() int {
return ct.page + 1
}
@ -12,11 +8,28 @@ func (ct *Cointop) getTotalPages() int {
return (ct.getListCount() / ct.perpage) + 1
}
func (ct *Cointop) getTotalPerPage() int {
return ct.perpage
}
func (ct *Cointop) getListCount() int {
return len(ct.allcoins)
}
func (ct *Cointop) cursorDown(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) setPage(page int) int {
if (page*ct.perpage) <= ct.getListCount() && page >= 0 {
ct.page = page
}
return ct.page
}
func (ct *Cointop) highlightRow(idx int) error {
cx, _ := ct.tableview.Cursor()
ct.tableview.SetCursor(cx, idx)
return nil
}
func (ct *Cointop) cursorDown() error {
if ct.tableview == nil {
return nil
}
@ -37,7 +50,7 @@ func (ct *Cointop) cursorDown(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) cursorUp(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) cursorUp() error {
if ct.tableview == nil {
return nil
}
@ -53,7 +66,7 @@ func (ct *Cointop) cursorUp(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) pageDown(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) pageDown() error {
if ct.tableview == nil {
return nil
}
@ -79,7 +92,7 @@ func (ct *Cointop) pageDown(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) pageUp(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) pageUp() error {
if ct.tableview == nil {
return nil
}
@ -103,7 +116,7 @@ func (ct *Cointop) pageUp(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) navigateFirstLine(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) navigateFirstLine() error {
if ct.tableview == nil {
return nil
}
@ -119,7 +132,7 @@ func (ct *Cointop) navigateFirstLine(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) navigateLastLine(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) navigateLastLine() error {
if ct.tableview == nil {
return nil
}
@ -138,7 +151,7 @@ func (ct *Cointop) navigateLastLine(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) navigatePageFirstLine(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) navigatePageFirstLine() error {
if ct.tableview == nil {
return nil
}
@ -150,7 +163,7 @@ func (ct *Cointop) navigatePageFirstLine(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) navigatePageMiddleLine(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) navigatePageMiddleLine() error {
if ct.tableview == nil {
return nil
}
@ -163,7 +176,7 @@ func (ct *Cointop) navigatePageMiddleLine(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) navigatePageLastLine(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) navigatePageLastLine() error {
if ct.tableview == nil {
return nil
}
@ -176,32 +189,28 @@ func (ct *Cointop) navigatePageLastLine(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) prevPage(g *gocui.Gui, v *gocui.View) error {
if (ct.page - 1) >= 0 {
ct.page = ct.page - 1
}
func (ct *Cointop) prevPage() error {
ct.setPage(ct.page - 1)
ct.updateTable()
ct.rowChanged()
return nil
}
func (ct *Cointop) nextPage(g *gocui.Gui, v *gocui.View) error {
if ((ct.page + 1) * ct.perpage) <= ct.getListCount() {
ct.page = ct.page + 1
}
func (ct *Cointop) nextPage() error {
ct.setPage(ct.page + 1)
ct.updateTable()
ct.rowChanged()
return nil
}
func (ct *Cointop) firstPage(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) firstPage() error {
ct.page = 0
ct.updateTable()
ct.rowChanged()
return nil
}
func (ct *Cointop) lastPage(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) lastPage() error {
ct.page = ct.getListCount() / ct.perpage
ct.updateTable()
ct.rowChanged()

@ -5,6 +5,11 @@ import (
"time"
)
func (ct *Cointop) refresh() error {
ct.forcerefresh <- true
return nil
}
func (ct *Cointop) refreshAll() error {
ct.refreshmux.Lock()
ct.setRefreshStatus()

@ -0,0 +1,62 @@
package cointop
import (
"log"
"regexp"
"strings"
)
func (ct *Cointop) openSearch() error {
ct.setActiveView("searchfield")
return nil
}
func (ct *Cointop) cancelSearch() error {
ct.setActiveView("table")
return nil
}
func (ct *Cointop) doSearch() error {
ct.searchfield.Rewind()
b := make([]byte, 100)
n, err := ct.searchfield.Read(b)
defer ct.setActiveView("table")
if err != nil {
return nil
}
if n == 0 {
return nil
}
q := string(b)
// remove slash
regex := regexp.MustCompile(`/(.*)`)
matches := regex.FindStringSubmatch(q)
if len(matches) > 0 {
q = matches[1]
}
return ct.search(q)
}
func (ct *Cointop) search(q string) error {
q = strings.TrimSpace(strings.ToLower(q))
for i := range ct.allcoins {
coin := ct.allcoins[i]
if strings.ToLower(coin.Name) == q || strings.ToLower(coin.Symbol) == q {
ct.goToGlobalIndex(i)
return nil
}
}
return nil
}
func (ct *Cointop) goToGlobalIndex(idx int) error {
perpage := ct.getTotalPerPage()
atpage := idx / perpage
ct.setPage(atpage)
rowIndex := (idx % perpage)
ct.highlightRow(rowIndex)
log.Println(rowIndex)
ct.updateTable()
ct.rowChanged()
return nil
}

@ -36,6 +36,7 @@ func actionsMap() map[string]bool {
"sort_left_column": true,
"sort_right_column": true,
"toggle_row_chart": true,
"open_search": true,
}
}
@ -90,5 +91,6 @@ func defaultShortcuts() map[string]string {
"q": "quit",
"$": "last_page",
"?": "help",
"/": "open_search",
}
}

@ -68,7 +68,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.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
@ -87,10 +87,10 @@ func (ct *Cointop) getSortColIndex() int {
return 0
}
func (ct *Cointop) sortAsc(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) sortAsc() error {
ct.sortdesc = false
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
ct.Update(func() {
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
@ -98,10 +98,10 @@ func (ct *Cointop) sortAsc(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) sortDesc(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) sortDesc() error {
ct.sortdesc = true
ct.sort(ct.sortby, ct.sortdesc, ct.coins)
ct.Update(func() {
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
@ -109,7 +109,7 @@ func (ct *Cointop) sortDesc(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) sortPrevCol(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) sortPrevCol() error {
nextsortby := colorder[0]
i := ct.getSortColIndex()
k := i - 1
@ -118,7 +118,7 @@ func (ct *Cointop) sortPrevCol(g *gocui.Gui, v *gocui.View) error {
}
nextsortby = colorder[k]
ct.sort(nextsortby, ct.sortdesc, ct.coins)
ct.Update(func() {
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})
@ -126,7 +126,7 @@ func (ct *Cointop) sortPrevCol(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (ct *Cointop) sortNextCol(g *gocui.Gui, v *gocui.View) error {
func (ct *Cointop) sortNextCol() error {
nextsortby := colorder[0]
l := len(colorder)
i := ct.getSortColIndex()
@ -136,7 +136,7 @@ func (ct *Cointop) sortNextCol(g *gocui.Gui, v *gocui.View) error {
}
nextsortby = colorder[k]
ct.sort(nextsortby, ct.sortdesc, ct.coins)
ct.Update(func() {
ct.update(func() {
ct.tableview.Clear()
ct.updateTable()
})

@ -7,7 +7,7 @@ import (
)
func (ct *Cointop) updateStatusbar(s string) {
ct.Update(func() {
ct.update(func() {
ct.statusbarview.Clear()
currpage := ct.getCurrentPage()
totalpages := ct.getTotalPages()
@ -18,7 +18,7 @@ func (ct *Cointop) updateStatusbar(s string) {
func (ct *Cointop) refreshRowLink() {
url := ct.rowLink()
ct.Update(func() {
ct.update(func() {
ct.updateStatusbar(fmt.Sprintf("[↵]%s", url))
})
}

@ -6,11 +6,9 @@ import (
"strings"
"time"
"github.com/jroimartin/gocui"
apt "github.com/miguelmota/cointop/pkg/api/types"
"github.com/miguelmota/cointop/pkg/color"
"github.com/miguelmota/cointop/pkg/humanize"
"github.com/miguelmota/cointop/pkg/open"
"github.com/miguelmota/cointop/pkg/table"
)
@ -78,7 +76,7 @@ func (ct *Cointop) refreshTable() error {
)
}
ct.Update(func() {
ct.update(func() {
ct.tableview.Clear()
ct.table.Format().Fprint(ct.tableview)
})
@ -108,8 +106,3 @@ func (ct *Cointop) rowLink() string {
slug := strings.ToLower(strings.Replace(ct.highlightedRowCoin().Name, " ", "-", -1))
return fmt.Sprintf("https://coinmarketcap.com/currencies/%s", slug)
}
func (ct *Cointop) openLink(g *gocui.Gui, v *gocui.View) error {
open.URL(ct.rowLink())
return nil
}

@ -2,8 +2,8 @@ package cointop
import "github.com/jroimartin/gocui"
// Update update view
func (ct *Cointop) Update(f func()) {
// update update view
func (ct *Cointop) update(f func()) {
ct.g.Update(func(g *gocui.Gui) error {
f()
return nil

@ -0,0 +1,8 @@
package cointop
import "github.com/miguelmota/cointop/pkg/open"
func (ct *Cointop) openLink() error {
open.URL(ct.rowLink())
return nil
}
Loading…
Cancel
Save