Adopt sats standard to show amounts (for Bitcoin) #924

This commit is contained in:
Martin Boehm 2023-05-11 00:28:04 +02:00
parent 9256a13fe6
commit d83d501272
4 changed files with 167 additions and 41 deletions

View File

@ -219,6 +219,49 @@ func appendAmountSpan(rv *strings.Builder, class, amount, shortcut, txDate strin
rv.WriteString("</span>")
}
func appendAmountSpanBitcoinType(rv *strings.Builder, class, amount, shortcut, txDate string) {
if amount == "0" {
appendAmountSpan(rv, class, amount, shortcut, txDate)
return
}
rv.WriteString(`<span`)
if class != "" {
rv.WriteString(` class="`)
rv.WriteString(class)
rv.WriteString(`"`)
}
if txDate != "" {
rv.WriteString(` tm="`)
rv.WriteString(txDate)
rv.WriteString(`"`)
}
rv.WriteString(">")
i := strings.IndexByte(amount, '.')
var decimals string
if i < 0 {
appendSeparatedNumberSpans(rv, amount, "nc")
decimals = "00000000"
} else {
appendSeparatedNumberSpans(rv, amount[:i], "nc")
decimals = amount[i+1:] + "00000000"
}
rv.WriteString(`.`)
rv.WriteString(`<span class="amt-dec">`)
rv.WriteString(decimals[:2])
rv.WriteString(`<span class="ns">`)
rv.WriteString(decimals[2:5])
rv.WriteString("</span>")
rv.WriteString(`<span class="ns">`)
rv.WriteString(decimals[5:8])
rv.WriteString("</span>")
rv.WriteString("</span>")
if shortcut != "" {
rv.WriteString(" ")
rv.WriteString(shortcut)
}
rv.WriteString("</span>")
}
func appendAmountWrapperSpan(rv *strings.Builder, primary, symbol, classes string) {
rv.WriteString(`<span class="amt`)
if classes != "" {

View File

@ -166,7 +166,84 @@ func Test_appendAmountSpan(t *testing.T) {
var rv strings.Builder
appendAmountSpan(&rv, tt.class, tt.amount, tt.shortcut, tt.txDate)
if got := rv.String(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("formatTime() = %v, want %v", got, tt.want)
t.Errorf("appendAmountSpan() = %v, want %v", got, tt.want)
}
})
}
}
func Test_appendAmountSpanBitcoinType(t *testing.T) {
tests := []struct {
name string
class string
amount string
shortcut string
txDate string
want string
}{
{
name: "prim-amt 1.23456789 BTC",
class: "prim-amt",
amount: "1.23456789",
shortcut: "BTC",
want: `<span class="prim-amt">1.<span class="amt-dec">23<span class="ns">456</span><span class="ns">789</span></span> BTC</span>`,
},
{
name: "prim-amt 1432134.23456 BTC",
class: "prim-amt",
amount: "1432134.23456",
shortcut: "BTC",
want: `<span class="prim-amt">1<span class="nc">432</span><span class="nc">134</span>.<span class="amt-dec">23<span class="ns">456</span><span class="ns">000</span></span> BTC</span>`,
},
{
name: "prim-amt 1 BTC",
class: "prim-amt",
amount: "1",
shortcut: "BTC",
want: `<span class="prim-amt">1.<span class="amt-dec">00<span class="ns">000</span><span class="ns">000</span></span> BTC</span>`,
},
{
name: "prim-amt 0 BTC",
class: "prim-amt",
amount: "0",
shortcut: "BTC",
want: `<span class="prim-amt">0 BTC</span>`,
},
{
name: "prim-amt 34.2 BTC",
class: "prim-amt",
amount: "34.2",
shortcut: "BTC",
want: `<span class="prim-amt">34.<span class="amt-dec">20<span class="ns">000</span><span class="ns">000</span></span> BTC</span>`,
},
{
name: "prim-amt -34.2345678 BTC",
class: "prim-amt",
amount: "-34.2345678",
shortcut: "BTC",
want: `<span class="prim-amt">-34.<span class="amt-dec">23<span class="ns">456</span><span class="ns">780</span></span> BTC</span>`,
},
{
name: "prim-amt -1234.2345 BTC",
class: "prim-amt",
amount: "-1234.2345",
shortcut: "BTC",
want: `<span class="prim-amt">-1<span class="nc">234</span>.<span class="amt-dec">23<span class="ns">450</span><span class="ns">000</span></span> BTC</span>`,
},
{
name: "prim-amt -123.23 BTC",
class: "prim-amt",
amount: "-123.23",
shortcut: "BTC",
want: `<span class="prim-amt">-123.<span class="amt-dec">23<span class="ns">000</span><span class="ns">000</span></span> BTC</span>`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var rv strings.Builder
appendAmountSpanBitcoinType(&rv, tt.class, tt.amount, tt.shortcut, tt.txDate)
if got := rv.String(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("appendAmountSpanBitcoinType() = %v, want %v", got, tt.want)
}
})
}

