Add configurable preferred main table columns

pull/94/head
Miguel Mota 3 years ago
parent 093084e859
commit 82eb713652

@ -9,22 +9,36 @@ import (
"github.com/miguelmota/cointop/pkg/table"
)
// DefaultCoinTableHeaders are the default coin table header columns
var DefaultCoinTableHeaders = []string{
"rank",
"name",
"symbol",
"price",
"marketcap",
"24h_volume",
"1h_change",
"24h_change",
"7d_change",
"total_supply",
"available_supply",
"last_updated",
}
// ValidCoinsTableHeader returns true if it's a valid table header name
func (ct *Cointop) ValidCoinsTableHeader(name string) bool {
for _, v := range DefaultCoinTableHeaders {
if v == name {
return true
}
}
return false
}
// GetCoinsTableHeaders returns the coins table headers
func (ct *Cointop) GetCoinsTableHeaders() []string {
return []string{
"rank",
"name",
"symbol",
"price",
"marketcap",
"24h_volume",
"1h_change",
"24h_change",
"7d_change",
"total_supply",
"available_supply",
"last_updated",
}
return ct.State.coinsTableColumns
}
// GetCoinsTable returns the table for diplaying the coins
@ -75,92 +89,123 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
}
unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64)
lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02")
headers := ct.GetCoinsTableHeaders()
var rowCells []*table.RowCell
for _, header := range headers {
switch header {
case "rank":
rowCells = append(rowCells, &table.RowCell{
LeftMargin: 0,
Width: 6,
LeftAlign: false,
Color: ct.colorscheme.Default,
Text: rank,
})
case "name":
rowCells = append(rowCells, &table.RowCell{
LeftMargin: 1,
Width: 22,
LeftAlign: true,
Color: namecolor,
Text: name,
})
case "symbol":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: symbolpadding,
LeftAlign: true,
Color: ct.colorscheme.TableRow,
Text: symbol,
})
case "price":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 12,
LeftAlign: false,
Color: ct.colorscheme.TableColumnPrice,
Text: humanize.Commaf(coin.Price),
})
case "marketcap":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 18,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.MarketCap),
})
case "24h_volume":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 16,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.Volume24H),
})
case "1h_change":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 11,
LeftAlign: false,
Color: color1h,
Text: fmt.Sprintf("%.2f%%", coin.PercentChange1H),
})
case "24h_change":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 10,
LeftAlign: false,
Color: color24h,
Text: fmt.Sprintf("%.2f%%", coin.PercentChange24H),
})
case "7d_change":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 10,
LeftAlign: false,
Color: color7d,
Text: fmt.Sprintf("%.2f%%", coin.PercentChange7D),
})
case "total_supply":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 22,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.TotalSupply),
})
case "available_supply":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 19,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.AvailableSupply),
})
case "last_updated":
rowCells = append(rowCells,
&table.RowCell{
LeftMargin: 1,
Width: 18,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: lastUpdated,
})
}
}
t.AddRowCells(
&table.RowCell{
LeftMargin: 0,
Width: 6,
LeftAlign: false,
Color: ct.colorscheme.Default,
Text: rank,
},
&table.RowCell{
LeftMargin: 1,
Width: 22,
LeftAlign: true,
Color: namecolor,
Text: name,
},
&table.RowCell{
LeftMargin: 1,
Width: symbolpadding,
LeftAlign: true,
Color: ct.colorscheme.TableRow,
Text: symbol,
},
&table.RowCell{
LeftMargin: 1,
Width: 12,
LeftAlign: false,
Color: ct.colorscheme.TableColumnPrice,
Text: humanize.Commaf(coin.Price),
},
&table.RowCell{
LeftMargin: 1,
Width: 18,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.MarketCap),
},
&table.RowCell{
LeftMargin: 1,
Width: 16,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.Volume24H),
},
&table.RowCell{
LeftMargin: 1,
Width: 11,
LeftAlign: false,
Color: color1h,
Text: fmt.Sprintf("%.2f%%", coin.PercentChange1H),
},
&table.RowCell{
LeftMargin: 1,
Width: 10,
LeftAlign: false,
Color: color24h,
Text: fmt.Sprintf("%.2f%%", coin.PercentChange24H),
},
&table.RowCell{
LeftMargin: 1,
Width: 10,
LeftAlign: false,
Color: color7d,
Text: fmt.Sprintf("%.2f%%", coin.PercentChange7D),
},
&table.RowCell{
LeftMargin: 1,
Width: 22,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.TotalSupply),
},
&table.RowCell{
LeftMargin: 1,
Width: 19,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: humanize.Commaf(coin.AvailableSupply),
},
&table.RowCell{
LeftMargin: 1,
Width: 18,
LeftAlign: false,
Color: ct.colorscheme.TableRow,
Text: lastUpdated,
},
// TODO: add %percent of cap
rowCells...,
// TODO: add %percent of cap
)
}

