summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Mota <hello@miguelmota.com>2021-09-13 22:07:13 -0700
committerMiguel Mota <hello@miguelmota.com>2021-09-13 22:07:13 -0700
commit1d293631851f3af7f4680b5d4209c59a24b0f646 (patch)
tree1f4b0235b5dc16d3777ba8df89ffda1bf8b368ae
parent5f76e89a0be481796fe1c33bc75beb4966c6fbe1 (diff)
Add keybinding to toggle hide portfolio balancesv1.6.7
-rw-r--r--cmd/commands/holdings.go3
-rw-r--r--cmd/commands/root.go35
-rw-r--r--cointop/cointop.go37
-rw-r--r--cointop/default_shortcuts.go163
-rw-r--r--cointop/keybindings.go2
-rw-r--r--cointop/marketbar.go4
-rw-r--r--cointop/portfolio.go22
-rw-r--r--docs/content/faq.md4
8 files changed, 156 insertions, 114 deletions
diff --git a/cmd/commands/holdings.go b/cmd/commands/holdings.go
index 8f3cef3..47b8267 100644
--- a/cmd/commands/holdings.go
+++ b/cmd/commands/holdings.go
@@ -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",
@@ -68,6 +69,7 @@ func HoldingsCmd() *cobra.Command {
Cols: cols,
Convert: convert,
NoHeader: noHeader,
+ HideBalances: hideBalances,
})
},
}
@@ -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")
diff --git a/cmd/commands/root.go b/cmd/commands/root.go
index 4aab35f..160c4be 100644
--- a/cmd/commands/root.go
+++ b/cmd/commands/root.go
@@ -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")
@@ -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
@@ -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")
diff --git a/cointop/cointop.go b/cointop/cointop.go
index 98a1d03..dbbaa89 100644
--- a/cointop/cointop.go
+++ b/cointop/cointop.go
@@ -57,6 +57,7 @@ type State struct {
hideChart bool
hideTable bool
hideStatusbar bool
+ hidePortfolioBalances bool
keepRowFocusOnSort bool
lastSelectedRowIndex int
marketBarHeight int
@@ -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
@@ -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),
diff --git a/cointop/default_shortcuts.go b/cointop/default_shortcuts.go
index f1bdafa..8dc8ff1 100644
--- a/cointop/default_shortcuts.go
+++ b/cointop/default_shortcuts.go
@@ -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",
}
}
diff --git a/cointop/keybindings.go b/cointop/keybindings.go
index 3b8ed5e..cb2993c 100644
--- a/cointop/keybindings.go
+++ b/cointop/keybindings.go
@@ -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":
diff --git a/cointop/marketbar.go b/cointop/marketbar.go
index e2a0eec..fb50cd3 100644
--- a/cointop/marketbar.go
+++ b/cointop/marketbar.go
@@ -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
diff --git a/cointop/portfolio.go b/cointop/portfolio.go
index aefb44c..1a09560 100644
--- a/cointop/portfolio.go
+++ b/cointop/portfolio.go
@@ -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 {
@@ -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
@@ -634,6 +640,7 @@ type TablePrintOptions struct {
Convert string
NoHeader bool
PercentChange24H bool
+ HideBalances bool
}
// outputFormats is list of valid output formats
@@ -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"
@@ -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))
@@ -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
+}
diff --git a/docs/content/faq.md b/docs/content/faq.md
index 6cca90d..feb1a56 100644
--- a/docs/content/faq.md
+++ b/docs/content/faq.md
@@ -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.