View File

@ -44,21 +44,22 @@ const (
// PublicServer provides public http server functionality
type PublicServer struct {
htmlTemplates[TemplateData]
binding string
certFiles string
socketio *SocketIoServer
websocket *WebsocketServer
https *http.Server
db *db.RocksDB
txCache *db.TxCache
chain bchain.BlockChain
chainParser bchain.BlockChainParser
mempool bchain.Mempool
api *api.Worker
explorerURL string
internalExplorer bool
is *common.InternalState
fiatRates *fiat.FiatRates
binding string
certFiles string
socketio *SocketIoServer
websocket *WebsocketServer
https *http.Server
db *db.RocksDB
txCache *db.TxCache
chain bchain.BlockChain
chainParser bchain.BlockChainParser
mempool bchain.Mempool
api *api.Worker
explorerURL string
internalExplorer bool
is *common.InternalState
fiatRates *fiat.FiatRates
useSatsAmountFormat bool
}
// NewPublicServer creates new public server http interface to blockbook and returns its handle
@ -92,21 +93,22 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch
metrics: metrics,
debug: debugMode,
},
binding: binding,
certFiles: certFiles,
https: https,
api: api,
socketio: socketio,
websocket: websocket,
db: db,
txCache: txCache,
chain: chain,
chainParser: chain.GetChainParser(),
mempool: mempool,
explorerURL: explorerURL,
internalExplorer: explorerURL == "",
is: is,
fiatRates: fiatRates,
binding: binding,
certFiles: certFiles,
https: https,
api: api,
socketio: socketio,
websocket: websocket,
db: db,
txCache: txCache,
chain: chain,
chainParser: chain.GetChainParser(),
mempool: mempool,
explorerURL: explorerURL,
internalExplorer: explorerURL == "",
is: is,
fiatRates: fiatRates,
useSatsAmountFormat: chain.GetChainParser().GetChainType() == bchain.ChainBitcoinType && chain.GetChainParser().AmountDecimals() == 8,
}
s.htmlTemplates.newTemplateData = s.newTemplateData
s.htmlTemplates.newTemplateDataWithError = s.newTemplateDataWithError
@ -569,7 +571,11 @@ func (s *PublicServer) amountSpan(a *api.Amount, td *TemplateData, classes strin
primary := s.formatAmount(a)
var rv strings.Builder
appendAmountWrapperSpan(&rv, primary, td.CoinShortcut, classes)
appendAmountSpan(&rv, "prim-amt", primary, td.CoinShortcut, "")
if s.useSatsAmountFormat {
appendAmountSpanBitcoinType(&rv, "prim-amt", primary, td.CoinShortcut, "")
} else {
appendAmountSpan(&rv, "prim-amt", primary, td.CoinShortcut, "")
}
if td.SecondaryCoin != "" {
p, err := strconv.ParseFloat(primary, 64)
if err == nil {

File diff suppressed because one or more lines are too long