Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions internal/ui/component/summary/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ func (m *Model) View() string {
m.styles.TextLabel("Change: ") + quoteChangeText(m.summary.TotalChange.Amount, m.summary.TotalChange.Percent, m.styles)
widthChange := ansi.PrintableRuneWidth(textChange)
textValue := m.styles.TextLabel(" • ") +
m.styles.TextLabel("Value: ") + m.styles.TextLabel(u.ConvertFloatToString(m.summary.Value, false))
m.styles.TextLabel("Value: ") + m.styles.TextLabel(u.ConvertFloatToStringWithCommas(m.summary.Value, false))
widthValue := ansi.PrintableRuneWidth(textValue)
textCost := m.styles.TextLabel(" • ") +
m.styles.TextLabel("Cost: ") + m.styles.TextLabel(u.ConvertFloatToString(m.summary.Cost, false))
m.styles.TextLabel("Cost: ") + m.styles.TextLabel(u.ConvertFloatToStringWithCommas(m.summary.Cost, false))
widthCost := ansi.PrintableRuneWidth(textValue)

return grid.Render(grid.Grid{
Expand Down Expand Up @@ -103,12 +103,12 @@ func (m *Model) View() string {

func quoteChangeText(change float64, changePercent float64, styles c.Styles) string {
if change == 0.0 {
return styles.TextLabel(u.ConvertFloatToString(change, false) + " (" + u.ConvertFloatToString(changePercent, false) + "%)")
return styles.TextLabel(u.ConvertFloatToStringWithCommas(change, false) + " (" + u.ConvertFloatToStringWithCommas(changePercent, false) + "%)")
}

if change > 0.0 {
return styles.TextPrice(changePercent, "↑ "+u.ConvertFloatToString(change, false)+" ("+u.ConvertFloatToString(changePercent, false)+"%)")
return styles.TextPrice(changePercent, "↑ "+u.ConvertFloatToStringWithCommas(change, false)+" ("+u.ConvertFloatToStringWithCommas(changePercent, false)+"%)")
}

return styles.TextPrice(changePercent, "↓ "+u.ConvertFloatToString(change, false)+" ("+u.ConvertFloatToString(changePercent, false)+"%)")
return styles.TextPrice(changePercent, "↓ "+u.ConvertFloatToStringWithCommas(change, false)+" ("+u.ConvertFloatToStringWithCommas(changePercent, false)+"%)")
}
4 changes: 2 additions & 2 deletions internal/ui/component/summary/summary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var _ = Describe("Summary", func() {
},
}))
Expect(removeFormatting(m.View())).To(Equal(strings.Join([]string{
"Day Change: ↑ 100.00 (10.00%) • Change: ↑ 9000.00 (1000.00%) • Value: 10000.00 • Cost: 1000.00 ",
"Day Change: ↑ 100.00 (10.00%) • Change: ↑ 9,000.00 (1,000.00%) • Value: 10,000.00 • Cost: 1,000.00 ",
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
}, "\n")))
})
Expand All @@ -69,7 +69,7 @@ var _ = Describe("Summary", func() {
},
}))
Expect(removeFormatting(m.View())).To(Equal(strings.Join([]string{
"Day Change: ↓ -100.00 (-10.00%) • Change: ↓ -9000.00 (-1000.00%) • Value: 1000.00 • Cost: 10000.00",
"Day Change: ↓ -100.00 (-10.00%) • Change: ↓ -9,000.00 (-1,000.00%) • Value: 1,000.00 • Cost: 10,000.00",
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
}, "\n")))
})
Expand Down
50 changes: 25 additions & 25 deletions internal/ui/component/watchlist/row/row.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func New(config Config) *Model {
id: id,
width: 80,
config: config,
priceNoChangeSegment: u.ConvertFloatToString(config.Asset.QuotePrice.Price, config.Asset.Meta.IsVariablePrecision),
priceNoChangeSegment: u.ConvertFloatToStringWithCommas(config.Asset.QuotePrice.Price, config.Asset.Meta.IsVariablePrecision),
priceChangeSegment: "",
}
}
Expand All @@ -111,8 +111,8 @@ func (m *Model) Update(msg tea.Msg) (*Model, tea.Cmd) {
m.priceStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("15")).Background(lipgloss.Color(""))
m.frame = 0

oldPrice := u.ConvertFloatToString(m.config.Asset.QuotePrice.Price, m.config.Asset.Meta.IsVariablePrecision)
newPrice := u.ConvertFloatToString(msg.QuotePrice.Price, msg.Meta.IsVariablePrecision)
oldPrice := u.ConvertFloatToStringWithCommas(m.config.Asset.QuotePrice.Price, m.config.Asset.Meta.IsVariablePrecision)
newPrice := u.ConvertFloatToStringWithCommas(msg.QuotePrice.Price, msg.Meta.IsVariablePrecision)

