Add comments

pull/58/head
Miguel Mota 4 years ago
parent 2d54de72c7
commit 52be62a2c1

@ -24,7 +24,8 @@ func NewChartView() *ChartView {
var chartLock sync.Mutex
var chartPointsLock sync.Mutex
func chartRanges() []string {
// ChartRanges returns list of chart ranges available
func ChartRanges() []string {
return []string{
"24H",
"3D",
@ -38,7 +39,8 @@ func chartRanges() []string {
}
}
func chartRangesMap() map[string]time.Duration {
// ChartRanges returns map of chart range time ranges
func ChartRangesMap() map[string]time.Duration {
return map[string]time.Duration{
"All Time": time.Duration(24 * 7 * 4 * 12 * 5 * time.Hour),
"YTD": time.Duration(1 * time.Second), // this will be calculated
@ -69,8 +71,8 @@ func (ct *Cointop) UpdateChart() error {
return err
}
} else {
symbol := ct.selectedCoinSymbol()
name := ct.selectedCoinName()
symbol := ct.SelectedCoinSymbol()
name := ct.SelectedCoinName()
ct.ChartPoints(symbol, name)
}
@ -111,7 +113,7 @@ func (ct *Cointop) ChartPoints(symbol string, name string) error {
defer chartPointsLock.Unlock()
// TODO: not do this (SoC)
go ct.updateMarketbar()
go ct.UpdateMarketbar()
chart := termui.NewLineChart()
chart.Height = ct.State.chartHeight
@ -216,7 +218,7 @@ func (ct *Cointop) PortfolioChart() error {
defer chartPointsLock.Unlock()
// TODO: not do this (SoC)
go ct.updateMarketbar()
go ct.UpdateMarketbar()
chart := termui.NewLineChart()
chart.Height = ct.State.chartHeight
@ -237,8 +239,8 @@ func (ct *Cointop) PortfolioChart() error {
end := nowseconds
var data []float64
portfolio := ct.getPortfolioSlice()
chartname := ct.selectedCoinName()
portfolio := ct.GetPortfolioSlice()
chartname := ct.SelectedCoinName()
for _, p := range portfolio {
// filter by selected chart if selected
if chartname != "" {
@ -419,7 +421,7 @@ func (ct *Cointop) ToggleCoinChart() error {
ct.UpdateChart()
}()
go ct.updateMarketbar()
go ct.UpdateMarketbar()
return nil
}

@ -160,9 +160,9 @@ func NewCointop(config *Config) (*Cointop, error) {
ActionsMap: ActionsMap(),
cache: cache.New(1*time.Minute, 2*time.Minute),
configFilepath: configFilepath,
chartRanges: chartRanges(),
chartRanges: ChartRanges(),
debug: debug,
chartRangesMap: chartRangesMap(),
chartRangesMap: ChartRangesMap(),
limiter: time.Tick(2 * time.Second),
State: &State{
allCoins: []*Coin{},
@ -200,7 +200,7 @@ func NewCointop(config *Config) (*Cointop, error) {
},
}
err := ct.setupConfig()
err := ct.SetupConfig()
if err != nil {
return nil, err
}
@ -224,7 +224,7 @@ func NewCointop(config *Config) (*Cointop, error) {
// prompt for CoinMarketCap api key if not found
if config.CoinMarketCapAPIKey != "" {
ct.apiKeys.cmc = config.CoinMarketCapAPIKey
if err := ct.saveConfig(); err != nil {
if err := ct.SaveConfig(); err != nil {
return nil, err
}
}
@ -241,7 +241,7 @@ func NewCointop(config *Config) (*Cointop, error) {
if config.APIChoice != "" {
ct.apiChoice = config.APIChoice
if err := ct.saveConfig(); err != nil {
if err := ct.SaveConfig(); err != nil {
return nil, err
}
}
@ -261,7 +261,7 @@ func NewCointop(config *Config) (*Cointop, error) {
ct.apiKeys.cmc = apiKey
}
if err := ct.saveConfig(); err != nil {
if err := ct.SaveConfig(); err != nil {
return nil, err
}
}
@ -298,7 +298,7 @@ func NewCointop(config *Config) (*Cointop, error) {
if max > 100 {
max = 100
}
ct.sort(ct.State.sortBy, ct.State.sortDesc, ct.State.allCoins, false)
ct.Sort(ct.State.sortBy, ct.State.sortDesc, ct.State.allCoins, false)
ct.State.coins = ct.State.allCoins[0:max]
}
@ -353,7 +353,7 @@ func (ct *Cointop) Run() error {
g.Mouse = true
g.Highlight = true
g.SetManagerFunc(ct.layout)
if err := ct.keybindings(g); err != nil {
if err := ct.Keybindings(g); err != nil {
return fmt.Errorf("keybindings: %v", err)
}
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
@ -386,17 +386,18 @@ func PrintPrice(config *PriceConfig) error {
return err
}
symbol := currencySymbol(config.Currency)
symbol := CurrencySymbol(config.Currency)
fmt.Fprintf(os.Stdout, "%s%s", symbol, humanize.Commaf(price))
return nil
}
// CleanConfig is the config for the clean function
type CleanConfig struct {
Log bool
}
// Clean ...
// Clean removes cache files
func Clean(config *CleanConfig) error {
tmpPath := "/tmp"
if _, err := os.Stat(tmpPath); !os.IsNotExist(err) {
@ -425,11 +426,12 @@ func Clean(config *CleanConfig) error {
return nil
}
// ResetConfig is the config for the reset function
type ResetConfig struct {
Log bool
}
// Reset ...
// Reset removes configuration and cache files
func Reset(config *ResetConfig) error {
if err := Clean(&CleanConfig{
Log: config.Log,

@ -301,7 +301,7 @@ func (c *Colorscheme) toFgAttr(v string) (fcolor.Attribute, bool) {
return attr, true
}
if code, ok := hexToAnsi(v); ok {
if code, ok := HexToAnsi(v); ok {
return fcolor.Attribute(code), true
}
@ -313,7 +313,7 @@ func (c *Colorscheme) toBgAttr(v string) (fcolor.Attribute, bool) {
return attr, true
}
if code, ok := hexToAnsi(v); ok {
if code, ok := HexToAnsi(v); ok {
return fcolor.Attribute(code), true
}
@ -336,15 +336,15 @@ func (c *Colorscheme) toGocuiAttr(v string) (gocui.Attribute, bool) {
return attr, true
}
if code, ok := hexToAnsi(v); ok {
if code, ok := HexToAnsi(v); ok {
return gocui.Attribute(code), true
}
return 0, false
}
// hexToAnsi converts a hex color string to a uint8 ansi code
func hexToAnsi(h string) (uint8, bool) {
// HexToAnsi converts a hex color string to a uint8 ansi code
func HexToAnsi(h string) (uint8, bool) {
if h == "" {
return 0, false
}

@ -26,9 +26,10 @@ type config struct {
RefreshRate interface{} `toml:"refresh_rate"`
}
func (ct *Cointop) setupConfig() error {
// SetupConfig loads config file
func (ct *Cointop) SetupConfig() error {
ct.debuglog("setupConfig()")
if err := ct.createConfigIfNotExists(); err != nil {
if err := ct.CreateConfigIfNotExists(); err != nil {
return err
}
if err := ct.parseConfig(); err != nil {
@ -65,7 +66,8 @@ func (ct *Cointop) setupConfig() error {
return nil
}
func (ct *Cointop) createConfigIfNotExists() error {
// CreateConfigIfNotExists creates config file if it doesn't exist
func (ct *Cointop) CreateConfigIfNotExists() error {
ct.debuglog("createConfigIfNotExists()")
// NOTE: this is to support previous default config filepaths
@ -95,7 +97,8 @@ func (ct *Cointop) createConfigIfNotExists() error {
return nil
}
func (ct *Cointop) configDirPath() string {
// ConfigDirPath returns the config directory path
func (ct *Cointop) ConfigDirPath() string {
ct.debuglog("configDirPath()")
path := NormalizePath(ct.configFilepath)
separator := string(filepath.Separator)
@ -103,14 +106,16 @@ func (ct *Cointop) configDirPath() string {
return strings.Join(parts[0:len(parts)-1], separator)
}
func (ct *Cointop) configPath() string {
ct.debuglog("configPath()")
// ConfigPath return the config file path
func (ct *Cointop) ConfigFilePath() string {
ct.debuglog("configFilePath()")
return NormalizePath(ct.configFilepath)
}
// ConfigPath return the config file path
func (ct *Cointop) makeConfigDir() error {
ct.debuglog("makeConfigDir()")
path := ct.configDirPath()
path := ct.ConfigDirPath()
if _, err := os.Stat(path); os.IsNotExist(err) {
return os.MkdirAll(path, os.ModePerm)
}
@ -118,9 +123,10 @@ func (ct *Cointop) makeConfigDir() error {
return nil
}
// MakeConfigFile creates a new config file
func (ct *Cointop) makeConfigFile() error {
ct.debuglog("makeConfigFile()")
path := ct.configPath()
path := ct.ConfigFilePath()
if _, err := os.Stat(path); os.IsNotExist(err) {
fo, err := os.Create(path)
if err != nil {
@ -138,11 +144,12 @@ func (ct *Cointop) makeConfigFile() error {
return nil
}
func (ct *Cointop) saveConfig() error {
// SaveConfig writes settings to the config file
func (ct *Cointop) SaveConfig() error {
ct.debuglog("saveConfig()")
ct.saveMux.Lock()
defer ct.saveMux.Unlock()
path := ct.configPath()
path := ct.ConfigFilePath()
if _, err := os.Stat(path); err == nil {
b, err := ct.configToToml()
if err != nil {
@ -156,10 +163,11 @@ func (ct *Cointop) saveConfig() error {
return nil
}
// ParseConfig decodes the toml config file
func (ct *Cointop) parseConfig() error {
ct.debuglog("parseConfig()")
var conf config
path := ct.configPath()
path := ct.ConfigFilePath()
if _, err := toml.DecodeFile(path, &conf); err != nil {
return err
}
@ -168,6 +176,7 @@ func (ct *Cointop) parseConfig() error {
return nil
}
// ConfigToToml encodes config struct to TOML
func (ct *Cointop) configToToml() ([]byte, error) {
ct.debuglog("configToToml()")
shortcutsIfcs := map[string]interface{}{}
@ -232,6 +241,7 @@ func (ct *Cointop) configToToml() ([]byte, error) {
return b.Bytes(), nil
}
// LoadShortcutsFromConfig loads keyboard shortcuts from config file to struct
func (ct *Cointop) loadShortcutsFromConfig() error {
ct.debuglog("loadShortcutsFromConfig()")
for k, ifc := range ct.config.Shortcuts {
@ -248,6 +258,7 @@ func (ct *Cointop) loadShortcutsFromConfig() error {
return nil
}
// LoadCurrencyFromConfig loads currency from config file to struct
func (ct *Cointop) loadCurrencyFromConfig() error {
ct.debuglog("loadCurrencyFromConfig()")
if currency, ok := ct.config.Currency.(string); ok {
@ -256,6 +267,7 @@ func (ct *Cointop) loadCurrencyFromConfig() error {
return nil
}
// LoadDefaultViewFromConfig loads default view from config file to struct
func (ct *Cointop) loadDefaultViewFromConfig() error {
ct.debuglog("loadDefaultViewFromConfig()")
if defaultView, ok := ct.config.DefaultView.(string); ok {
@ -277,6 +289,7 @@ func (ct *Cointop) loadDefaultViewFromConfig() error {
return nil
}
// LoadAPIKeysFromConfig loads API keys from config file to struct
func (ct *Cointop) loadAPIKeysFromConfig() error {
ct.debuglog("loadAPIKeysFromConfig()")
for key, value := range ct.config.CoinMarketCap {
@ -288,6 +301,7 @@ func (ct *Cointop) loadAPIKeysFromConfig() error {
return nil
}
// LoadColorschemeFromConfig loads colorscheme name from config file to struct
func (ct *Cointop) loadColorschemeFromConfig() error {
ct.debuglog("loadColorschemeFromConfig()")
if colorscheme, ok := ct.config.Colorscheme.(string); ok {
@ -297,6 +311,7 @@ func (ct *Cointop) loadColorschemeFromConfig() error {
return nil
}
// LoadRefreshRateFromConfig loads refresh rate from config file to struct
func (ct *Cointop) loadRefreshRateFromConfig() error {
ct.debuglog("loadRefreshRateFromConfig()")
if refreshRate, ok := ct.config.RefreshRate.(int64); ok {
@ -306,6 +321,7 @@ func (ct *Cointop) loadRefreshRateFromConfig() error {
return nil
}
// GetColorschemeColors loads colors from colorsheme file to struct
func (ct *Cointop) getColorschemeColors() (map[string]interface{}, error) {
ct.debuglog("getColorschemeColors()")
var colors map[string]interface{}
@ -337,6 +353,7 @@ func (ct *Cointop) getColorschemeColors() (map[string]interface{}, error) {
return colors, nil
}
// LoadAPIChoiceFromConfig loads API choices from config file to struct
func (ct *Cointop) loadAPIChoiceFromConfig() error {
ct.debuglog("loadAPIKeysFromConfig()")
apiChoice, ok := ct.config.API.(string)
@ -347,6 +364,7 @@ func (ct *Cointop) loadAPIChoiceFromConfig() error {
return nil
}
// LoadFavoritesFromConfig loads favorites data from config file to struct
func (ct *Cointop) loadFavoritesFromConfig() error {
ct.debuglog("loadFavoritesFromConfig()")
for k, arr := range ct.config.Favorites {
@ -368,6 +386,7 @@ func (ct *Cointop) loadFavoritesFromConfig() error {
return nil
}
// LoadPortfolioFromConfig loads portfolio data from config file to struct
func (ct *Cointop) loadPortfolioFromConfig() error {
ct.debuglog("loadPortfolioFromConfig()")
for name, holdingsIfc := range ct.config.Portfolio {
@ -379,7 +398,7 @@ func (ct *Cointop) loadPortfolioFromConfig() error {
}
}
if err := ct.setPortfolioEntry(name, holdings); err != nil {
if err := ct.SetPortfolioEntry(name, holdings); err != nil {
return err
}
}

@ -9,8 +9,9 @@ import (
"github.com/miguelmota/cointop/cointop/common/pad"
)
// keep these in alphabetical order
var fiatCurrencyNames = map[string]string{
// FiatCurrencyNames is a mpa of currency symbols to names.
// Keep these in alphabetical order.
var FiatCurrencyNames = map[string]string{
"AUD": "Australian Dollar",
"BGN": "Bulgarian lev",
"BRL": "Brazilian Real",
@ -50,13 +51,15 @@ var fiatCurrencyNames = map[string]string{
"ZAR": "South African Rand",
}
var cryptocurrencyNames = map[string]string{
// CryptocurrencyNames is a map of cryptocurrency symbols to name
var CryptocurrencyNames = map[string]string{
"BTC": "Bitcoin",
"ETH": "Ethereum",
}
// keep these in alphabetical order
var currencySymbolMap = map[string]string{
// CurrencySymbolMap is map of fiat currency symbols to names.
// Keep these in alphabetical order.
var CurrencySymbolMap = map[string]string{
"AUD": "$",
"BGN": "Лв.",
"BRL": "R$",
@ -110,13 +113,14 @@ func NewConvertMenuView() *ConvertMenuView {
return &ConvertMenuView{NewView("convertmenu")}
}
func (ct *Cointop) supportedCurrencyConversions() map[string]string {
// SupportedCurrencyConversions returns a map of all supported currencies for conversion
func (ct *Cointop) SupportedCurrencyConversions() map[string]string {
all := map[string]string{}
for _, symbol := range ct.api.SupportedCurrencies() {
if v, ok := fiatCurrencyNames[symbol]; ok {
if v, ok := FiatCurrencyNames[symbol]; ok {
all[symbol] = v
}
if v, ok := cryptocurrencyNames[symbol]; ok {
if v, ok := CryptocurrencyNames[symbol]; ok {
all[symbol] = v
}
}
@ -124,16 +128,19 @@ func (ct *Cointop) supportedCurrencyConversions() map[string]string {
return all
}
func (ct *Cointop) supportedFiatCurrencyConversions() map[string]string {
return fiatCurrencyNames
// SupportedFiatCurrencyConversions returns map of supported fiat currencies for conversion
func (ct *Cointop) SupportedFiatCurrencyConversions() map[string]string {
return FiatCurrencyNames
}
func (ct *Cointop) supportedCryptoCurrencyConversions() map[string]string {
return cryptocurrencyNames
// SupportedCryptoCurrencyConversions returns map of supported cryptocurrencies for conversion
func (ct *Cointop) SupportedCryptoCurrencyConversions() map[string]string {
return CryptocurrencyNames
}
func (ct *Cointop) sortedSupportedCurrencyConversions() []string {
currencies := ct.supportedCurrencyConversions()
// SortedSupportedCurrencyConversions returns sorted list of supported currencies for conversion
func (ct *Cointop) SortedSupportedCurrencyConversions() []string {
currencies := ct.SupportedCurrencyConversions()
keys := make([]string, 0, len(currencies))
for k := range currencies {
keys = append(keys, k)
@ -142,7 +149,8 @@ func (ct *Cointop) sortedSupportedCurrencyConversions() []string {
return keys
}
func (ct *Cointop) updateConvertMenu() {
// UpdateConvertMenu updates the convert menu
func (ct *Cointop) UpdateConvertMenu() {
ct.debuglog("updateConvertMenu()")
header := ct.colorscheme.MenuHeader(fmt.Sprintf(" Currency Conversion %s\n\n", pad.Left("[q] close menu ", ct.maxTableWidth-20, " ")))
helpline := " Press the corresponding key to select currency for conversion\n\n"
@ -154,8 +162,8 @@ func (ct *Cointop) updateConvertMenu() {
cols[i] = make([]string, 20)
}
keys := ct.sortedSupportedCurrencyConversions()
currencies := ct.supportedCurrencyConversions()
keys := ct.SortedSupportedCurrencyConversions()
currencies := ct.SupportedCurrencyConversions()
for i, key := range keys {
currency := currencies[key]
if cnt%percol == 0 {
@ -198,10 +206,11 @@ func (ct *Cointop) updateConvertMenu() {
})
}
func (ct *Cointop) setCurrencyConverstionFn(convert string) func() error {
// SetCurrencyConverstionFn sets the currency conversion function
func (ct *Cointop) SetCurrencyConverstionFn(convert string) func() error {
ct.debuglog("setCurrencyConverstionFn()")
return func() error {
ct.hideConvertMenu()
ct.HideConvertMenu()
// NOTE: return if the currency selection wasn't changed
if ct.State.currencyConversion == convert {
@ -214,15 +223,15 @@ func (ct *Cointop) setCurrencyConverstionFn(convert string) func() error {
return err
}
go ct.refreshAll()
go ct.RefreshAll()
return nil
}
}
// currencySymbol returns the symbol for the currency
func (ct *Cointop) currencySymbol() string {
// CurrencySymbol returns the symbol for the currency conversion
func (ct *Cointop) CurrencySymbol() string {
ct.debuglog("currencySymbol()")
symbol, ok := currencySymbolMap[strings.ToUpper(ct.State.currencyConversion)]
symbol, ok := CurrencySymbolMap[strings.ToUpper(ct.State.currencyConversion)]
if ok {
return symbol
}
@ -230,15 +239,17 @@ func (ct *Cointop) currencySymbol() string {
return "$"
}
func (ct *Cointop) showConvertMenu() error {
// ShowConvertMenu shows the convert menu view
func (ct *Cointop) ShowConvertMenu() error {
ct.debuglog("showConvertMenu()")
ct.State.convertMenuVisible = true
ct.updateConvertMenu()
ct.UpdateConvertMenu()
ct.SetActiveView(ct.Views.ConvertMenu.Name())
return nil
}
func (ct *Cointop) hideConvertMenu() error {
// HideConvertMenu hides the convert menu view
func (ct *Cointop) HideConvertMenu() error {
ct.debuglog("hideConvertMenu()")
ct.State.convertMenuVisible = false
ct.SetViewOnBottom(ct.Views.ConvertMenu.Name())
@ -256,18 +267,19 @@ func (ct *Cointop) hideConvertMenu() error {
return nil
}
func (ct *Cointop) toggleConvertMenu() error {
// ToggleConvertMenu toggles the convert menu view
func (ct *Cointop) ToggleConvertMenu() error {
ct.debuglog("toggleConvertMenu()")
ct.State.convertMenuVisible = !ct.State.convertMenuVisible
if ct.State.convertMenuVisible {
return ct.showConvertMenu()
return ct.ShowConvertMenu()
}
return ct.hideConvertMenu()
return ct.HideConvertMenu()
}
// currencySymbol returns the symbol for the currency
func currencySymbol(currency string) string {
symbol, ok := currencySymbolMap[strings.ToUpper(currency)]
// CurrencySymbol returns the symbol for the currency name
func CurrencySymbol(currency string) string {
symbol, ok := CurrencySymbolMap[strings.ToUpper(currency)]
if ok {
return symbol
}

@ -2,7 +2,8 @@ package cointop
import "sort"
func (ct *Cointop) toggleFavorite() error {
// ToggleFavorite toggles coin as favorite
func (ct *Cointop) ToggleFavorite() error {
ct.debuglog("toggleFavorite()")
coin := ct.HighlightedRowCoin()
if coin == nil {
@ -27,7 +28,8 @@ func (ct *Cointop) toggleFavorite() error {
return nil
}
func (ct *Cointop) toggleShowFavorites() error {
// ToggleShowFavorites toggles the favorites view
func (ct *Cointop) ToggleShowFavorites() error {
ct.debuglog("toggleShowFavorites()")
ct.State.portfolioVisible = false
ct.State.filterByFavorites = !ct.State.filterByFavorites
@ -35,7 +37,8 @@ func (ct *Cointop) toggleShowFavorites() error {
return nil
}
func (ct *Cointop) getFavoritesSlice() []*Coin {
// GetFavoritesSlice returns coin favorites as slice
func (ct *Cointop) GetFavoritesSlice() []*Coin {
ct.debuglog("getFavoritesSlice()")
sliced := []*Coin{}
for i := range ct.State.allCoins {

@ -17,7 +17,8 @@ func NewHelpView() *HelpView {
return &HelpView{NewView("help")}
}
func (ct *Cointop) updateHelp() {
// UpdateHelp updates the help views
func (ct *Cointop) UpdateHelp() {
ct.debuglog("updateHelp()")
keys := make([]string, 0, len(ct.State.shortcutKeys))
for k := range ct.State.shortcutKeys {
@ -70,15 +71,17 @@ func (ct *Cointop) updateHelp() {
})
}
func (ct *Cointop) showHelp() error {
// ShowHelp shows the help view
func (ct *Cointop) ShowHelp() error {
ct.debuglog("showHelp()")
ct.State.helpVisible = true
ct.updateHelp()
ct.UpdateHelp()
ct.SetActiveView(ct.Views.Help.Name())
return nil
}
func (ct *Cointop) hideHelp() error {
// HideHelp hides the help view
func (ct *Cointop) HideHelp() error {
ct.debuglog("hideHelp()")
ct.State.helpVisible = false
ct.SetViewOnBottom(ct.Views.Help.Name())
@ -96,11 +99,12 @@ func (ct *Cointop) hideHelp() error {
return nil
}
func (ct *Cointop) toggleHelp() error {
// ToggleHelp toggles the help view
func (ct *Cointop) ToggleHelp() error {
ct.debuglog("toggleHelp()")
ct.State.helpVisible = !ct.State.helpVisible
if ct.State.helpVisible {
return ct.showHelp()
return ct.ShowHelp()
}
return ct.hideHelp()
return ct.HideHelp()
}

@ -6,7 +6,8 @@ import (
"github.com/miguelmota/gocui"
)
func (ct *Cointop) parseKeys(s string) (interface{}, gocui.Modifier) {
// ParseKeys returns string keyboard key as gocui key type
func (ct *Cointop) ParseKeys(s string) (interface{}, gocui.Modifier) {
var key interface{}
mod := gocui.ModNone
split := strings.Split(s, "+")
@ -206,182 +207,184 @@ func (ct *Cointop) parseKeys(s string) (interface{}, gocui.Modifier) {
return key, mod
}
func (ct *Cointop) keybindings(g *gocui.Gui) error {
// Keybindings sets keyboard shortcut key bindings
func (ct *Cointop) Keybindings(g *gocui.Gui) error {
for k, v := range ct.State.shortcutKeys {
if k == "" {
continue
}
v = strings.TrimSpace(strings.ToLower(v))
var fn func(g *gocui.Gui, v *gocui.View) error
key, mod := ct.parseKeys(k)
key, mod := ct.ParseKeys(k)
view := "table"
switch v {
case "move_up":
fn = ct.keyfn(ct.cursorUp)
fn = ct.Keyfn(ct.CursorUp)
case "move_down":
fn = ct.keyfn(ct.cursorDown)
fn = ct.Keyfn(ct.CursorDown)
case "previous_page":
fn = ct.handleHkey(key)
case "next_page":
fn = ct.keyfn(ct.nextPage)
fn = ct.Keyfn(ct.NextPage)
case "page_down":
fn = ct.keyfn(ct.pageDown)
fn = ct.Keyfn(ct.PageDown)
case "page_up":
fn = ct.keyfn(ct.pageUp)
fn = ct.Keyfn(ct.PageUp)
case "sort_column_symbol":
fn = ct.sortfn("symbol", false)
fn = ct.Sortfn("symbol", false)
case "move_to_page_first_row":
fn = ct.keyfn(ct.navigateFirstLine)
fn = ct.Keyfn(ct.NavigateFirstLine)
case "move_to_page_last_row":
fn = ct.keyfn(ct.navigateLastLine)
fn = ct.Keyfn(ct.NavigateLastLine)
case "open_link":
fn = ct.keyfn(ct.OpenLink)
fn = ct.Keyfn(ct.OpenLink)
case "refresh":
fn = ct.keyfn(ct.refresh)
fn = ct.Keyfn(ct.Refresh)
case "sort_column_asc":
fn = ct.keyfn(ct.sortAsc)
fn = ct.Keyfn(ct.SortAsc)
case "sort_column_desc":
fn = ct.keyfn(ct.sortDesc)
fn = ct.Keyfn(ct.SortDesc)
case "sort_left_column":
fn = ct.keyfn(ct.sortPrevCol)
fn = ct.Keyfn(ct.SortPrevCol)
case "sort_right_column":
fn = ct.keyfn(ct.sortNextCol)
fn = ct.Keyfn(ct.SortNextCol)
case "help":
fallthrough
case "toggle_show_help":
fn = ct.keyfn(ct.toggleHelp)
fn = ct.Keyfn(ct.ToggleHelp)
view = ""
case "show_help":
fn = ct.keyfn(ct.showHelp)
fn = ct.Keyfn(ct.ShowHelp)
view = ""
case "hide_help":
fn = ct.keyfn(ct.hideHelp)
fn = ct.Keyfn(ct.HideHelp)
view = "help"
case "first_page":
fn = ct.keyfn(ct.firstPage)
fn = ct.Keyfn(ct.FirstPage)
case "sort_column_1h_change":
fn = ct.sortfn("1hchange", true)
fn = ct.Sortfn("1hchange", true)
case "sort_column_24h_change":
fn = ct.sortfn("24hchange", true)
fn = ct.Sortfn("24hchange", true)
case "sort_column_7d_change":
fn = ct.sortfn("7dchange", true)
fn = ct.Sortfn("7dchange", true)
case "sort_column_available_supply":
fn = ct.sortfn("availablesupply", true)
fn = ct.Sortfn("availablesupply", true)
case "toggle_row_chart":
fn = ct.keyfn(ct.ToggleCoinChart)
fn = ct.Keyfn(ct.ToggleCoinChart)
case "move_to_page_visible_first_row":
fn = ct.keyfn(ct.navigatePageFirstLine)
fn = ct.Keyfn(ct.NavigatePageFirstLine)
case "move_to_page_visible_last_row":
fn = ct.keyfn(ct.navigatePageLastLine)
fn = ct.Keyfn(ct.navigatePageLastLine)
case "sort_column_market_cap":
fn = ct.sortfn("marketcap", true)
fn = ct.Sortfn("marketcap", true)
case "move_to_page_visible_middle_row":
fn = ct.keyfn(ct.navigatePageMiddleLine)
fn = ct.Keyfn(ct.NavigatePageMiddleLine)
case "sort_column_name":
fn = ct.sortfn("name", false)
fn = ct.Sortfn("name", false)
case "sort_column_price":
fn = ct.sortfn("price", true)
fn = ct.Sortfn("price", true)
case "sort_column_rank":
fn = ct.sortfn("rank", false)
fn = ct.Sortfn("rank", false)
case "sort_column_total_supply":
fn = ct.sortfn("totalsupply", true)
fn = ct.Sortfn("totalsupply", true)
case "sort_column_last_updated":
fn = ct.sortfn("lastupdated", true)
fn = ct.Sortfn("lastupdated", true)
case "sort_column_24h_volume":
fn = ct.sortfn("24hvolume", true)
fn = ct.Sortfn("24hvolume", true)
case "sort_column_balance":
fn = ct.sortfn("balance", true)
fn = ct.Sortfn("balance", true)
case "sort_column_holdings":
fn = ct.sortfn("holdings", true)
fn = ct.Sortfn("holdings", true)
case "last_page":
fn = ct.keyfn(ct.lastPage)
fn = ct.Keyfn(ct.LastPage)
case "open_search":
fn = ct.keyfn(ct.openSearch)
fn = ct.Keyfn(ct.openSearch)
view = ""
case "toggle_favorite":
fn = ct.keyfn(ct.toggleFavorite)
fn = ct.Keyfn(ct.ToggleFavorite)
case "toggle_show_favorites":
fn = ct.keyfn(ct.toggleShowFavorites)
fn = ct.Keyfn(ct.ToggleShowFavorites)
case "save":
fn = ct.keyfn(ct.Save)
fn = ct.Keyfn(ct.Save)
case "quit":
fn = ct.keyfn(ct.Quit)
fn = ct.Keyfn(ct.Quit)
view = ""
case "quit_view":
fn = ct.keyfn(ct.QuitView)
fn = ct.Keyfn(ct.QuitView)
case "next_chart_range":
fn = ct.keyfn(ct.NextChartRange)
fn = ct.Keyfn(ct.NextChartRange)
case "previous_chart_range":
fn = ct.keyfn(ct.PrevChartRange)
fn = ct.Keyfn(ct.PrevChartRange)
case "first_chart_range":
fn = ct.keyfn(ct.FirstChartRange)
fn = ct.Keyfn(ct.FirstChartRange)
case "last_chart_range":
fn = ct.keyfn(ct.LastChartRange)
fn = ct.Keyfn(ct.LastChartRange)
case "toggle_show_currency_convert_menu":
fn = ct.keyfn(ct.toggleConvertMenu)
fn = ct.Keyfn(ct.ToggleConvertMenu)
case "show_currency_convert_menu":
fn = ct.keyfn(ct.showConvertMenu)
fn = ct.Keyfn(ct.ShowConvertMenu)
case "hide_currency_convert_menu":
fn = ct.keyfn(ct.hideConvertMenu)
fn = ct.Keyfn(ct.HideConvertMenu)
view = "convertmenu"
case "toggle_portfolio":
fn = ct.keyfn(ct.togglePortfolio)
fn = ct.Keyfn(ct.TogglePortfolio)
case "toggle_show_portfolio":
fn = ct.keyfn(ct.toggleShowPortfolio)
fn = ct.Keyfn(ct.ToggleShowPortfolio)
case "show_portfolio_edit_menu":
fn = ct.keyfn(ct.togglePortfolioUpdateMenu)
fn = ct.Keyfn(ct.TogglePortfolioUpdateMenu)
case "toggle_table_fullscreen":
fn = ct.keyfn(ct.ToggleTableFullscreen)
fn = ct.Keyfn(ct.ToggleTableFullscreen)
view = ""
case "enlarge_chart":
fn = ct.keyfn(ct.EnlargeChart)
fn = ct.Keyfn(ct.EnlargeChart)
case "shorten_chart":
fn = ct.keyfn(ct.ShortenChart)
fn = ct.Keyfn(ct.ShortenChart)
case "move_down_or_next_page":
fn = ct.keyfn(ct.CursorDownOrNextPage)
fn = ct.Keyfn(ct.CursorDownOrNextPage)
case "move_up_or_previous_page":
fn = ct.keyfn(ct.CursorUpOrPreviousPage)
fn = ct.Keyfn(ct.CursorUpOrPreviousPage)
default:
fn = ct.keyfn(ct.noop)
fn = ct.Keyfn(ct.Noop)
}
ct.setKeybindingMod(key, mod, fn, view)
ct.SetKeybindingMod(key, mod, fn, view)
}
// keys to force quit
ct.setKeybindingMod(gocui.KeyCtrlC, gocui.ModNone, ct.keyfn(ct.Quit), "")
ct.setKeybindingMod(gocui.KeyCtrlZ, gocui.ModNone, ct.keyfn(ct.Quit), "")
ct.SetKeybindingMod(gocui.KeyCtrlC, gocui.ModNone, ct.Keyfn(ct.Quit), "")
ct.SetKeybindingMod(gocui.KeyCtrlZ, gocui.ModNone, ct.Keyfn(ct.Quit), "")
// searchfield keys
ct.setKeybindingMod(gocui.KeyEnter, gocui.ModNone, ct.keyfn(ct.doSearch), ct.Views.SearchField.Name())
ct.setKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.keyfn(ct.cancelSearch), ct.Views.SearchField.Name())
ct.SetKeybindingMod(gocui.KeyEnter, gocui.ModNone, ct.Keyfn(ct.DoSearch), ct.Views.SearchField.Name())
ct.SetKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.Keyfn(ct.CancelSearch), ct.Views.SearchField.Name())
// keys to quit help when open
ct.setKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.keyfn(ct.hideHelp), ct.Views.Help.Name())
ct.setKeybindingMod('q', gocui.ModNone, ct.keyfn(ct.hideHelp), ct.Views.Help.Name())
ct.SetKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.Keyfn(ct.HideHelp), ct.Views.Help.Name())
ct.SetKeybindingMod('q', gocui.ModNone, ct.Keyfn(ct.HideHelp), ct.Views.Help.Name())
// keys to quit portfolio update menu when open
ct.setKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.keyfn(ct.hidePortfolioUpdateMenu), ct.Views.Input.Name())
ct.setKeybindingMod('q', gocui.ModNone, ct.keyfn(ct.hidePortfolioUpdateMenu), ct.Views.Input.Name())
ct.SetKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.Keyfn(ct.HidePortfolioUpdateMenu), ct.Views.Input.Name())
ct.SetKeybindingMod('q', gocui.ModNone, ct.Keyfn(ct.HidePortfolioUpdateMenu), ct.Views.Input.Name())
// keys to update portfolio holdings
ct.setKeybindingMod(gocui.KeyEnter, gocui.ModNone, ct.keyfn(ct.setPortfolioHoldings), ct.Views.Input.Name())
ct.SetKeybindingMod(gocui.KeyEnter, gocui.ModNone, ct.Keyfn(ct.SetPortfolioHoldings), ct.Views.Input.Name())
// keys to quit convert menu when open
ct.setKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.keyfn(ct.hideConvertMenu), ct.Views.ConvertMenu.Name())
ct.setKeybindingMod('q', gocui.ModNone, ct.keyfn(ct.hideConvertMenu), ct.Views.ConvertMenu.Name())
ct.SetKeybindingMod(gocui.KeyEsc, gocui.ModNone, ct.Keyfn(ct.HideConvertMenu), ct.Views.ConvertMenu.Name())
ct.SetKeybindingMod('q', gocui.ModNone, ct.Keyfn(ct.HideConvertMenu), ct.Views.ConvertMenu.Name())
// character key press to select option
// TODO: use scrolling table
keys := ct.sortedSupportedCurrencyConversions()
keys := ct.SortedSupportedCurrencyConversions()
for i, k := range keys {
ct.setKeybindingMod(rune(alphanumericcharacters[i]), gocui.ModNone, ct.keyfn(ct.setCurrencyConverstionFn(k)), ct.Views.ConvertMenu.Name())
ct.SetKeybindingMod(rune(alphanumericcharacters[i]), gocui.ModNone, ct.Keyfn(ct.SetCurrencyConverstionFn(k)), ct.Views.ConvertMenu.Name())
}
return nil
}
func (ct *Cointop) setKeybindingMod(key interface{}, mod gocui.Modifier, callback func(g *gocui.Gui, v *gocui.View) error, view string) error {
// SetKeybindingMod sets the keybinding modifier key
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:
@ -392,23 +395,26 @@ func (ct *Cointop) setKeybindingMod(key interface{}, mod gocui.Modifier, callbac
return err
}
func (ct *Cointop) keyfn(fn func() error) func(g *gocui.Gui, v *gocui.View) error {
// Keyfn returns the keybinding function as a wrapped gocui view function
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()
}
}
// 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 {
ct.sortToggle("holdings", true)
ct.SortToggle("holdings", true)
} else {
ct.prevPage()
ct.PrevPage()
}
return nil
}
}
func (ct *Cointop) noop() error {
// Noop is a no-operation function
func (ct *Cointop) Noop() error {
return nil
}

@ -51,11 +51,11 @@ func (ct *Cointop) layout(g *gocui.Gui) error {
ct.Views.Marketbar.Backing().Frame = false
ct.colorscheme.SetViewColor(ct.Views.Marketbar.Backing(), "marketbar")
go func() {
ct.updateMarketbar()
ct.UpdateMarketbar()
_, found := ct.cache.Get(ct.Views.Marketbar.Name())
if found {
ct.cache.Delete(ct.Views.Marketbar.Name())
ct.updateMarketbar()
ct.UpdateMarketbar()
}
}()
}
@ -123,7 +123,7 @@ func (ct *Cointop) layout(g *gocui.Gui) error {
ct.cache.Delete("allCoinsSlugMap")
}
go func() {
ct.updateCoins()
ct.UpdateCoins()
ct.UpdateTable()
}()
}
@ -209,7 +209,7 @@ func (ct *Cointop) layout(g *gocui.Gui) error {
if lastWidth != maxX {
lastWidth = maxX
ct.refresh()
ct.Refresh()
}
return nil

@ -10,7 +10,8 @@ import (
var coinslock sync.Mutex
var updatecoinsmux sync.Mutex
func (ct *Cointop) updateCoins() error {
// UpdateCoins updates coins view
func (ct *Cointop) UpdateCoins() error {
ct.debuglog("updateCoins()")
coinslock.Lock()
defer coinslock.Unlock()
@ -45,6 +46,7 @@ func (ct *Cointop) updateCoins() error {
return nil
}
// ProcessCoinsMap processes coins map
func (ct *Cointop) processCoinsMap(coinsMap map[string]types.Coin) {
ct.debuglog("processCoinsMap()")
var coins []types.Coin
@ -55,6 +57,7 @@ func (ct *Cointop) processCoinsMap(coinsMap map[string]types.Coin) {
ct.processCoins(coins)
}
// ProcessCoins processes coins list
func (ct *Cointop) processCoins(coins []types.Coin) {
ct.debuglog("processCoins()")
updatecoinsmux.Lock()
@ -137,12 +140,13 @@ func (ct *Cointop) processCoins(coins []types.Coin) {
}
time.AfterFunc(10*time.Millisecond, func() {
ct.sort(ct.State.sortBy, ct.State.sortDesc, ct.State.coins, true)
ct.Sort(ct.State.sortBy, ct.State.sortDesc, ct.State.coins, true)
ct.UpdateTable()
})
}
func (ct *Cointop) getListCount() int {
// GetListCount returns count of coins list
func (ct *Cointop) GetListCount() int {
ct.debuglog("getListCount()")
if ct.State.filterByFavorites {
return len(ct.State.favorites)

@ -22,7 +22,8 @@ func NewMarketbarView() *MarketbarView {
return &MarketbarView{NewView("marketbar")}
}
func (ct *Cointop) updateMarketbar() error {
// UpdateMarketbar updates the market bar view
func (ct *Cointop) UpdateMarketbar() error {
ct.debuglog("updateMarketbar()")
if ct.Views.Marketbar.Backing() == nil {
return nil
@ -36,7 +37,7 @@ func (ct *Cointop) updateMarketbar() error {
var content string
if ct.State.portfolioVisible {
total := ct.getPortfolioTotal()
total := ct.GetPortfolioTotal()
totalstr := humanize.Commaf(total)
if !(ct.State.currencyConversion == "BTC" || ct.State.currencyConversion == "ETH" || total < 1) {
total = math.Round(total*1e2) / 1e2
@ -44,7 +45,7 @@ func (ct *Cointop) updateMarketbar() error {
}
timeframe := ct.State.selectedChartRange
chartname := ct.selectedCoinName()
chartname := ct.SelectedCoinName()
var charttitle string
if chartname == "" {
chartname = "Portfolio"
@ -54,7 +55,7 @@ func (ct *Cointop) updateMarketbar() error {
}
var percentChange24H float64
for _, p := range ct.getPortfolioSlice() {
for _, p := range ct.GetPortfolioSlice() {
n := ((p.Balance / total) * p.PercentChange24H)
if math.IsNaN(n) {
continue
@ -85,7 +86,7 @@ func (ct *Cointop) updateMarketbar() error {
content = fmt.Sprintf(
"%sTotal Portfolio Value: %s • 24H: %s",
chartInfo,
ct.colorscheme.MarketBarLabelActive(fmt.Sprintf("%s%s", ct.currencySymbol(), totalstr)),
ct.colorscheme.MarketBarLabelActive(fmt.Sprintf("%s%s", ct.CurrencySymbol(), totalstr)),
color24h(fmt.Sprintf("%.2f%%%s", percentChange24H, arrow)),
)
} else {
@ -116,7 +117,7 @@ func (ct *Cointop) updateMarketbar() error {
}
timeframe := ct.State.selectedChartRange
chartname := ct.selectedCoinName()
chartname := ct.SelectedCoinName()
if chartname == "" {
chartname = "Global"
}
@ -133,8 +134,8 @@ func (ct *Cointop) updateMarketbar() error {
content = fmt.Sprintf(
"%sGlobal ▶ Market Cap: %s • 24H Volume: %s • BTC Dominance: %.2f%%",
chartInfo,
fmt.Sprintf("%s%s", ct.currencySymbol(), humanize.Commaf0(market.TotalMarketCapUSD)),
fmt.Sprintf("%s%s", ct.currencySymbol(), humanize.Commaf0(market.Total24HVolumeUSD)),
fmt.Sprintf("%s%s", ct.CurrencySymbol(), humanize.Commaf0(market.TotalMarketCapUSD)),
fmt.Sprintf("%s%s", ct.CurrencySymbol(), humanize.Commaf0(market.Total24HVolumeUSD)),
market.BitcoinPercentageOfMarketCap,
)
}

@ -1,45 +1,52 @@
package cointop
func (ct *Cointop) currentPage() int {
// CurrentPage returns the current page
func (ct *Cointop) CurrentPage() int {
ct.debuglog("currentPage()")
return ct.State.page + 1
}
func (ct *Cointop) currentDisplayPage() int {
// CurrentDisplayPage returns the current page in human readable format
func (ct *Cointop) CurrentDisplayPage() int {
ct.debuglog("currentDisplayPage()")
return ct.State.page + 1
}
func (ct *Cointop) totalPages() int {
// TotalPages returns the number of total pages
func (ct *Cointop) TotalPages() int {
ct.debuglog("totalPages()")
return ct.getListCount() / ct.State.perPage
return ct.GetListCount() / ct.State.perPage
}
func (ct *Cointop) totalPagesDisplay() int {
// TotalPagesDisplay returns the number of total pages in human readable format
func (ct *Cointop) TotalPagesDisplay() int {
ct.debuglog("totalPagesDisplay()")
return ct.totalPages() + 1
return ct.TotalPages() + 1
}
func (ct *Cointop) totalPerPage() int {
// TotalPerPage returns the number max rows per page
func (ct *Cointop) TotalPerPage() int {
return ct.State.perPage
}
func (ct *Cointop) setPage(page int) int {
// SetPage navigates to the selected page
func (ct *Cointop) SetPage(page int) int {
ct.debuglog("setPage()")
if (page*ct.State.perPage) < ct.getListCount() && page >= 0 {
if (page*ct.State.perPage) < ct.GetListCount() && page >= 0 {
ct.State.page = page
}
return ct.State.page
}
func (ct *Cointop) cursorDown() error {
// CursorDown moves the cursor one row down
func (ct *Cointop) CursorDown() error {
ct.debuglog("cursorDown()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the bottom
if ct.isLastRow() {
if ct.IsLastRow() {
return nil
}
@ -56,14 +63,15 @@ func (ct *Cointop) cursorDown() error {
return nil
}
func (ct *Cointop) cursorUp() error {
// CursorUp moves the cursor one row up
func (ct *Cointop) CursorUp() error {
ct.debuglog("cursorUp()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the top
if ct.isFirstRow() {
if ct.IsFirstRow() {
return nil
}
@ -80,14 +88,15 @@ func (ct *Cointop) cursorUp() error {
return nil
}
func (ct *Cointop) pageDown() error {
// PageDown moves the cursor one page down
func (ct *Cointop) PageDown() error {
ct.debuglog("pageDown()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the bottom
if ct.isLastRow() {
if ct.IsLastRow() {
return nil
}
@ -119,14 +128,15 @@ func (ct *Cointop) pageDown() error {
return nil
}
func (ct *Cointop) pageUp() error {
// PageUp moves the cursor one page up
func (ct *Cointop) PageUp() error {
ct.debuglog("pageUp()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the top
if ct.isFirstRow() {
if ct.IsFirstRow() {
return nil
}
@ -150,14 +160,15 @@ func (ct *Cointop) pageUp() error {
return nil
}
func (ct *Cointop) navigateFirstLine() error {
// NavigateFirstLine moves the cursor to the first row of the table
func (ct *Cointop) NavigateFirstLine() error {
ct.debuglog("navigateFirstLine()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the top
if ct.isFirstRow() {
if ct.IsFirstRow() {
return nil
}
@ -174,14 +185,15 @@ func (ct *Cointop) navigateFirstLine() error {
return nil
}
func (ct *Cointop) navigateLastLine() error {
// NavigateLastLine moves the cursor to the last row of the table
func (ct *Cointop) NavigateLastLine() error {
ct.debuglog("navigateLastLine()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the bottom
if ct.isLastRow() {
if ct.IsLastRow() {
return nil
}
@ -201,14 +213,15 @@ func (ct *Cointop) navigateLastLine() error {
return nil
}
func (ct *Cointop) navigatePageFirstLine() error {
// NavigatePageFirstLine moves the cursor to the visible first row of the table
func (ct *Cointop) NavigatePageFirstLine() error {
ct.debuglog("navigatePageFirstLine()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the correct line
if ct.isPageFirstLine() {
if ct.IsPageFirstLine() {
return nil
}
@ -220,14 +233,15 @@ func (ct *Cointop) navigatePageFirstLine() error {
return nil
}
func (ct *Cointop) navigatePageMiddleLine() error {
// NavigatePageMiddleLine moves the cursor to the visible middle row of the table
func (ct *Cointop) NavigatePageMiddleLine() error {
ct.debuglog("navigatePageMiddleLine()")
if ct.Views.Table.Backing() == nil {
return nil
}
// NOTE: return if already at the correct line
if ct.isPageMiddleLine() {
if ct.IsPageMiddleLine() {
return nil
}
@ -240,6 +254,7 @@ func (ct *Cointop) navigatePageMiddleLine() error {
return nil
}
// NavigatePageLastLine moves the cursor to the visible last row of the table
func (ct *Cointop) navigatePageLastLine() error {
ct.debuglog("navigatePageLastLine()")
if ct.Views.Table.Backing() == nil {
@ -247,7 +262,7 @@ func (ct *Cointop) navigatePageLastLine() error {
}
// NOTE: return if already at the correct line
if ct.isPageLastLine() {
if ct.IsPageLastLine() {
return nil
}
@ -260,57 +275,62 @@ func (ct *Cointop) navigatePageLastLine() error {
return nil
}
func (ct *Cointop) prevPage() error {
ct.debuglog("prevPage()")
// NextPage navigates to the next page
func (ct *Cointop) NextPage() error {
ct.debuglog("nextPage()")
// NOTE: return if already at the first page
if ct.isFirstPage() {
// NOTE: return if already at the last page
if ct.IsLastPage() {
return nil
}
ct.setPage(ct.State.page - 1)
ct.SetPage(ct.State.page + 1)
ct.UpdateTable()
ct.RowChanged()
return nil
}
func (ct *Cointop) nextPage() error {
ct.debuglog("nextPage()")
// PrevPage navigates to the previous page
func (ct *Cointop) PrevPage() error {
ct.debuglog("prevPage()")
// NOTE: return if already at the last page
if ct.isLastPage() {
// NOTE: return if already at the first page
if ct.IsFirstPage() {
return nil
}
ct.setPage(ct.State.page + 1)
ct.SetPage(ct.State.page - 1)
ct.UpdateTable()
ct.RowChanged()
return nil
}
// NextPageTop navigates to the first row of the next page
func (ct *Cointop) nextPageTop() error {
ct.debuglog("nextPageTop()")
ct.nextPage()
ct.navigateFirstLine()
ct.NextPage()
ct.NavigateFirstLine()
return nil
}
func (ct *Cointop) prevPageTop() error {
// PrevPageTop navigates to the first row of the previous page
func (ct *Cointop) PrevPageTop() error {
ct.debuglog("prevtPageTop()")
ct.prevPage()
ct.navigateLastLine()
ct.PrevPage()
ct.NavigateLastLine()
return nil
}
func (ct *Cointop) firstPage() error {
// FirstPage navigates to the first page
func (ct *Cointop) FirstPage() error {
ct.debuglog("firstPage()")
// NOTE: return if already at the first page
if ct.isFirstPage() {
if ct.IsFirstPage() {
return nil
}
@ -320,7 +340,23 @@ func (ct *Cointop) firstPage() error {
return nil
}
func (ct *Cointop) isFirstRow() bool {
// LastPage navigates to the last page
func (ct *Cointop) LastPage() error {
ct.debuglog("lastPage()")
// NOTE: return if already at the last page
if ct.IsLastPage() {
return nil
}
ct.State.page = ct.GetListCount() / ct.State.perPage
ct.UpdateTable()
ct.RowChanged()
return nil
}
// IsFirstRow returns true if cursor is on first row
func (ct *Cointop) IsFirstRow() bool {
ct.debuglog("isFirstRow()")
_, y := ct.Views.Table.Backing().Origin()
@ -329,7 +365,8 @@ func (ct *Cointop) isFirstRow() bool {
return (cy + y) == 0
}
func (ct *Cointop) isLastRow() bool {
// IsLastRow returns true if cursor is on last row
func (ct *Cointop) IsLastRow() bool {
ct.debuglog("isLastRow()")
_, y := ct.Views.Table.Backing().Origin()
@ -339,24 +376,28 @@ func (ct *Cointop) isLastRow() bool {
return (cy + y + 1) > numRows
}
func (ct *Cointop) isFirstPage() bool {
// IsFirstPage returns true if cursor is on the first page
func (ct *Cointop) IsFirstPage() bool {
ct.debuglog("isFirstPage()")
return ct.State.page == 0
}
func (ct *Cointop) isLastPage() bool {
// IsLastPage returns true if cursor is on the last page
func (ct *Cointop) IsLastPage() bool {
ct.debuglog("isLastPage()")
return ct.State.page == ct.totalPages()-1
return ct.State.page == ct.TotalPages()-1
}
func (ct *Cointop) isPageFirstLine() bool {
// IsPageFirstLine returns true if the cursor is on the visible first row
func (ct *Cointop) IsPageFirstLine() bool {
ct.debuglog("isPageFirstLine()")
_, cy := ct.Views.Table.Backing().Cursor()
return cy == 0
}
func (ct *Cointop) isPageMiddleLine() bool {
// IsPageMiddleLine returns true if the cursor is on the visible middle row
func (ct *Cointop) IsPageMiddleLine() bool {
ct.debuglog("isPageMiddleLine()")
_, cy := ct.Views.Table.Backing().Cursor()
@ -364,7 +405,8 @@ func (ct *Cointop) isPageMiddleLine() bool {
return (sy/2)-1 == cy
}
func (ct *Cointop) isPageLastLine() bool {
// IsPageLastLine returns true if the cursor is on the visible last row
func (ct *Cointop) IsPageLastLine() bool {
ct.debuglog("isPageLastLine()")
_, cy := ct.Views.Table.Backing().Cursor()
@ -372,21 +414,8 @@ func (ct *Cointop) isPageLastLine() bool {
return cy+1 == sy
}
func (ct *Cointop) lastPage() error {
ct.debuglog("lastPage()")
// NOTE: return if already at the last page
if ct.isLastPage() {
return nil
}
ct.State.page = ct.getListCount() / ct.State.perPage
ct.UpdateTable()
ct.RowChanged()
return nil
}
func (ct *Cointop) goToPageRowIndex(idx int) error {
// GoToPageRowIndex navigates to the selected row index of the page
func (ct *Cointop) GoToPageRowIndex(idx int) error {
ct.debuglog("goToPageRowIndex()")
if ct.Views.Table.Backing() == nil {
return nil
@ -399,25 +428,27 @@ func (ct *Cointop) goToPageRowIndex(idx int) error {
return nil
}
func (ct *Cointop) goToGlobalIndex(idx int) error {
// GoToGlobalIndex navigates to the selected row index of all page rows
func (ct *Cointop) GoToGlobalIndex(idx int) error {
ct.debuglog("goToGlobalIndex()")
perpage := ct.totalPerPage()
perpage := ct.TotalPerPage()
atpage := idx / perpage
ct.setPage(atpage)
ct.SetPage(atpage)
rowIndex := (idx % perpage)
ct.highlightRow(rowIndex)
ct.HighlightRow(rowIndex)
ct.UpdateTable()
return nil
}
func (ct *Cointop) highlightRow(idx int) error {
// HighlightRow highlights the row at index
func (ct *Cointop) HighlightRow(idx int) error {
ct.debuglog("highlightRow()")
ct.Views.Table.Backing().SetOrigin(0, 0)
ct.Views.Table.Backing().SetCursor(0, 0)
ox, _ := ct.Views.Table.Backing().Origin()
cx, _ := ct.Views.Table.Backing().Cursor()
_, sy := ct.Views.Table.Backing().Size()
perpage := ct.totalPerPage()
perpage := ct.TotalPerPage()
p := idx % perpage
oy := (p / sy) * sy
cy := p % sy
@ -429,11 +460,11 @@ func (ct *Cointop) highlightRow(idx int) error {
return nil
}
// CursorDownOrNextPage ...
// 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()")
if ct.isLastRow() {
if ct.isLastPage() {
if ct.IsLastRow() {
if ct.IsLastPage() {
return nil
}
@ -444,29 +475,29 @@ func (ct *Cointop) CursorDownOrNextPage() error {
return nil
}
if err := ct.cursorDown(); err != nil {
if err := ct.CursorDown(); err != nil {
return err
}
return nil
}
// CursorUpOrPreviousPage ...
// CursorUpOrPreviousPage moves the cursor up one row or goes to the previous page if cursor is on the first row
func (ct *Cointop) CursorUpOrPreviousPage() error {
ct.debuglog("CursorUpOrPreviousPage()")
if ct.isFirstRow() {
if ct.isFirstPage() {
if ct.IsFirstRow() {
if ct.IsFirstPage() {
return nil
}
if err := ct.prevPageTop(); err != nil {
if err := ct.PrevPageTop(); err != nil {
return err
}
return nil
}
if err := ct.cursorUp(); err != nil {
if err := ct.CursorUp(); err != nil {
return err
}

@ -20,10 +20,11 @@ func NewPortfolioUpdateMenuView() *PortfolioUpdateMenuView {
return &PortfolioUpdateMenuView{NewView("portfolioupdatemenu")}
}
func (ct *Cointop) togglePortfolio() error {
// TogglePortfolio toggles the portfolio view
func (ct *Cointop) TogglePortfolio() error {
ct.debuglog("togglePortfolio()")
if ct.State.portfolioVisible {
ct.goToPageRowIndex(ct.State.lastSelectedRowIndex)
ct.GoToPageRowIndex(ct.State.lastSelectedRowIndex)
} else {
ct.State.lastSelectedRowIndex = ct.HighlightedPageRowIndex()
}
@ -36,7 +37,8 @@ func (ct *Cointop) togglePortfolio() error {
return nil
}
func (ct *Cointop) toggleShowPortfolio() error {
// ToggleShowPortfolio shows the portfolio view
func (ct *Cointop) ToggleShowPortfolio() error {
ct.debuglog("toggleShowPortfolio()")
ct.State.filterByFavorites = false
ct.State.portfolioVisible = true
@ -45,26 +47,29 @@ func (ct *Cointop) toggleShowPortfolio() error {
return nil
}
func (ct *Cointop) togglePortfolioUpdateMenu() error {
// TogglePortfolioUpdateMenu toggles the portfolio update menu
func (ct *Cointop) TogglePortfolioUpdateMenu() error {
ct.debuglog("togglePortfolioUpdateMenu()")
ct.State.portfolioUpdateMenuVisible = !ct.State.portfolioUpdateMenuVisible
if ct.State.portfolioUpdateMenuVisible {
return ct.showPortfolioUpdateMenu()
return ct.ShowPortfolioUpdateMenu()
}
return ct.hidePortfolioUpdateMenu()
return ct.HidePortfolioUpdateMenu()
}
func (ct *Cointop) coinHoldings(coin *Coin) float64 {
// CoinHoldings returns portfolio coin holdings
func (ct *Cointop) CoinHoldings(coin *Coin) float64 {
entry, _ := ct.PortfolioEntry(coin)
return entry.Holdings
}
func (ct *Cointop) updatePortfolioUpdateMenu() {
// UpdatePortfolioUpdateMenu updates the portfolio update menu view
func (ct *Cointop) UpdatePortfolioUpdateMenu() {
ct.debuglog("updatePortfolioUpdateMenu()")
coin := ct.HighlightedRowCoin()
exists := ct.PortfolioEntryExists(coin)
value := strconv.FormatFloat(ct.coinHoldings(coin), 'f', -1, 64)
value := strconv.FormatFloat(ct.CoinHoldings(coin), 'f', -1, 64)
ct.debuglog(fmt.Sprintf("holdings %v", value))
var mode string
var current string
@ -91,22 +96,24 @@ func (ct *Cointop) updatePortfolioUpdateMenu() {
})
}
func (ct *Cointop) showPortfolioUpdateMenu() error {
// ShowPortfolioUpdateMenu shows the portfolio update menu
func (ct *Cointop) ShowPortfolioUpdateMenu() error {
ct.debuglog("showPortfolioUpdateMenu()")
coin := ct.HighlightedRowCoin()
if coin == nil {
ct.togglePortfolio()
ct.TogglePortfolio()
return nil
}
ct.State.lastSelectedRowIndex = ct.HighlightedPageRowIndex()
ct.State.portfolioUpdateMenuVisible = true
ct.updatePortfolioUpdateMenu()
ct.UpdatePortfolioUpdateMenu()
ct.SetActiveView(ct.Views.PortfolioUpdateMenu.Name())
return nil
}
func (ct *Cointop) hidePortfolioUpdateMenu() error {
// HidePortfolioUpdateMenu hides the portfolio update menu
func (ct *Cointop) HidePortfolioUpdateMenu() error {
ct.debuglog("hidePortfolioUpdateMenu()")
ct.State.portfolioUpdateMenuVisible = false
ct.SetViewOnBottom(ct.Views.PortfolioUpdateMenu.Name())
@ -129,10 +136,10 @@ func (ct *Cointop) hidePortfolioUpdateMenu() error {
return nil
}
// sets portfolio entry holdings from inputed value
func (ct *Cointop) setPortfolioHoldings() error {
// SetPortfolioHoldings sets portfolio entry holdings from inputed value
func (ct *Cointop) SetPortfolioHoldings() error {
ct.debuglog("setPortfolioHoldings()")
defer ct.hidePortfolioUpdateMenu()
defer ct.HidePortfolioUpdateMenu()
coin := ct.HighlightedRowCoin()
// read input field
@ -145,7 +152,7 @@ func (ct *Cointop) setPortfolioHoldings() error {
return nil
}
value := normalizeFloatstring(string(b))
value := normalizeFloatString(string(b))
shouldDelete := value == ""
var holdings float64
@ -156,16 +163,16 @@ func (ct *Cointop) setPortfolioHoldings() error {
}
}
if err := ct.setPortfolioEntry(coin.Name, holdings); err != nil {
if err := ct.SetPortfolioEntry(coin.Name, holdings); err != nil {
return err
}
if shouldDelete {
ct.removePortfolioEntry(coin.Name)
ct.RemovePortfolioEntry(coin.Name)
ct.UpdateTable()
} else {
ct.UpdateTable()
ct.goToPageRowIndex(ct.State.lastSelectedRowIndex)
ct.GoToPageRowIndex(ct.State.lastSelectedRowIndex)
}
return nil
@ -197,7 +204,8 @@ func (ct *Cointop) PortfolioEntry(c *Coin) (*PortfolioEntry, bool) {
return p, isNew
}
func (ct *Cointop) setPortfolioEntry(coin string, holdings float64) error {
// SetPortfolioEntry sets a portfolio entry
func (ct *Cointop) SetPortfolioEntry(coin string, holdings float64) error {
ct.debuglog("setPortfolioEntry()")
ic, _ := ct.State.allCoinsSlugMap.Load(strings.ToLower(coin))
c, _ := ic.(*Coin)
@ -219,7 +227,8 @@ func (ct *Cointop) setPortfolioEntry(coin string, holdings float64) error {
return nil
}
func (ct *Cointop) removePortfolioEntry(coin string) {
// RemovePortfolioEntry removes a portfolio entry
func (ct *Cointop) RemovePortfolioEntry(coin string) {
ct.debuglog("removePortfolioEntry()")
delete(ct.State.portfolio.Entries, strings.ToLower(coin))
}
@ -231,15 +240,17 @@ func (ct *Cointop) PortfolioEntryExists(c *Coin) bool {
return !isNew
}
func (ct *Cointop) portfolioEntriesCount() int {
// PortfolioEntriesCount returns the count of portfolio entries
func (ct *Cointop) PortfolioEntriesCount() int {
ct.debuglog("portfolioEntriesCount()")
return len(ct.State.portfolio.Entries)
}
func (ct *Cointop) getPortfolioSlice() []*Coin {
// GetPortfolioSlice returns portfolio entries as a slice
func (ct *Cointop) GetPortfolioSlice() []*Coin {
ct.debuglog("getPortfolioSlice()")
sliced := []*Coin{}
if ct.portfolioEntriesCount() == 0 {
if ct.PortfolioEntriesCount() == 0 {
return sliced
}
@ -271,9 +282,10 @@ func (ct *Cointop) getPortfolioSlice() []*Coin {
return sliced
}
func (ct *Cointop) getPortfolioTotal() float64 {
// GetPortfolioTotal returns the total balance of portfolio entries
func (ct *Cointop) GetPortfolioTotal() float64 {
ct.debuglog("getPortfolioTotal()")
portfolio := ct.getPortfolioSlice()
portfolio := ct.GetPortfolioSlice()
var total float64
for _, p := range portfolio {
total += p.Balance
@ -281,7 +293,8 @@ func (ct *Cointop) getPortfolioTotal() float64 {
return total
}
func normalizeFloatstring(input string) string {
// NormalizeFloatString normalizes a float as a string
func normalizeFloatString(input string) string {
re := regexp.MustCompile(`(\d+\.\d+|\.\d+|\d+)`)
result := re.FindStringSubmatch(input)
if len(result) > 0 {

@ -5,7 +5,8 @@ import (
"time"
)
func (ct *Cointop) refresh() error {
// Refresh triggers a force refresh of coin data
func (ct *Cointop) Refresh() error {
ct.debuglog("refresh()")
go func() {
<-ct.limiter
@ -14,7 +15,8 @@ func (ct *Cointop) refresh() error {
return nil
}
func (ct *Cointop) refreshAll() error {
// RefreshAll triggers a force refresh of all data
func (ct *Cointop) RefreshAll() error {
ct.debuglog("refreshAll()")
ct.refreshMux.Lock()
defer ct.refreshMux.Unlock()
@ -22,13 +24,14 @@ func (ct *Cointop) refreshAll() error {
ct.cache.Delete("allCoinsSlugMap")
ct.cache.Delete("market")
go func() {
ct.updateCoins()
ct.UpdateCoins()
ct.UpdateTable()
ct.UpdateChart()
}()
return nil
}
// SetRefreshStatus sets the refresh ticker
func (ct *Cointop) setRefreshStatus() {
ct.debuglog("setRefreshStatus()")
go func() {
@ -37,6 +40,7 @@ func (ct *Cointop) setRefreshStatus() {
}()
}
// LoadingTicks sets the loading ticking dots
func (ct *Cointop) loadingTicks(s string, t int) {
ct.debuglog("loadingTicks()")
interval := 150
@ -51,15 +55,16 @@ func (ct *Cointop) loadingTicks(s string, t int) {
}
}
// intervalFetchData does a force refresh at every interval
func (ct *Cointop) intervalFetchData() {
ct.debuglog("intervalFetchData()")
go func() {
for {
select {
case <-ct.forceRefresh:
ct.refreshAll()
ct.RefreshAll()
case <-ct.refreshTicker.C:
ct.refreshAll()
ct.RefreshAll()
}
}
}()

@ -4,7 +4,7 @@ package cointop
func (ct *Cointop) Save() error {
ct.debuglog("Save()")
ct.SetSavingStatus()
if err := ct.saveConfig(); err != nil {
if err := ct.SaveConfig(); err != nil {
return err
}

@ -27,6 +27,7 @@ func NewInputView() *InputView {
return &InputView{NewView("input")}
}
// OpenSearch opens the search field
func (ct *Cointop) openSearch() error {
ct.debuglog("openSearch()")
ct.State.searchFieldVisible = true
@ -34,14 +35,16 @@ func (ct *Cointop) openSearch() error {
return nil
}
func (ct *Cointop) cancelSearch() error {
// CancelSearch closes the search field
func (ct *Cointop) CancelSearch() error {
ct.debuglog("cancelSearch()")
ct.State.searchFieldVisible = false
ct.SetActiveView(ct.Views.Table.Name())
return nil
}
func (ct *Cointop) doSearch() error {
// DoSearch triggers the search and sets views
func (ct *Cointop) DoSearch() error {
ct.debuglog("doSearch()")
ct.Views.SearchField.Backing().Rewind()
b := make([]byte, 100)
@ -65,10 +68,11 @@ func (ct *Cointop) doSearch() error {
if len(matches) > 0 {
q = matches[1]
}
return ct.search(q)
return ct.Search(q)
}
func (ct *Cointop) search(q string) error {
// Search performs the search and filtering
func (ct *Cointop) Search(q string) error {
ct.debuglog("search()")
q = strings.TrimSpace(strings.ToLower(q))
idx := -1
@ -81,12 +85,12 @@ func (ct *Cointop) search(q string) error {
symbol := strings.ToLower(coin.Symbol)
// if query matches symbol, return immediately
if symbol == q {
ct.goToGlobalIndex(i)
ct.GoToGlobalIndex(i)
return nil
}
// if query matches name, return immediately
if name == q {
ct.goToGlobalIndex(i)
ct.GoToGlobalIndex(i)
return nil
}
// store index with the smallest levenshtein
@ -105,12 +109,12 @@ func (ct *Cointop) search(q string) error {
}
// go to row if prefix match
if len(hasprefixidx) > 0 && hasprefixidx[0] != -1 && min > 0 {
ct.goToGlobalIndex(hasprefixidx[0])
ct.GoToGlobalIndex(hasprefixidx[0])
return nil
}
// go to row if levenshtein distance is small enough
if idx > -1 && min <= 6 {
ct.goToGlobalIndex(idx)
ct.GoToGlobalIndex(idx)
return nil
}
return nil

@ -1,6 +1,7 @@
package cointop
func (ct *Cointop) selectedCoinName() string {
// SelectedCoinName returns the selected coin name
func (ct *Cointop) SelectedCoinName() string {
ct.debuglog("selectedCoinName()")
coin := ct.State.selectedCoin
if coin != nil {
@ -10,7 +11,8 @@ func (ct *Cointop) selectedCoinName() string {
return ""
}
func (ct *Cointop) selectedCoinSymbol() string {
// SelectedCoinSymbol returns the selected coin symbol
func (ct *Cointop) SelectedCoinSymbol() string {
ct.debuglog("selectedCoinSymbol()")
coin := ct.State.selectedCoin
if coin != nil {

@ -9,7 +9,8 @@ import (
var sortlock sync.Mutex
func (ct *Cointop) sort(sortBy string, desc bool, list []*Coin, renderHeaders bool) {
// Sort sorts the list of coins
func (ct *Cointop) Sort(sortBy string, desc bool, list []*Coin, renderHeaders bool) {
ct.debuglog("sort()")
sortlock.Lock()
defer sortlock.Unlock()
@ -72,70 +73,77 @@ func (ct *Cointop) sort(sortBy string, desc bool, list []*Coin, renderHeaders bo
}
}
func (ct *Cointop) sortAsc() error {
// SortAsc sorts list of coins in ascending order
func (ct *Cointop) SortAsc() error {
ct.debuglog("sortAsc()")
ct.State.sortDesc = false
ct.UpdateTable()
return nil
}
func (ct *Cointop) sortDesc() error {
// SortDesc sorts list of coins in descending order
func (ct *Cointop) SortDesc() error {
ct.debuglog("sortDesc()")
ct.State.sortDesc = true
ct.UpdateTable()
return nil
}
func (ct *Cointop) sortPrevCol() error {
// SortPrevCol sorts the previous column
func (ct *Cointop) SortPrevCol() error {
ct.debuglog("sortPrevCol()")
nextsortBy := ct.TableColumnOrder[0]
i := ct.getSortColIndex()
i := ct.GetSortColIndex()
k := i - 1
if k < 0 {
k = 0
}
nextsortBy = ct.TableColumnOrder[k]
ct.sort(nextsortBy, ct.State.sortDesc, ct.State.coins, true)
ct.Sort(nextsortBy, ct.State.sortDesc, ct.State.coins, true)
ct.UpdateTable()
return nil
}
func (ct *Cointop) sortNextCol() error {
// SortNextCol sorts the next column
func (ct *Cointop) SortNextCol() error {
ct.debuglog("sortNextCol()")
nextsortBy := ct.TableColumnOrder[0]
l := len(ct.TableColumnOrder)
i := ct.getSortColIndex()
i := ct.GetSortColIndex()
k := i + 1
if k > l-1 {
k = l - 1
}
nextsortBy = ct.TableColumnOrder[k]
ct.sort(nextsortBy, ct.State.sortDesc, ct.State.coins, true)
ct.Sort(nextsortBy, ct.State.sortDesc, ct.State.coins, true)
ct.UpdateTable()
return nil
}
func (ct *Cointop) sortToggle(sortBy string, desc bool) error {
// SortToggle toggles the sort order
func (ct *Cointop) SortToggle(sortBy string, desc bool) error {
ct.debuglog("sortToggle()")
if ct.State.sortBy == sortBy {
desc = !ct.State.sortDesc
}
ct.sort(sortBy, desc, ct.State.coins, true)
ct.Sort(sortBy, desc, ct.State.coins, true)
ct.UpdateTable()
return nil
}
func (ct *Cointop) sortfn(sortBy string, desc bool) func(g *gocui.Gui, v *gocui.View) error {
// Sortfn returns the sort function as a wrapped gocui keybinding function
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)
return ct.SortToggle(sortBy, desc)
}
}
func (ct *Cointop) getSortColIndex() int {
// GetSortColIndex gets the sort column index
func (ct *Cointop) GetSortColIndex() int {
ct.debuglog("getSortColIndex()")
for i, col := range ct.TableColumnOrder {
if ct.State.sortBy == col {

@ -32,8 +32,8 @@ func (statusbar *StatusbarView) Update(str string) error {
// UpdateStatusbar updates the statusbar view
func (ct *Cointop) UpdateStatusbar(s string) error {
ct.debuglog("UpdateStatusbar()")
currpage := ct.currentDisplayPage()
totalpages := ct.totalPagesDisplay()
currpage := ct.CurrentDisplayPage()
totalpages := ct.TotalPagesDisplay()
var quitText string
var favoritesText string
var portfolioText string

@ -63,7 +63,7 @@ func (ct *Cointop) RefreshTable() error {
ct.table.AddCol("")
ct.table.AddCol("")
total := ct.getPortfolioTotal()
total := ct.GetPortfolioTotal()
for _, coin := range ct.State.coins {
unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64)
@ -190,7 +190,7 @@ func (ct *Cointop) RefreshTable() error {
// 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)
ct.HighlightRow(currentrow)
}
ct.Update(func() error {
@ -202,7 +202,7 @@ func (ct *Cointop) RefreshTable() error {
ct.table.Format().Fprint(ct.Views.Table.Backing())
go ct.RowChanged()
go ct.UpdateTableHeader()
go ct.updateMarketbar()
go ct.UpdateMarketbar()
go ct.UpdateChart()
return nil
})
@ -224,9 +224,9 @@ func (ct *Cointop) UpdateTable() error {
})
if ct.State.filterByFavorites {
ct.State.coins = ct.getFavoritesSlice()
ct.State.coins = ct.GetFavoritesSlice()
} else if ct.State.portfolioVisible {
ct.State.coins = ct.getPortfolioSlice()
ct.State.coins = ct.GetPortfolioSlice()
} else {
// TODO: maintain state of previous sorting
if ct.State.sortBy == "holdings" {
@ -237,7 +237,7 @@ func (ct *Cointop) UpdateTable() error {
ct.State.coins = ct.GetTableCoinsSlice()
}
ct.sort(ct.State.sortBy, ct.State.sortDesc, ct.State.coins, true)
ct.Sort(ct.State.sortBy, ct.State.sortDesc, ct.State.coins, true)
go ct.RefreshTable()
return nil
}

@ -77,7 +77,7 @@ func (ct *Cointop) UpdateTableHeader() {
var str string
d := s.arrow + s.displaytext
if v == "price" || v == "balance" {
d = s.arrow + ct.currencySymbol() + s.displaytext
d = s.arrow + ct.CurrencySymbol() + s.displaytext
}
str = fmt.Sprintf(

Loading…
Cancel
Save