diff --git a/cointop/chart.go b/cointop/chart.go index dfd3dbf6..d101036a 100644 --- a/cointop/chart.go +++ b/cointop/chart.go @@ -61,7 +61,7 @@ func (ct *Cointop) UpdateChart() error { chartLock.Lock() defer chartLock.Unlock() - if ct.State.portfolioVisible { + if ct.IsPortfolioVisible() { if err := ct.PortfolioChart(); err != nil { return err } diff --git a/cointop/coin.go b/cointop/coin.go index a51a57bf..8ec776a4 100644 --- a/cointop/coin.go +++ b/cointop/coin.go @@ -26,7 +26,7 @@ type Coin struct { // AllCoins returns a slice of all the coins func (ct *Cointop) AllCoins() []*Coin { ct.debuglog("AllCoins()") - if ct.State.filterByFavorites { + if ct.IsFavoritesVisible() { var list []*Coin for i := range ct.State.allCoins { coin := ct.State.allCoins[i] @@ -37,7 +37,7 @@ func (ct *Cointop) AllCoins() []*Coin { return list } - if ct.State.portfolioVisible { + if ct.IsPortfolioVisible() { var list []*Coin for i := range ct.State.allCoins { coin := ct.State.allCoins[i] diff --git a/cointop/coins_table.go b/cointop/coins_table.go new file mode 100644 index 00000000..01b33f9c --- /dev/null +++ b/cointop/coins_table.go @@ -0,0 +1,168 @@ +package cointop + +import ( + "fmt" + "strconv" + "time" + + "github.com/miguelmota/cointop/pkg/humanize" + "github.com/miguelmota/cointop/pkg/table" +) + +// GetCoinsTableHeaders returns the coins table headers +func (ct *Cointop) GetCoinsTableHeaders() []string { + return []string{ + "rank", + "name", + "symbol", + "price", + "marketcap", + "24hvolume", + "1hchange", + "24hchange", + "7dchange", + "totalsupply", + "availablesupply", + "lastupdated", + } +} + +// GetCoinsTable returns the table for diplaying the coins +func (ct *Cointop) GetCoinsTable() *table.Table { + maxX := ct.width() + t := table.NewTable().SetWidth(maxX) + for _, coin := range ct.State.coins { + if coin == nil { + continue + } + star := ct.colorscheme.TableRow(" ") + if coin.Favorite { + star = ct.colorscheme.TableRowFavorite("*") + } + rank := fmt.Sprintf("%s%v", star, ct.colorscheme.TableRow(fmt.Sprintf("%6v ", coin.Rank))) + name := TruncateString(coin.Name, 20) + symbol := TruncateString(coin.Symbol, 6) + symbolpadding := 8 + // NOTE: this is to adjust padding by 1 because when all name rows are + // yellow it messes the spacing (need to debug) + if ct.IsFavoritesVisible() { + symbolpadding++ + } + namecolor := ct.colorscheme.TableRow + color1h := ct.colorscheme.TableColumnChange + color24h := ct.colorscheme.TableColumnChange + color7d := ct.colorscheme.TableColumnChange + if coin.Favorite { + namecolor = ct.colorscheme.TableRowFavorite + } + if coin.PercentChange1H > 0 { + color1h = ct.colorscheme.TableColumnChangeUp + } + if coin.PercentChange1H < 0 { + color1h = ct.colorscheme.TableColumnChangeDown + } + if coin.PercentChange24H > 0 { + color24h = ct.colorscheme.TableColumnChangeUp + } + if coin.PercentChange24H < 0 { + color24h = ct.colorscheme.TableColumnChangeDown + } + if coin.PercentChange7D > 0 { + color7d = ct.colorscheme.TableColumnChangeUp + } + if coin.PercentChange7D < 0 { + color7d = ct.colorscheme.TableColumnChangeDown + } + unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64) + lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02") + 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 + ) + } + + return t +} diff --git a/cointop/cointop.go b/cointop/cointop.go index 761b275b..c96d7ec7 100644 --- a/cointop/cointop.go +++ b/cointop/cointop.go @@ -53,7 +53,6 @@ type State struct { favoritesBySymbol map[string]bool favorites map[string]bool - filterByFavorites bool helpVisible bool hideMarketbar bool hideChart bool @@ -62,13 +61,14 @@ type State struct { page int perPage int portfolio *Portfolio - portfolioVisible bool portfolioUpdateMenuVisible bool refreshRate time.Duration running bool searchFieldVisible bool selectedCoin *Coin selectedChartRange string + selectedView string + lastSelectedView string shortcutKeys map[string]string sortDesc bool sortBy string @@ -107,12 +107,6 @@ type Cointop struct { Views *Views } -// CoinMarketCap is API choice -var CoinMarketCap = "coinmarketcap" - -// CoinGecko is API choice -var CoinGecko = "coingecko" - // PortfolioEntry is portfolio entry type PortfolioEntry struct { Coin string diff --git a/cointop/config.go b/cointop/config.go index 16d8e406..49338523 100644 --- a/cointop/config.go +++ b/cointop/config.go @@ -284,14 +284,13 @@ func (ct *Cointop) loadDefaultViewFromConfig() error { defaultView = strings.ToLower(defaultView) switch defaultView { case "portfolio": - ct.State.portfolioVisible = true + ct.SetSelectedView(PortfolioView) case "favorites": - ct.State.filterByFavorites = true + ct.SetSelectedView(FavoritesView) case "default": fallthrough default: - ct.State.portfolioVisible = false - ct.State.filterByFavorites = false + ct.SetSelectedView(CoinsView) defaultView = "default" } ct.State.defaultView = defaultView diff --git a/cointop/constants.go b/cointop/constants.go new file mode 100644 index 00000000..2293d736 --- /dev/null +++ b/cointop/constants.go @@ -0,0 +1,16 @@ +package cointop + +// CoinMarketCap is API choice +const CoinMarketCap = "coinmarketcap" + +// CoinGecko is API choice +const CoinGecko = "coingecko" + +// PortfolioView is portfolio table constant +const PortfolioView = "portfolio" + +// CoinsView is coins table constant +const CoinsView = "coins" + +// FavoritesView is favorites table constant +const FavoritesView = "favorites" diff --git a/cointop/favorites.go b/cointop/favorites.go index 8136f30f..049061ab 100644 --- a/cointop/favorites.go +++ b/cointop/favorites.go @@ -1,6 +1,8 @@ package cointop -import "sort" +import ( + "sort" +) // ToggleFavorite toggles coin as favorite func (ct *Cointop) ToggleFavorite() error { @@ -28,11 +30,18 @@ func (ct *Cointop) ToggleFavorite() error { return nil } -// ToggleShowFavorites toggles the favorites view +// ToggleFavorites toggles the favorites view +func (ct *Cointop) ToggleFavorites() error { + ct.debuglog("toggleFavorites()") + ct.ToggleSelectedView(FavoritesView) + go ct.UpdateTable() + return nil +} + +// ToggleShowFavorites shows the favorites view func (ct *Cointop) ToggleShowFavorites() error { ct.debuglog("toggleShowFavorites()") - ct.State.portfolioVisible = false - ct.State.filterByFavorites = !ct.State.filterByFavorites + ct.ToggleSelectedView(FavoritesView) go ct.UpdateTable() return nil } @@ -58,3 +67,8 @@ func (ct *Cointop) GetFavoritesSlice() []*Coin { return sliced } + +// IsFavoritesVisible returns true if favorites view is visible +func (ct *Cointop) IsFavoritesVisible() bool { + return ct.State.selectedView == FavoritesView +} diff --git a/cointop/keybindings.go b/cointop/keybindings.go index 925fa0e8..dcca762b 100644 --- a/cointop/keybindings.go +++ b/cointop/keybindings.go @@ -308,6 +308,8 @@ func (ct *Cointop) Keybindings(g *gocui.Gui) error { view = "" case "toggle_favorite": fn = ct.Keyfn(ct.ToggleFavorite) + case "toggle_favorites": + fn = ct.Keyfn(ct.ToggleFavorites) case "toggle_show_favorites": fn = ct.Keyfn(ct.ToggleShowFavorites) case "save": @@ -419,7 +421,7 @@ func (ct *Cointop) Keyfn(fn func() error) func(g *gocui.Gui, v *gocui.View) erro // handleHkey handles the h key func (ct *Cointop) handleHkey(key interface{}) func(g *gocui.Gui, v *gocui.View) error { return func(g *gocui.Gui, v *gocui.View) error { - if k, ok := key.(rune); ok && k == 'h' && ct.State.portfolioVisible { + if k, ok := key.(rune); ok && k == 'h' && ct.IsPortfolioVisible() { ct.SortToggle("holdings", true) } else { ct.PrevPage() diff --git a/cointop/list.go b/cointop/list.go index 5fa43953..8d69f77a 100644 --- a/cointop/list.go +++ b/cointop/list.go @@ -157,9 +157,9 @@ func (ct *Cointop) processCoins(coins []types.Coin) { // GetListCount returns count of coins list func (ct *Cointop) GetListCount() int { ct.debuglog("getListCount()") - if ct.State.filterByFavorites { + if ct.IsFavoritesVisible() { return len(ct.State.favorites) - } else if ct.State.portfolioVisible { + } else if ct.IsPortfolioVisible() { return len(ct.State.portfolio.Entries) } else { return len(ct.State.allCoins) diff --git a/cointop/marketbar.go b/cointop/marketbar.go index 28c73e7b..fd8d1826 100644 --- a/cointop/marketbar.go +++ b/cointop/marketbar.go @@ -31,7 +31,7 @@ func (ct *Cointop) UpdateMarketbar() error { } var content string - if ct.State.portfolioVisible { + if ct.IsPortfolioVisible() { total := ct.GetPortfolioTotal() totalstr := humanize.Commaf(total) if !(ct.State.currencyConversion == "BTC" || ct.State.currencyConversion == "ETH" || total < 1) { diff --git a/cointop/portfolio.go b/cointop/portfolio.go index ddbcdc37..a6c14c74 100644 --- a/cointop/portfolio.go +++ b/cointop/portfolio.go @@ -10,10 +10,12 @@ import ( "sort" "strconv" "strings" + "time" "github.com/miguelmota/cointop/pkg/asciitable" "github.com/miguelmota/cointop/pkg/humanize" "github.com/miguelmota/cointop/pkg/pad" + "github.com/miguelmota/cointop/pkg/table" "github.com/miguelmota/cointop/pkg/ui" ) @@ -26,17 +28,137 @@ func NewPortfolioUpdateMenuView() *PortfolioUpdateMenuView { return view } +// GetPortfolioTableHeaders returns the portfolio table headers +func (ct *Cointop) GetPortfolioTableHeaders() []string { + return []string{ + "rank", + "name", + "symbol", + "price", + "holdings", + "balance", + "24hchange", + "percentholdings", + "lastupdated", + } +} + +// GetPortfolioTable returns the table for displaying portfolio holdings +func (ct *Cointop) GetPortfolioTable() *table.Table { + total := ct.GetPortfolioTotal() + maxX := ct.width() + t := table.NewTable().SetWidth(maxX) + + for _, coin := range ct.State.coins { + star := ct.colorscheme.TableRow(" ") + name := TruncateString(coin.Name, 20) + symbol := TruncateString(coin.Symbol, 6) + if coin.Favorite { + star = ct.colorscheme.TableRowFavorite("*") + } + rank := fmt.Sprintf("%s%v", star, ct.colorscheme.TableRow(fmt.Sprintf("%6v ", coin.Rank))) + + namecolor := ct.colorscheme.TableRow + if coin.Favorite { + namecolor = ct.colorscheme.TableRowFavorite + } + + colorbalance := ct.colorscheme.TableColumnPrice + color24h := ct.colorscheme.TableColumnChange + if coin.PercentChange24H > 0 { + color24h = ct.colorscheme.TableColumnChangeUp + } + if coin.PercentChange24H < 0 { + color24h = ct.colorscheme.TableColumnChangeDown + } + + percentHoldings := (coin.Balance / total) * 1e2 + if math.IsNaN(percentHoldings) { + percentHoldings = 0 + } + unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64) + lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02") + + 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: 6, + LeftAlign: true, + Color: ct.colorscheme.TableRow, + Text: symbol, + }, + &table.RowCell{ + LeftMargin: 1, + Width: 14, + LeftAlign: false, + Color: ct.colorscheme.TableRow, + Text: humanize.Commaf(coin.Price), + }, + &table.RowCell{ + LeftMargin: 1, + Width: 16, + LeftAlign: false, + Color: ct.colorscheme.TableRow, + Text: strconv.FormatFloat(coin.Holdings, 'f', -1, 64), + }, + &table.RowCell{ + LeftMargin: 1, + Width: 16, + LeftAlign: false, + Color: colorbalance, + Text: humanize.Commaf(coin.Balance), + }, + &table.RowCell{ + LeftMargin: 1, + Width: 10, + LeftAlign: false, + Color: color24h, + Text: fmt.Sprintf("%.2f%%", coin.PercentChange24H), + }, + &table.RowCell{ + LeftMargin: 1, + Width: 14, + LeftAlign: false, + Color: ct.colorscheme.TableRow, + Text: fmt.Sprintf("%.2f%%", percentHoldings), + }, + &table.RowCell{ + LeftMargin: 1, + Width: 18, + LeftAlign: false, + Color: ct.colorscheme.TableRow, + Text: lastUpdated, + }, + ) + } + + return t +} + // TogglePortfolio toggles the portfolio view func (ct *Cointop) TogglePortfolio() error { ct.debuglog("togglePortfolio()") - if ct.State.portfolioVisible { + if ct.IsPortfolioVisible() { ct.GoToPageRowIndex(ct.State.lastSelectedRowIndex) } else { ct.State.lastSelectedRowIndex = ct.HighlightedPageRowIndex() } - ct.State.filterByFavorites = false - ct.State.portfolioVisible = !ct.State.portfolioVisible + ct.ToggleSelectedView(PortfolioView) go ct.UpdateChart() go ct.UpdateTable() @@ -46,8 +168,7 @@ func (ct *Cointop) TogglePortfolio() error { // ToggleShowPortfolio shows the portfolio view func (ct *Cointop) ToggleShowPortfolio() error { ct.debuglog("toggleShowPortfolio()") - ct.State.filterByFavorites = false - ct.State.portfolioVisible = true + ct.SetSelectedView(PortfolioView) go ct.UpdateChart() go ct.UpdateTable() return nil @@ -545,6 +666,11 @@ func (ct *Cointop) PrintTotalHoldings(options *TablePrintOptions) error { return nil } +// IsPortfolioVisible returns true if portfolio view is visible +func (ct *Cointop) IsPortfolioVisible() bool { + return ct.State.selectedView == PortfolioView +} + // NormalizeFloatString normalizes a float as a string func normalizeFloatString(input string) string { re := regexp.MustCompile(`(\d+\.\d+|\.\d+|\d+)`) diff --git a/cointop/quit.go b/cointop/quit.go index dab2fa99..cc72a4bf 100644 --- a/cointop/quit.go +++ b/cointop/quit.go @@ -14,12 +14,12 @@ func (ct *Cointop) Quit() error { // QuitView exists the current view func (ct *Cointop) QuitView() error { ct.debuglog("quitView()") - if ct.State.portfolioVisible { - ct.State.portfolioVisible = false + if ct.IsPortfolioVisible() { + ct.SetSelectedView(CoinsView) return ct.UpdateTable() } - if ct.State.filterByFavorites { - ct.State.filterByFavorites = false + if ct.IsFavoritesVisible() { + ct.SetSelectedView(CoinsView) return ct.UpdateTable() } if ct.ui.ActiveViewName() == ct.Views.Table.Name() { diff --git a/cointop/search.go b/cointop/search.go index 89dccad3..696547fe 100644 --- a/cointop/search.go +++ b/cointop/search.go @@ -53,8 +53,7 @@ func (ct *Cointop) DoSearch() error { } // TODO: do this a better way (SoC) - ct.State.filterByFavorites = false - ct.State.portfolioVisible = false + ct.SetSelectedView(CoinsView) defer ct.SetActiveView(ct.Views.Table.Name()) if err != nil { diff --git a/cointop/statusbar.go b/cointop/statusbar.go index 7cb613a1..d6ec8929 100644 --- a/cointop/statusbar.go +++ b/cointop/statusbar.go @@ -25,17 +25,17 @@ func (ct *Cointop) UpdateStatusbar(s string) error { var quitText string var favoritesText string var portfolioText string - if ct.State.portfolioVisible || ct.State.filterByFavorites { + if ct.IsPortfolioVisible() || ct.IsFavoritesVisible() { quitText = "Return" } else { quitText = "Quit" } - if ct.State.portfolioVisible { + if ct.IsPortfolioVisible() { portfolioText = "[E]Edit" } else { portfolioText = "[P]Portfolio" } - if ct.State.filterByFavorites { + if ct.IsFavoritesVisible() { favoritesText = "[Space]Unfavorite" } else { favoritesText = "[F]Favorites" diff --git a/cointop/table.go b/cointop/table.go index a1c80e79..7cacfe30 100644 --- a/cointop/table.go +++ b/cointop/table.go @@ -4,12 +4,8 @@ import ( "fmt" "math" "net/url" - "strconv" "strings" - "time" - "github.com/miguelmota/cointop/pkg/humanize" - "github.com/miguelmota/cointop/pkg/table" "github.com/miguelmota/cointop/pkg/ui" ) @@ -47,246 +43,15 @@ const dots = "..." // RefreshTable refreshes the table func (ct *Cointop) RefreshTable() error { ct.debuglog("refreshTable()") - maxX := ct.width() - ct.table = table.NewTable().SetWidth(maxX) - ct.table.HideColumHeaders = true - - if ct.State.portfolioVisible { - total := ct.GetPortfolioTotal() - - for _, coin := range ct.State.coins { - unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64) - lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02") - colorbalance := ct.colorscheme.TableColumnPrice - color24h := ct.colorscheme.TableColumnChange - if coin.PercentChange24H > 0 { - color24h = ct.colorscheme.TableColumnChangeUp - } - if coin.PercentChange24H < 0 { - color24h = ct.colorscheme.TableColumnChangeDown - } - name := TruncateString(coin.Name, 20) - symbol := TruncateString(coin.Symbol, 6) - star := ct.colorscheme.TableRow(" ") - if coin.Favorite { - star = ct.colorscheme.TableRowFavorite("*") - } - - namecolor := ct.colorscheme.TableRow - if coin.Favorite { - namecolor = ct.colorscheme.TableRowFavorite - } - percentHoldings := (coin.Balance / total) * 1e2 - if math.IsNaN(percentHoldings) { - percentHoldings = 0 - } - - rank := fmt.Sprintf("%s%v", star, ct.colorscheme.TableRow(fmt.Sprintf("%6v ", coin.Rank))) - - ct.table.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: 6, - LeftAlign: true, - Color: ct.colorscheme.TableRow, - Text: symbol, - }, - &table.RowCell{ - LeftMargin: 1, - Width: 14, - LeftAlign: false, - Color: ct.colorscheme.TableRow, - Text: humanize.Commaf(coin.Price), - }, - &table.RowCell{ - LeftMargin: 1, - Width: 16, - LeftAlign: false, - Color: ct.colorscheme.TableRow, - Text: strconv.FormatFloat(coin.Holdings, 'f', -1, 64), - }, - &table.RowCell{ - LeftMargin: 1, - Width: 16, - LeftAlign: false, - Color: colorbalance, - Text: humanize.Commaf(coin.Balance), - }, - &table.RowCell{ - LeftMargin: 1, - Width: 10, - LeftAlign: false, - Color: color24h, - Text: fmt.Sprintf("%.2f%%", coin.PercentChange24H), - }, - &table.RowCell{ - LeftMargin: 1, - Width: 14, - LeftAlign: false, - Color: ct.colorscheme.TableRow, - Text: fmt.Sprintf("%.2f%%", percentHoldings), - }, - &table.RowCell{ - LeftMargin: 1, - Width: 18, - LeftAlign: false, - Color: ct.colorscheme.TableRow, - Text: lastUpdated, - }, - ) - } + if ct.IsPortfolioVisible() { + ct.table = ct.GetPortfolioTable() } else { - for _, coin := range ct.State.coins { - if coin == nil { - continue - } - unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64) - lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02") - namecolor := ct.colorscheme.TableRow - color1h := ct.colorscheme.TableColumnChange - color24h := ct.colorscheme.TableColumnChange - color7d := ct.colorscheme.TableColumnChange - if coin.Favorite { - namecolor = ct.colorscheme.TableRowFavorite - } - if coin.PercentChange1H > 0 { - color1h = ct.colorscheme.TableColumnChangeUp - } - if coin.PercentChange1H < 0 { - color1h = ct.colorscheme.TableColumnChangeDown - } - if coin.PercentChange24H > 0 { - color24h = ct.colorscheme.TableColumnChangeUp - } - if coin.PercentChange24H < 0 { - color24h = ct.colorscheme.TableColumnChangeDown - } - if coin.PercentChange7D > 0 { - color7d = ct.colorscheme.TableColumnChangeUp - } - if coin.PercentChange7D < 0 { - color7d = ct.colorscheme.TableColumnChangeDown - } - name := TruncateString(coin.Name, 20) - symbol := TruncateString(coin.Symbol, 6) - star := ct.colorscheme.TableRow(" ") - if coin.Favorite { - star = ct.colorscheme.TableRowFavorite("*") - } - - symbolpadding := 8 - // NOTE: this is to adjust padding by 1 because when all name rows are - // yellow it messes the spacing (need to debug) - if ct.State.filterByFavorites { - symbolpadding++ - } - - rank := fmt.Sprintf("%s%v", star, ct.colorscheme.TableRow(fmt.Sprintf("%6v ", coin.Rank))) - ct.table.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 - ) - } + ct.table = ct.GetCoinsTable() } + 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 { @@ -319,9 +84,9 @@ func (ct *Cointop) UpdateTable() error { return true }) - if ct.State.filterByFavorites { + if ct.IsFavoritesVisible() { ct.State.coins = ct.GetFavoritesSlice() - } else if ct.State.portfolioVisible { + } else if ct.IsPortfolioVisible() { ct.State.coins = ct.GetPortfolioSlice() } else { // TODO: maintain state of previous sorting @@ -481,3 +246,18 @@ func (ct *Cointop) ToggleTableFullscreen() error { return nil } + +// SetSelectedView sets the active table view +func (ct *Cointop) SetSelectedView(viewName string) { + ct.State.lastSelectedView = ct.State.selectedView + ct.State.selectedView = viewName +} + +// ToggleSelectedView toggles between current table view and last selected table view +func (ct *Cointop) ToggleSelectedView(viewName string) { + if ct.State.lastSelectedView == "" || ct.State.selectedView != viewName { + ct.SetSelectedView(viewName) + } else { + ct.SetSelectedView(ct.State.lastSelectedView) + } +} diff --git a/cointop/table_header.go b/cointop/table_header.go index 3659a7af..586c63b6 100644 --- a/cointop/table_header.go +++ b/cointop/table_header.go @@ -30,7 +30,7 @@ func (ct *Cointop) UpdateTableHeader() error { } baseColor := ct.colorscheme.TableHeaderSprintf() - cm := map[string]*t{ + possibleHeaders := map[string]*t{ "rank": {baseColor, "[r]ank", 0, 1, " "}, "name": {baseColor, "[n]ame", 0, 11, " "}, "symbol": {baseColor, "[s]ymbol", 4, 0, " "}, @@ -48,30 +48,27 @@ func (ct *Cointop) UpdateTableHeader() error { "lastupdated": {baseColor, "last [u]pdated", 3, 0, " "}, } - for k := range cm { - cm[k].arrow = " " + for k := range possibleHeaders { + possibleHeaders[k].arrow = " " if ct.State.sortBy == k { - cm[k].colorfn = ct.colorscheme.TableHeaderColumnActiveSprintf() + possibleHeaders[k].colorfn = ct.colorscheme.TableHeaderColumnActiveSprintf() if ct.State.sortDesc { - cm[k].arrow = "▼" + possibleHeaders[k].arrow = "▼" } else { - cm[k].arrow = "▲" + possibleHeaders[k].arrow = "▲" } } } - if ct.State.portfolioVisible { - cols = []string{"rank", "name", "symbol", "price", - "holdings", "balance", "24hchange", "percentholdings", "lastupdated"} + if ct.IsPortfolioVisible() { + cols = ct.GetPortfolioTableHeaders() } else { - cols = []string{"rank", "name", "symbol", "price", - "marketcap", "24hvolume", "1hchange", "24hchange", - "7dchange", "totalsupply", "availablesupply", "lastupdated"} + cols = ct.GetCoinsTableHeaders() } var headers []string for _, v := range cols { - s, ok := cm[v] + s, ok := possibleHeaders[v] if !ok { continue }