if msg.QuotePrice.Price > m.config.Asset.QuotePrice.Price {
m.priceChangeDirection = 1
Expand Down Expand Up @@ -147,7 +147,7 @@ func (m *Model) Update(msg tea.Msg) (*Model, tea.Cmd) {

// If symbol has changed or price has not changed then just update the asset
m.config.Asset = msg
m.priceNoChangeSegment = u.ConvertFloatToString(msg.QuotePrice.Price, msg.Meta.IsVariablePrecision)
m.priceNoChangeSegment = u.ConvertFloatToStringWithCommas(msg.QuotePrice.Price, msg.Meta.IsVariablePrecision)
m.priceChangeSegment = ""

return m, nil
Expand Down Expand Up @@ -366,7 +366,7 @@ func textPosition(asset *c.Asset, styles c.Styles) string {
positionValue = u.ValueText(asset.Holding.Value, styles) +
styles.TextLight(
" ("+
u.ConvertFloatToString(asset.Holding.Weight, asset.Meta.IsVariablePrecision)+"%"+
u.ConvertFloatToStringWithCommas(asset.Holding.Weight, asset.Meta.IsVariablePrecision)+"%"+
")")
}
if asset.Holding.TotalChange.Amount != 0.0 {
Expand All @@ -385,19 +385,19 @@ func textQuoteExtended(asset *c.Asset, styles c.Styles) string {
}

if asset.Class == c.AssetClassFuturesContract {
return styles.Text(u.ConvertFloatToString(asset.QuoteFutures.IndexPrice, asset.Meta.IsVariablePrecision)) +
return styles.Text(u.ConvertFloatToStringWithCommas(asset.QuoteFutures.IndexPrice, asset.Meta.IsVariablePrecision)) +
"\n" +
styles.Text(u.ConvertFloatToString(asset.QuoteFutures.Basis, false)) + "%"
styles.Text(u.ConvertFloatToStringWithCommas(asset.QuoteFutures.Basis, false)) + "%"
}

if asset.QuotePrice.PriceOpen == 0.0 {
return styles.Text(u.ConvertFloatToString(asset.QuotePrice.PricePrevClose, asset.Meta.IsVariablePrecision)) +
return styles.Text(u.ConvertFloatToStringWithCommas(asset.QuotePrice.PricePrevClose, asset.Meta.IsVariablePrecision)) +
"\n"
}

return styles.Text(u.ConvertFloatToString(asset.QuotePrice.PricePrevClose, asset.Meta.IsVariablePrecision)) +
return styles.Text(u.ConvertFloatToStringWithCommas(asset.QuotePrice.PricePrevClose, asset.Meta.IsVariablePrecision)) +
"\n" +
styles.Text(u.ConvertFloatToString(asset.QuotePrice.PriceOpen, asset.Meta.IsVariablePrecision))
styles.Text(u.ConvertFloatToStringWithCommas(asset.QuotePrice.PriceOpen, asset.Meta.IsVariablePrecision))

}

Expand Down Expand Up @@ -429,9 +429,9 @@ func textPositionExtended(asset *c.Asset, styles c.Styles) string {
return ""
}

return styles.Text(u.ConvertFloatToString(asset.Holding.UnitCost, asset.Meta.IsVariablePrecision)) +
return styles.Text(u.ConvertFloatToStringWithCommas(asset.Holding.UnitCost, asset.Meta.IsVariablePrecision)) +
"\n" +
styles.Text(u.ConvertFloatToString(asset.Holding.Quantity, asset.Meta.IsVariablePrecision))
styles.Text(u.ConvertFloatToStringWithCommas(asset.Holding.Quantity, asset.Meta.IsVariablePrecision))

}

Expand All @@ -451,9 +451,9 @@ func textQuoteRange(asset *c.Asset, styles c.Styles) string {
if asset.Class == c.AssetClassFuturesContract {

if asset.QuotePrice.PriceDayHigh != 0.0 && asset.QuotePrice.PriceDayLow != 0.0 {
return u.ConvertFloatToString(asset.QuotePrice.PriceDayLow, asset.Meta.IsVariablePrecision) +
return u.ConvertFloatToStringWithCommas(asset.QuotePrice.PriceDayLow, asset.Meta.IsVariablePrecision) +
styles.Text(" - ") +
u.ConvertFloatToString(asset.QuotePrice.PriceDayHigh, asset.Meta.IsVariablePrecision) +
u.ConvertFloatToStringWithCommas(asset.QuotePrice.PriceDayHigh, asset.Meta.IsVariablePrecision) +
"\n" +
asset.QuoteFutures.Expiry
}
Expand All @@ -463,13 +463,13 @@ func textQuoteRange(asset *c.Asset, styles c.Styles) string {
}

if asset.QuotePrice.PriceDayHigh != 0.0 && asset.QuotePrice.PriceDayLow != 0.0 {
return u.ConvertFloatToString(asset.QuotePrice.PriceDayLow, asset.Meta.IsVariablePrecision) +
return u.ConvertFloatToStringWithCommas(asset.QuotePrice.PriceDayLow, asset.Meta.IsVariablePrecision) +
styles.Text(" - ") +
u.ConvertFloatToString(asset.QuotePrice.PriceDayHigh, asset.Meta.IsVariablePrecision) +
u.ConvertFloatToStringWithCommas(asset.QuotePrice.PriceDayHigh, asset.Meta.IsVariablePrecision) +
"\n" +
u.ConvertFloatToString(asset.QuoteExtended.FiftyTwoWeekLow, asset.Meta.IsVariablePrecision) +
u.ConvertFloatToStringWithCommas(asset.QuoteExtended.FiftyTwoWeekLow, asset.Meta.IsVariablePrecision) +
styles.Text(" - ") +
u.ConvertFloatToString(asset.QuoteExtended.FiftyTwoWeekHigh, asset.Meta.IsVariablePrecision)
u.ConvertFloatToStringWithCommas(asset.QuoteExtended.FiftyTwoWeekHigh, asset.Meta.IsVariablePrecision)
}

return ""
Expand Down Expand Up @@ -501,14 +501,14 @@ func textQuoteRangeLabels(asset *c.Asset, styles c.Styles) string {
func textVolumeMarketCap(asset *c.Asset) string {

if asset.Class == c.AssetClassFuturesContract {
return u.ConvertFloatToString(asset.QuoteFutures.OpenInterest, true) +
return u.ConvertFloatToStringWithCommas(asset.QuoteFutures.OpenInterest, true) +
"\n" +
u.ConvertFloatToString(asset.QuoteExtended.Volume, true)
u.ConvertFloatToStringWithCommas(asset.QuoteExtended.Volume, true)
}

return u.ConvertFloatToString(asset.QuoteExtended.MarketCap, true) +
return u.ConvertFloatToStringWithCommas(asset.QuoteExtended.MarketCap, true) +
"\n" +
u.ConvertFloatToString(asset.QuoteExtended.Volume, true)
u.ConvertFloatToStringWithCommas(asset.QuoteExtended.Volume, true)
}
func textVolumeMarketCapLabels(asset *c.Asset, styles c.Styles) string {

Expand Down Expand Up @@ -537,14 +537,14 @@ func textMarketState(asset *c.Asset, styles c.Styles) string {

func quoteChangeText(change float64, changePercent float64, isVariablePrecision bool, styles c.Styles) string {
if change == 0.0 {
return styles.TextPrice(changePercent, " "+u.ConvertFloatToString(change, isVariablePrecision)+" ("+u.ConvertFloatToString(changePercent, false)+"%)")
return styles.TextPrice(changePercent, " "+u.ConvertFloatToStringWithCommas(change, isVariablePrecision)+" ("+u.ConvertFloatToStringWithCommas(changePercent, false)+"%)")
}

if change > 0.0 {
return styles.TextPrice(changePercent, "↑ "+u.ConvertFloatToString(change, isVariablePrecision)+" ("+u.ConvertFloatToString(changePercent, false)+"%)")
return styles.TextPrice(changePercent, "↑ "+u.ConvertFloatToStringWithCommas(change, isVariablePrecision)+" ("+u.ConvertFloatToStringWithCommas(changePercent, false)+"%)")
}

return styles.TextPrice(changePercent, "↓ "+u.ConvertFloatToString(change, isVariablePrecision)+" ("+u.ConvertFloatToString(changePercent, false)+"%)")
return styles.TextPrice(changePercent, "↓ "+u.ConvertFloatToStringWithCommas(change, isVariablePrecision)+" ("+u.ConvertFloatToStringWithCommas(changePercent, false)+"%)")
}

func textSeparator(width int, styles c.Styles) string {
Expand Down
4 changes: 2 additions & 2 deletions internal/ui/component/watchlist/row/row_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ var _ = Describe("Row", func() {

view := stripANSI(outputRow.View())
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
Expect(view).To(ContainSubstring("1500.00"), "output was: %q", view)
Expect(view).To(ContainSubstring("1,500.00"), "output was: %q", view)
Expect(cmd).ToNot(BeNil())

// Simulate frame updates
Expand All @@ -196,7 +196,7 @@ var _ = Describe("Row", func() {
view = stripANSI(outputRow.View())
Expect(cmd).To(BeNil(), "expected cmd to be nil after final frame, got: %v", cmd)
Expect(view).To(ContainSubstring("AAPL"), "output was: %q", view)
Expect(view).To(ContainSubstring("1500.00"), "output was: %q", view)
Expect(view).To(ContainSubstring("1,500.00"), "output was: %q", view)
})

})
Expand Down
51 changes: 46 additions & 5 deletions internal/ui/component/watchlist/watchlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type SetAssetsMsg []c.Asset
// Messages for updating assets
type UpdateAssetsMsg []c.Asset

// Messages for changing sort
type ChangeSortMsg string

// NewModel returns a model with default values
func NewModel(config Config) *Model {
return &Model{
Expand Down Expand Up @@ -138,6 +141,44 @@ func (m *Model) Update(msg tea.Msg) (*Model, tea.Cmd) {

return m, tea.Batch(cmds...)

case ChangeSortMsg:

var cmd tea.Cmd
cmds := make([]tea.Cmd, 0)

// Update the sorter with the new sort option
m.config.Sort = string(msg)
m.sorter = s.NewSorter(m.config.Sort)

// Re-sort and update the assets
assets := m.sorter(m.assets)
m.assets = assets

// Update rows with the new order (similar to SetAssetsMsg)
for i, asset := range assets {
if i < len(m.rows) {
m.rows[i], cmd = m.rows[i].Update(row.UpdateAssetMsg(asset))
cmds = append(cmds, cmd)
} else {
// Create new row if needed
m.rows = append(m.rows, row.New(row.Config{
Separate: m.config.Separate,
ExtraInfoExchange: m.config.ExtraInfoExchange,
ExtraInfoFundamentals: m.config.ExtraInfoFundamentals,
ShowHoldings: m.config.ShowHoldings,
Styles: m.config.Styles,
Asset: asset,
}))
}
}

// Remove extra rows if needed
if len(assets) < len(m.rows) {
m.rows = m.rows[:len(assets)]
}

return m, tea.Batch(cmds...)

}

return m, nil
Expand Down Expand Up @@ -165,14 +206,14 @@ func getCellWidths(assets []*c.Asset) row.CellWidthsContainer {
for _, asset := range assets {
var quoteLength int

volumeMarketCapLength := len(u.ConvertFloatToString(asset.QuoteExtended.MarketCap, true))
volumeMarketCapLength := len(u.ConvertFloatToStringWithCommas(asset.QuoteExtended.MarketCap, true))

if asset.QuoteExtended.FiftyTwoWeekHigh == 0.0 {
quoteLength = len(u.ConvertFloatToString(asset.QuotePrice.Price, asset.Meta.IsVariablePrecision))
quoteLength = len(u.ConvertFloatToStringWithCommas(asset.QuotePrice.Price, asset.Meta.IsVariablePrecision))
}

if asset.QuoteExtended.FiftyTwoWeekHigh != 0.0 {
quoteLength = len(u.ConvertFloatToString(asset.QuoteExtended.FiftyTwoWeekHigh, asset.Meta.IsVariablePrecision))
quoteLength = len(u.ConvertFloatToStringWithCommas(asset.QuoteExtended.FiftyTwoWeekHigh, asset.Meta.IsVariablePrecision))
}

if volumeMarketCapLength > cellMaxWidths.WidthVolumeMarketCap {
Expand All @@ -187,8 +228,8 @@ func getCellWidths(assets []*c.Asset) row.CellWidthsContainer {
}

if asset.Holding != (c.Holding{}) {
positionLength := len(u.ConvertFloatToString(asset.Holding.Value, asset.Meta.IsVariablePrecision))
positionQuantityLength := len(u.ConvertFloatToString(asset.Holding.Quantity, asset.Meta.IsVariablePrecision))
positionLength := len(u.ConvertFloatToStringWithCommas(asset.Holding.Value, asset.Meta.IsVariablePrecision))
positionQuantityLength := len(u.ConvertFloatToStringWithCommas(asset.Holding.Quantity, asset.Meta.IsVariablePrecision))

if positionLength > cellMaxWidths.PositionLength {
cellMaxWidths.PositionLength = positionLength
Expand Down
Loading
Loading