@ -44,6 +44,7 @@ type State struct {
coins []*Coin
chartPoints [][]rune
currencyConversion string
coinsTableColumns []string
convertMenuVisible bool
defaultView string
@ -211,6 +212,7 @@ func NewCointop(config *Config) (*Cointop, error) {
State: &State{
allCoins: []*Coin{},
cacheDir: DefaultCacheDir,
coinsTableColumns: DefaultCoinTableHeaders,
currencyConversion: "USD",
// DEPRECATED: favorites by 'symbol' is deprecated because of collisions. Kept for backward compatibility.
favoritesBySymbol: make(map[string]bool),

@ -7,6 +7,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"sort"
"strconv"
"strings"
@ -42,6 +43,7 @@ type config struct {
Colorscheme interface{} `toml:"colorscheme"`
RefreshRate interface{} `toml:"refresh_rate"`
CacheDir interface{} `toml:"cache_dir"`
Table map[string]interface{} `toml:"table"`
}
// SetupConfig loads config file
@ -53,6 +55,9 @@ func (ct *Cointop) SetupConfig() error {
if err := ct.parseConfig(); err != nil {
return err
}
if err := ct.loadTableColumnsFromConfig(); err != nil {
return err
}
if err := ct.loadShortcutsFromConfig(); err != nil {
return err
}
@ -260,6 +265,15 @@ func (ct *Cointop) configToToml() ([]byte, error) {
"sound": ct.State.priceAlerts.SoundEnabled,
}
var coinsTableColumnsIfc interface{} = ct.State.coinsTableColumns
tableMapIfc := map[string]interface{}{}
if reflect.DeepEqual(DefaultCoinTableHeaders, ct.State.coinsTableColumns) {
tableMapIfc["columns"] = []string{}
} else {
tableMapIfc["columns"] = coinsTableColumnsIfc
}
var inputs = &config{
API: apiChoiceIfc,
Colorscheme: colorschemeIfc,
@ -272,6 +286,7 @@ func (ct *Cointop) configToToml() ([]byte, error) {
Portfolio: portfolioIfc,
PriceAlerts: priceAlertsMapIfc,
CacheDir: cacheDirIfc,
Table: tableMapIfc,
}
var b bytes.Buffer
@ -284,6 +299,31 @@ func (ct *Cointop) configToToml() ([]byte, error) {
return b.Bytes(), nil
}
// LoadTableColumnsFromConfig loads preferred coins table columns from config file to struct
func (ct *Cointop) loadTableColumnsFromConfig() error {
ct.debuglog("loadTableColumnsFromConfig()")
columnsIfc, ok := ct.config.Table["columns"]
if !ok {
return nil
}
var columns []string
ifcs, ok := columnsIfc.([]interface{})
if ok {
for _, ifc := range ifcs {
if v, ok := ifc.(string); ok {
if !ct.ValidCoinsTableHeader(v) {
return fmt.Errorf("Invalid table header name %q. Valid names are: %s", v, strings.Join(DefaultCoinTableHeaders, ","))
}
columns = append(columns, v)
}
}
if len(columns) > 0 {
ct.State.coinsTableColumns = columns
}
}
return nil
}
// LoadShortcutsFromConfig loads keyboard shortcuts from config file to struct
func (ct *Cointop) loadShortcutsFromConfig() error {
ct.debuglog("loadShortcutsFromConfig()")

Loading…
Cancel
Save