summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Mota <miguelmota2@gmail.com>2021-02-20 00:51:08 -0800
committerMiguel Mota <miguelmota2@gmail.com>2021-02-20 00:52:06 -0800
commit0a0530de5a6829159fbbaccf9605da94864c7121 (patch)
treeca02bd3f98490913751191a75643a17cebcb0460
parent269b9ad5b79d08b8cecde36eb143b766966deb53 (diff)
Add option to keep row focus on sortv1.6.2
-rw-r--r--cointop/cointop.go3
-rw-r--r--cointop/config.go19
-rw-r--r--cointop/navigation.go84
-rw-r--r--cointop/sort.go13
-rw-r--r--cointop/table.go14
-rw-r--r--pkg/api/impl/coingecko/coingecko.go2
-rw-r--r--pkg/chartplot/chartplot.go3
7 files changed, 104 insertions, 34 deletions
diff --git a/cointop/cointop.go b/cointop/cointop.go
index 0e54335..56428e3 100644
--- a/cointop/cointop.go
+++ b/cointop/cointop.go
@@ -53,6 +53,7 @@ type State struct {
hideMarketbar bool
hideChart bool
hideStatusbar bool
+ keepRowFocusOnSort bool
lastSelectedRowIndex int
marketBarHeight int
page int
@@ -197,6 +198,7 @@ func NewCointop(config *Config) (*Cointop, error) {
}
ct := &Cointop{
+ // defaults
apiChoice: CoinGecko,
apiKeys: new(APIKeys),
forceRefresh: make(chan bool),
@@ -222,6 +224,7 @@ func NewCointop(config *Config) (*Cointop, error) {
hideMarketbar: config.HideMarketbar,
hideChart: config.HideChart,
hideStatusbar: config.HideStatusbar,
+ keepRowFocusOnSort: false,
marketBarHeight: 1,
onlyTable: config.OnlyTable,
refreshRate: 60 * time.Second,
diff --git a/cointop/config.go b/cointop/config.go
index 4ef1e46..e8445b7 100644
--- a/cointop/config.go
+++ b/cointop/config.go
@@ -54,7 +54,7 @@ func (ct *Cointop) SetupConfig() error {
if err := ct.parseConfig(); err != nil {
return err
}
- if err := ct.loadTableColumnsFromConfig(); err != nil {
+ if err := ct.loadTableConfig(); err != nil {
return err
}
if err := ct.loadShortcutsFromConfig(); err != nil {
@@ -280,6 +280,8 @@ func (ct *Cointop) configToToml() ([]byte, error) {
var coinsTableColumnsIfc interface{} = ct.State.coinsTableColumns
tableMapIfc := map[string]interface{}{}
tableMapIfc["columns"] = coinsTableColumnsIfc
+ var keepRowFocusOnSortIfc interface{} = ct.State.keepRowFocusOnSort
+ tableMapIfc["keep_row_focus_on_sort"] = keepRowFocusOnSortIfc
var inputs = &config{
API: apiChoiceIfc,
@@ -306,6 +308,20 @@ func (ct *Cointop) configToToml() ([]byte, error) {
return b.Bytes(), nil
}
+// LoadTableConfig loads table config from toml config into state struct
+func (ct *Cointop) loadTableConfig() error {
+ err := ct.loadTableColumnsFromConfig()
+ if err != nil {
+ return err
+ }
+
+ keepRowFocusOnSortIfc, ok := ct.config.Table["keep_row_focus_on_sort"]
+ if ok {
+ ct.State.keepRowFocusOnSort = keepRowFocusOnSortIfc.(bool)
+ }
+ return nil
+}
+
// LoadTableColumnsFromConfig loads preferred coins table columns from config file to struct
func (ct *Cointop) loadTableColumnsFromConfig() error {
ct.debuglog("loadTableColumnsFromConfig()")
@@ -328,6 +344,7 @@ func (ct *Cointop) loadTableColumnsFromConfig() error {
ct.State.coinsTableColumns = columns
}
}
+
return nil
}
diff --git a/cointop/navigation.go b/cointop/navigation.go
index cbd9622..92db9a1 100644
--- a/cointop/navigation.go
+++ b/cointop/navigation.go
@@ -1,6 +1,7 @@
package cointop
import (
+ "fmt"
"math"
)
@@ -45,7 +46,7 @@ func (ct *Cointop) SetPage(page int) int {
// CursorDown moves the cursor one row down
func (ct *Cointop) CursorDown() error {
ct.debuglog("cursorDown()")
- // NOTE: return if already at the bottom
+ // return if already at the bottom
if ct.IsLastRow() {
return nil
}
@@ -65,7 +66,7 @@ func (ct *Cointop) CursorDown() error {
// CursorUp moves the cursor one row up
func (ct *Cointop) CursorUp() error {
ct.debuglog("cursorUp()")
- // NOTE: return if already at the top
+ // return if already at the top
if ct.IsFirstRow() {
return nil
}
@@ -86,7 +87,7 @@ func (ct *Cointop) CursorUp() error {
// PageDown moves the cursor one page down
func (ct *Cointop) PageDown() error {
ct.debuglog("pageDown()")
- // NOTE: return if already at the bottom
+ // return if already at the bottom
if ct.IsLastRow() {
return nil
}
@@ -94,24 +95,24 @@ func (ct *Cointop) PageDown() error {
ox, oy := ct.Views.Table.Origin() // this is prev origin position
cx := ct.Views.Table.CursorX() // relative cursor position
sy := ct.Views.Table.Height() // rows in visible view
- k := oy + sy
+ y := oy + sy
l := ct.TableRowsLen()
// end of table
if (oy + sy + sy) > l {
- k = l - sy
+ y = l - sy
}
// select last row if next jump is out of bounds
- if k < 0 {
- k = 0
+ if y < 0 {
+ y = 0
sy = l
}
- if err := ct.Views.Table.SetOrigin(ox, k); err != nil {
+ if err := ct.Views.Table.SetOrigin(ox, y); err != nil {
return err
}
// move cursor to last line if can't scroll further
- if k == oy {
+ if y == oy {
if err := ct.Views.Table.SetCursor(cx, sy-1); err != nil {
return err
}
@@ -123,7 +124,7 @@ func (ct *Cointop) PageDown() error {
// PageUp moves the cursor one page up
func (ct *Cointop) PageUp() error {
ct.debuglog("pageUp()")
- // NOTE: return if already at the top
+ // return if already at the top
if ct.IsFirstRow() {
return nil
}
@@ -151,7 +152,7 @@ func (ct *Cointop) PageUp() error {
// NavigateFirstLine moves the cursor to the first row of the table
func (ct *Cointop) NavigateFirstLine() error {
ct.debuglog("navigateFirstLine()")
- // NOTE: return if already at the top
+ // return if already at the top
if ct.IsFirstRow() {
return nil
}
@@ -172,7 +173,7 @@ func (ct *Cointop) NavigateFirstLine() error {
// NavigateLastLine moves the cursor to the last row of the table
func (ct *Cointop) NavigateLastLine() error {
ct.debuglog("navigateLastLine()")
- // NOTE: return if already at the bottom
+ // return if already at the bottom
if ct.IsLastRow() {
return nil
}
@@ -196,7 +197,7 @@ func (ct *Cointop) NavigateLastLine() error {
// NavigatePageFirstLine moves the cursor to the visible first row of the table
func (ct *Cointop) NavigatePageFirstLine() error {
ct.debuglog("navigatePageFirstLine()")
- // NOTE: return if already at the correct line
+ // return if already at the correct line
if ct.IsPageFirstLine() {
return nil
}
@@ -212,7 +213,7 @@ func (ct *Cointop) NavigatePageFirstLine() error {
// NavigatePageMiddleLine moves the cursor to the visible middle row of the table
func (ct *Cointop) NavigatePageMiddleLine() error {
ct.debuglog("navigatePageMiddleLine()")
- // NOTE: return if already at the correct line
+ // return if already at the correct line
if ct.IsPageMiddleLine() {
return nil
}
@@ -229,7 +230,7 @@ func (ct *Cointop) NavigatePageMiddleLine() error {
// NavigatePageLastLine moves the cursor to the visible last row of the table
func (ct *Cointop) navigatePageLastLine() error {
ct.debuglog("navigatePageLastLine()")
- // NOTE: return if already at the correct line
+ // return if already at the correct line
if ct.IsPageLastLine() {
return nil
}
@@ -247,7 +248,7 @@ func (ct *Cointop) navigatePageLastLine() error {
func (ct *Cointop) NextPage() error {
ct.debuglog("nextPage()")
- // NOTE: return if already at the last page
+ // return if already at the last page
if ct.IsLastPage() {
return nil
}
@@ -262,7 +263,7 @@ func (ct *Cointop) NextPage() error {
func (ct *Cointop) PrevPage() error {
ct.debuglog("prevPage()")
- // NOTE: return if already at the first page
+ // return if already at the first page
if ct.IsFirstPage() {
return nil
}
@@ -297,7 +298,7 @@ func (ct *Cointop) PrevPageTop() error {
func (ct *Cointop) FirstPage() error {
ct.debuglog("firstPage()")
- // NOTE: return if already at the first page
+ // return if already at the first page
if ct.IsFirstPage() {
return nil
}
@@ -312,7 +313,7 @@ func (ct *Cointop) FirstPage() error {
func (ct *Cointop) LastPage() error {
ct.debuglog("lastPage()")
- // NOTE: return if already at the last page
+ // return if already at the last page
if ct.IsLastPage() {
return nil
}
@@ -402,26 +403,57 @@ func (ct *Cointop) GoToGlobalIndex(idx int) error {
return nil
}
-// HighlightRow highlights the row at index
-func (ct *Cointop) HighlightRow(idx int) error {
+// HighlightRow highlights the row at index within page
+func (ct *Cointop) HighlightRow(pageRowIndex int) error {
ct.debuglog("highlightRow()")
ct.Views.Table.SetOrigin(0, 0)
ct.Views.Table.SetCursor(0, 0)
ox := ct.Views.Table.OriginX()
cx := ct.Views.Table.CursorX()
- sy := ct.Views.Table.Height()
+ h := ct.Views.Table.Height()
perpage := ct.TotalPerPage()
- p := idx % perpage
- oy := (p / sy) * sy
- cy := p % sy
+ oy := 0
+ cy := 0
+ if h > 0 {
+ _ = perpage
+ cy = pageRowIndex % h
+ oy = pageRowIndex - cy
+ // end of page
+ if pageRowIndex >= perpage-h {
+ oy = perpage - h
+ cy = h - (perpage - pageRowIndex)
+ }
+ }
+ ct.debuglog(fmt.Sprintf("highlightRow idx:%v h:%v cy:%v oy:%v", pageRowIndex, h, cy, oy))
if oy > 0 {
ct.Views.Table.SetOrigin(ox, oy)
}
ct.Views.Table.SetCursor(cx, cy)
-
return nil
}
+// GoToCoinRow navigates to the row of the matched coin
+func (ct *Cointop) GoToCoinRow(coin *Coin) error {
+ ct.debuglog("goToCoinRow()")
+ if coin == nil {
+ return nil
+ }
+ idx := ct.GetGlobalCoinIndex(coin)
+ return ct.GoToGlobalIndex(idx)
+}
+
+// GetGlobalCoinIndex returns the index of the coin in from the coins list
+func (ct *Cointop) GetGlobalCoinIndex(coin *Coin) int {
+ var idx int
+ for i, v := range ct.State.allCoins {
+ if v == coin {
+ idx = i
+ break
+ }
+ }
+ return idx
+}
+
// CursorDownOrNextPage moves the cursor down one row or goes to the next page if cursor is on the last row
func (ct *Cointop) CursorDownOrNextPage() error {
ct.debuglog("CursorDownOrNextPage()")
diff --git a/cointop/sort.go b/cointop/sort.go
index c42b402..7d11dcb 100644
--- a/cointop/sort.go
+++ b/cointop/sort.go
@@ -138,7 +138,18 @@ func (ct *Cointop) SortToggle(sortBy string, desc bool) error {
func (ct *Cointop) Sortfn(sortBy string, desc bool) func(g *gocui.Gui, v *gocui.View) error {
ct.debuglog("sortfn()")
return func(g *gocui.Gui, v *gocui.View) error {
- return ct.SortToggle(sortBy, desc)
+ coin := ct.HighlightedRowCoin()
+ err := ct.SortToggle(sortBy, desc)
+ if err != nil {
+ return err
+ }
+ if ct.State.keepRowFocusOnSort {
+ err = ct.GoToCoinRow(coin)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
}
}
diff --git a/cointop/table.go b/cointop/table.go
index 8a469ff..e3fa32b 100644
--- a/cointop/table.go
+++ b/cointop/table.go
@@ -63,10 +63,14 @@ func (ct *Cointop) RefreshTable() error {
}
ct.table.HideColumHeaders = true
- // highlight last row if current row is out of bounds (can happen when switching views)
- currentrow := ct.HighlightedRowIndex()
- if len(ct.State.coins) > currentrow {
- ct.HighlightRow(currentrow)
+ // highlight last row if current row is out of bounds (can happen when switching views).
+ // make sure to not highlight row when actively navigating, otherwise
+ // table will appear glitchy since this is method is async.
+ if ct.State.lastSelectedView != "" && ct.State.lastSelectedView != ct.State.selectedView {
+ currentRowIdx := ct.HighlightedRowIndex()
+ if len(ct.State.coins) > currentRowIdx {
+ ct.HighlightRow(currentRowIdx)
+ }
}
ct.UpdateUI(func() error {
@@ -161,7 +165,7 @@ func (ct *Cointop) GetTableCoinsSlice() []*Coin {
return sliced
}
-// HighlightedRowIndex returns the index of the highlighted row
+// HighlightedRowIndex returns the index of the highlighted row within the per-page limit
func (ct *Cointop) HighlightedRowIndex() int {
ct.debuglog("HighlightedRowIndex()")
oy := ct.Views.Table.OriginY()
diff --git a/pkg/api/impl/coingecko/coingecko.go b/pkg/api/impl/coingecko/coingecko.go
index 9380b74..2aa3ecf 100644
--- a/pkg/api/impl/coingecko/coingecko.go
+++ b/pkg/api/impl/coingecko/coingecko.go
@@ -33,7 +33,7 @@ func NewCoinGecko() *Service {
client := gecko.NewClient(nil)
svc := &Service{
client: client,
- maxResultsPerPage: 250,
+ maxResultsPerPage: 250, // max is 250
maxPages: 10,
cacheMap: sync.Map{},
}
diff --git a/pkg/chartplot/chartplot.go b/pkg/chartplot/chartplot.go
index 8dbbd4a..c9101b3 100644
--- a/pkg/chartplot/chartplot.go
+++ b/pkg/chartplot/chartplot.go
@@ -89,6 +89,9 @@ func (c *ChartPlot) GetChartPoints(width int) [][]rune {
func interpolateData(data []float64, width int) []float64 {
var res []float64
+ if len(data) == 0 {
+ return res
+ }
stepFactor := float64(len(data)-1) / float64(width-1)
res = append(res, data[0])
for i := 1; i < width-1; i++ {