Skip to content

Commit

Permalink
Add keybinding to toggle hide portfolio balances
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmota committed Sep 14, 2021
1 parent 5f76e89 commit 1d29363
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 114 deletions.
3 changes: 3 additions & 0 deletions cmd/commands/holdings.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func HoldingsCmd() *cobra.Command {
var filter []string
var cols []string
var convert string
var hideBalances bool

holdingsCmd := &cobra.Command{
Use: "holdings",
Expand Down Expand Up @@ -68,6 +69,7 @@ func HoldingsCmd() *cobra.Command {
Cols: cols,
Convert: convert,
NoHeader: noHeader,
HideBalances: hideBalances,
})
},
}
Expand All @@ -78,6 +80,7 @@ func HoldingsCmd() *cobra.Command {
holdingsCmd.Flags().BoolVarP(&noCache, "no-cache", "", noCache, "No cache")
holdingsCmd.Flags().BoolVarP(&humanReadable, "human", "h", humanReadable, "Human readable output")
holdingsCmd.Flags().BoolVarP(&noHeader, "no-header", "", noHeader, "Don't display header columns")
holdingsCmd.Flags().BoolVarP(&hideBalances, "hide-balances", "", hideBalances, "Hide portfolio balances. Useful for when sharing screen or taking screenshotss")
holdingsCmd.Flags().StringVarP(&config, "config", "c", "", fmt.Sprintf("Config filepath. (default %s)", cointop.DefaultConfigFilepath))
holdingsCmd.Flags().StringVarP(&sortBy, "sort-by", "s", sortBy, `Sort by column. Options are "name", "symbol", "price", "holdings", "balance", "24h"`)
holdingsCmd.Flags().BoolVarP(&sortDesc, "sort-desc", "d", sortDesc, "Sort in descending order")
Expand Down
35 changes: 19 additions & 16 deletions cmd/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func RootCmd() *cobra.Command {
hideChart := getEnvBool("COINTOP_HIDE_CHART")
hideTable := getEnvBool("COINTOP_HIDE_TABLE")
hideStatusbar := getEnvBool("COINTOP_HIDE_STATUSBAR")
hidePortfolioBalances := getEnvBool("COINTOP_HIDE_PORTFOLIO_BALANCES")
onlyTable := getEnvBool("COINTOP_ONLY_TABLE")
onlyChart := getEnvBool("COINTOP_ONLY_CHART")
silent := getEnvBool("COINTOP_SILENT")
Expand Down Expand Up @@ -90,22 +91,23 @@ See git.io/cointop for more info.`,
}

ct, err := cointop.NewCointop(&cointop.Config{
CacheDir: cacheDir,
ColorsDir: colorsDir,
NoCache: noCache,
ConfigFilepath: config,
CoinMarketCapAPIKey: cmcAPIKey,
APIChoice: apiChoice,
Colorscheme: colorscheme,
HideMarketbar: hideMarketbar,
HideChart: hideChart,
HideTable: hideTable,
HideStatusbar: hideStatusbar,
OnlyTable: onlyTable,
OnlyChart: onlyChart,
RefreshRate: refreshRateP,
PerPage: perPage,
MaxPages: maxPages,
CacheDir: cacheDir,
ColorsDir: colorsDir,
NoCache: noCache,
ConfigFilepath: config,
CoinMarketCapAPIKey: cmcAPIKey,
APIChoice: apiChoice,
Colorscheme: colorscheme,
HideMarketbar: hideMarketbar,
HideChart: hideChart,
HideTable: hideTable,
HideStatusbar: hideStatusbar,
OnlyTable: onlyTable,
OnlyChart: onlyChart,
RefreshRate: refreshRateP,
PerPage: perPage,
MaxPages: maxPages,
HidePortfolioBalances: hidePortfolioBalances,
})
if err != nil {
return err
Expand All @@ -123,6 +125,7 @@ See git.io/cointop for more info.`,
rootCmd.Flags().BoolVarP(&hideChart, "hide-chart", "", hideChart, "Hide the chart view")
rootCmd.Flags().BoolVarP(&hideTable, "hide-table", "", hideTable, "Hide the table view")
rootCmd.Flags().BoolVarP(&hideStatusbar, "hide-statusbar", "", hideStatusbar, "Hide the bottom statusbar")
rootCmd.Flags().BoolVarP(&hidePortfolioBalances, "hide-portfolio-balances", "", hidePortfolioBalances, "Hide portfolio balances. Useful for when sharing screen or taking screenshots")
rootCmd.Flags().BoolVarP(&onlyTable, "only-table", "", onlyTable, "Show only the table. Hides the chart and top and bottom bars")
rootCmd.Flags().BoolVarP(&onlyChart, "only-chart", "", onlyChart, "Show only the chart. Hides the table and top and bottom bars")
rootCmd.Flags().BoolVarP(&silent, "silent", "s", silent, "Silence log ouput")
Expand Down
37 changes: 20 additions & 17 deletions cointop/cointop.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type State struct {
hideChart bool
hideTable bool
hideStatusbar bool
hidePortfolioBalances bool
keepRowFocusOnSort bool
lastSelectedRowIndex int
marketBarHeight int
Expand Down Expand Up @@ -147,23 +148,24 @@ type PriceAlerts struct {

// Config config options
type Config struct {
APIChoice string
CacheDir string
ColorsDir string
Colorscheme string
ConfigFilepath string
CoinMarketCapAPIKey string
NoPrompts bool
HideMarketbar bool
HideChart bool
HideTable bool
HideStatusbar bool
NoCache bool
OnlyTable bool
OnlyChart bool
RefreshRate *uint
PerPage uint
MaxPages uint
APIChoice string
CacheDir string
ColorsDir string
Colorscheme string
ConfigFilepath string
CoinMarketCapAPIKey string
NoPrompts bool
HideMarketbar bool
HideChart bool
HideTable bool
HideStatusbar bool
HidePortfolioBalances bool
NoCache bool
OnlyTable bool
OnlyChart bool
RefreshRate *uint
PerPage uint
MaxPages uint
}

// APIKeys is api keys structure
Expand Down Expand Up @@ -251,6 +253,7 @@ func NewCointop(config *Config) (*Cointop, error) {
hideChart: config.HideChart,
hideTable: config.HideTable,
hideStatusbar: config.HideStatusbar,
hidePortfolioBalances: config.HidePortfolioBalances,
keepRowFocusOnSort: false,
marketBarHeight: 1,
maxPages: int(maxPages),
Expand Down
163 changes: 82 additions & 81 deletions cointop/default_shortcuts.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,86 +3,87 @@ package cointop
// DefaultShortcuts is a map of the default shortcuts
func DefaultShortcuts() map[string]string {
return map[string]string{
"up": "move_up",
"down": "move_down",
"left": "previous_page",
"right": "next_page",
"pagedown": "page_down",
"pageup": "page_up",
"home": "move_to_page_first_row",
"end": "move_to_page_last_row",
"enter": "toggle_row_chart",
"esc": "quit_view",
"space": "toggle_favorite",
"tab": "move_down_or_next_page",
"ctrl+c": "quit",
"ctrl+C": "quit",
"ctrl+d": "page_down",
"ctrl+f": "open_search",
"ctrl+n": "next_page",
"ctrl+p": "previous_page",
"ctrl+r": "refresh",
"ctrl+R": "refresh",
"ctrl+s": "save",
"ctrl+S": "save",
"ctrl+u": "page_up",
"ctrl+j": "enlarge_chart",
"ctrl+k": "shorten_chart",
"|": "toggle_chart_fullscreen",
"alt+up": "sort_column_asc",
"alt+down": "sort_column_desc",
"alt+left": "sort_left_column",
"alt+right": "sort_right_column",
"F1": "help",
"F5": "refresh",
"0": "first_page",
"1": "sort_column_1h_change",
"2": "sort_column_24h_change",
"3": "sort_column_30d_change",
"7": "sort_column_7d_change",
"a": "sort_column_available_supply",
"b": "sort_column_balance",
"c": "show_currency_convert_menu",
"C": "show_currency_convert_menu",
"e": "show_portfolio_edit_menu",
"E": "show_portfolio_edit_menu",
"A": "toggle_price_alerts",
"f": "toggle_favorite",
"F": "toggle_show_favorites",
"g": "move_to_page_first_row",
"G": "move_to_page_last_row",
"h": "previous_page",
"H": "move_to_page_visible_first_row",
"j": "move_down",
"k": "move_up",
"l": "next_page",
"L": "move_to_page_visible_last_row",
"m": "sort_column_market_cap",
"M": "move_to_page_visible_middle_row",
"n": "sort_column_name",
"o": "open_link",
"O": "open_link",
"p": "sort_column_price",
"P": "toggle_portfolio",
"r": "sort_column_rank",
"s": "sort_column_symbol",
"t": "sort_column_total_supply",
"u": "sort_column_last_updated",
"v": "sort_column_24h_volume",
"y": "sort_column_1y_change",
"q": "quit_view",
"Q": "quit_view",
"%": "sort_column_percent_holdings",
"$": "last_page",
"?": "help",
"/": "open_search",
"]": "next_chart_range",
"[": "previous_chart_range",
"}": "last_chart_range",
"{": "first_chart_range",
">": "scroll_right",
"<": "scroll_left",
"+": "show_price_alert_add_menu",
"\\\\": "toggle_table_fullscreen",
"up": "move_up",
"down": "move_down",
"left": "previous_page",
"right": "next_page",
"pagedown": "page_down",
"pageup": "page_up",
"home": "move_to_page_first_row",
"end": "move_to_page_last_row",
"enter": "toggle_row_chart",
"esc": "quit_view",
"space": "toggle_favorite",
"tab": "move_down_or_next_page",
"ctrl+c": "quit",
"ctrl+C": "quit",
"ctrl+d": "page_down",
"ctrl+f": "open_search",
"ctrl+n": "next_page",
"ctrl+p": "previous_page",
"ctrl+r": "refresh",
"ctrl+R": "refresh",
"ctrl+s": "save",
"ctrl+S": "save",
"ctrl+u": "page_up",
"ctrl+j": "enlarge_chart",
"ctrl+k": "shorten_chart",
"ctrl+space": "toggle_portfolio_balances",
"|": "toggle_chart_fullscreen",
"alt+up": "sort_column_asc",
"alt+down": "sort_column_desc",
"alt+left": "sort_left_column",
"alt+right": "sort_right_column",
"F1": "help",
"F5": "refresh",
"0": "first_page",
"1": "sort_column_1h_change",
"2": "sort_column_24h_change",
"3": "sort_column_30d_change",
"7": "sort_column_7d_change",
"a": "sort_column_available_supply",
"b": "sort_column_balance",
"c": "show_currency_convert_menu",
"C": "show_currency_convert_menu",
"e": "show_portfolio_edit_menu",
"E": "show_portfolio_edit_menu",
"A": "toggle_price_alerts",
"f": "toggle_favorite",
"F": "toggle_show_favorites",
"g": "move_to_page_first_row",
"G": "move_to_page_last_row",
"h": "previous_page",
"H": "move_to_page_visible_first_row",
"j": "move_down",
"k": "move_up",
"l": "next_page",
"L": "move_to_page_visible_last_row",
"m": "sort_column_market_cap",
"M": "move_to_page_visible_middle_row",
"n": "sort_column_name",
"o": "open_link",
"O": "open_link",
"p": "sort_column_price",
"P": "toggle_portfolio",
"r": "sort_column_rank",
"s": "sort_column_symbol",
"t": "sort_column_total_supply",
"u": "sort_column_last_updated",
"v": "sort_column_24h_volume",
"y": "sort_column_1y_change",
"q": "quit_view",
"Q": "quit_view",
"%": "sort_column_percent_holdings",
"$": "last_page",
"?": "help",
"/": "open_search",
"]": "next_chart_range",
"[": "previous_chart_range",
"}": "last_chart_range",
"{": "first_chart_range",
">": "scroll_right",
"<": "scroll_left",
"+": "show_price_alert_add_menu",
"\\\\": "toggle_table_fullscreen",
}
}
2 changes: 2 additions & 0 deletions cointop/keybindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ func (ct *Cointop) SetKeybindingAction(shortcutKey string, action string) error
fn = ct.Keyfn(ct.TogglePortfolio)
case "toggle_show_portfolio":
fn = ct.Keyfn(ct.ToggleShowPortfolio)
case "toggle_portfolio_balances":
fn = ct.Keyfn(ct.TogglePortfolioBalances)
case "show_portfolio_edit_menu":
fn = ct.Keyfn(ct.TogglePortfolioUpdateMenu)
case "show_price_alert_edit_menu":
Expand Down
4 changes: 4 additions & 0 deletions cointop/marketbar.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func (ct *Cointop) UpdateMarketbar() error {
totalstr = humanize.Monetaryf(total, 2)
}

if ct.State.hidePortfolioBalances {
totalstr = HiddenBalanceChars
}

timeframe := ct.State.selectedChartRange
chartname := ct.SelectedCoinName()
var charttitle string
Expand Down
22 changes: 22 additions & 0 deletions cointop/portfolio.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ var DefaultPortfolioTableHeaders = []string{
"last_updated",
}

// HiddenBalanceChars are the characters to show when hidding balances
var HiddenBalanceChars = "********"

// ValidPortfolioTableHeader returns the portfolio table headers
func (ct *Cointop) ValidPortfolioTableHeader(name string) bool {
for _, v := range SupportedPortfolioTableHeaders {
Expand Down Expand Up @@ -154,6 +157,9 @@ func (ct *Cointop) GetPortfolioTable() *table.Table {
})
case "balance":
text := humanize.Monetaryf(coin.Balance, 2)
if ct.State.hidePortfolioBalances {
text = HiddenBalanceChars
}
ct.SetTableColumnWidthFromString(header, text)
ct.SetTableColumnAlignLeft(header, false)
colorBalance := ct.colorscheme.TableColumnPrice
Expand Down Expand Up @@ -634,6 +640,7 @@ type TablePrintOptions struct {
Convert string
NoHeader bool
PercentChange24H bool
HideBalances bool
}

// outputFormats is list of valid output formats
Expand Down Expand Up @@ -674,6 +681,7 @@ func (ct *Cointop) PrintHoldingsTable(options *TablePrintOptions) error {
filterCols := options.Cols
holdings := ct.GetPortfolioSlice()
noHeader := options.NoHeader
hideBalances := options.HideBalances

if format == "" {
format = "table"
Expand Down Expand Up @@ -771,6 +779,9 @@ func (ct *Cointop) PrintHoldingsTable(options *TablePrintOptions) error {
} else {
item[i] = strconv.FormatFloat(entry.Balance, 'f', -1, 64)
}
if hideBalances {
item[i] = HiddenBalanceChars
}
case "24h%":
if humanReadable {
item[i] = fmt.Sprintf("%s%%", humanize.Numericf(entry.PercentChange24H, 2))
Expand Down Expand Up @@ -1034,3 +1045,14 @@ func (ct *Cointop) IsPortfolioVisible() bool {
func (ct *Cointop) PortfolioLen() int {
return len(ct.GetPortfolioSlice())
}

// TogglePortfolioBalances toggles hide/show portfolio balances. Useful for keeping balances secret when sharing screen or taking screenshots.
func (ct *Cointop) TogglePortfolioBalances() error {
ct.State.hidePortfolioBalances = !ct.State.hidePortfolioBalances
ct.UpdateUI(func() error {
go ct.UpdateChart()
go ct.UpdateTable()
return nil
})
return nil
}
4 changes: 4 additions & 0 deletions docs/content/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ draft: false

Your portfolio is autosaved after you edit holdings. You can also press <kbd>ctrl</kbd>+<kbd>s</kbd> to manually save your portfolio holdings to the config file.

## How do I hide my portfolio balances (private mode)?

You can run cointop with the `--hide-portfolio-balances` flag to toggle hide/show portfolio balances or use the keyboard shortcut <kbd>Ctrl</kbd>+<kbd>space</kbd> on the portfolio page.

## I'm getting question marks or weird symbols instead of the correct characters.

Make sure that your terminal has the encoding set to UTF-8 and that your terminal font supports UTF-8.
Expand Down

0 comments on commit 1d29363

Please sign in to comment.