feat(@desktop/wallet) reduce number of digits shown for large currency amounts
Fixes #8917
This commit is contained in:
parent
a2a6287537
commit
da1839fbbb
|
@ -45,6 +45,10 @@ ListModel {
|
|||
title: "CommunityMintedTokensView"
|
||||
section: "Views"
|
||||
}
|
||||
ListElement {
|
||||
title: "AmountToSendView"
|
||||
section: "Views"
|
||||
}
|
||||
ListElement {
|
||||
title: "StatusCommunityCard"
|
||||
section: "Panels"
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import AppLayouts.Profile.views 1.0
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared.views 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
readonly property double maxCryptoBalance: parseFloat(maxCryptoBalanceText.text)
|
||||
readonly property double rate: parseFloat(rateText.text)
|
||||
readonly property int decimals: parseInt(decimalsText.text)
|
||||
|
||||
Logs { id: logs }
|
||||
|
||||
SplitView {
|
||||
orientation: Qt.Vertical
|
||||
SplitView.fillWidth: true
|
||||
|
||||
Item {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
AmountToSend {
|
||||
id: amountToSendInput
|
||||
isBridgeTx: false
|
||||
interactive: true
|
||||
selectedSymbol: "Crypto"
|
||||
maxInputBalance: inputIsFiat ? getFiatValue(root.maxCryptoBalance) : root.maxCryptoBalance
|
||||
currentCurrency: "Fiat"
|
||||
getFiatValue: function(cryptoValue) {
|
||||
return cryptoValue * root.rate
|
||||
}
|
||||
getCryptoValue: function(fiatValue) {
|
||||
return fiatValue / root.rate
|
||||
}
|
||||
formatCurrencyAmount: function(amount, symbol, options = null, locale = null) {
|
||||
const currencyAmount = {
|
||||
amount: amount,
|
||||
symbol: symbol,
|
||||
displayDecimals: root.decimals,
|
||||
stripTrailingZeroes: true
|
||||
}
|
||||
return LocaleUtils.currencyAmountToLocaleString(currencyAmount, options)
|
||||
}
|
||||
onReCalculateSuggestedRoute: function() {
|
||||
logs.logEvent("onReCalculateSuggestedRoute")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
id: logsAndControlsPanel
|
||||
|
||||
SplitView.minimumHeight: 100
|
||||
|
||||
logsView.logText: logs.logText
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
SplitView.minimumWidth: 300
|
||||
SplitView.preferredWidth: 300
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
Layout.topMargin: 10
|
||||
Layout.fillWidth: true
|
||||
text: "Max Crypto Balance"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: maxCryptoBalanceText
|
||||
background: Rectangle { border.color: 'lightgrey' }
|
||||
Layout.preferredWidth: 200
|
||||
text: "1000000"
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.topMargin: 10
|
||||
Layout.fillWidth: true
|
||||
text: "Fiat/Crypto rate"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: rateText
|
||||
background: Rectangle { border.color: 'lightgrey' }
|
||||
Layout.preferredWidth: 200
|
||||
text: "10"
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.topMargin: 10
|
||||
Layout.fillWidth: true
|
||||
text: "Decimals"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: decimalsText
|
||||
background: Rectangle { border.color: 'lightgrey' }
|
||||
Layout.preferredWidth: 200
|
||||
text: "6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -239,7 +239,7 @@ Item {
|
|||
id: txtFiatBalance
|
||||
Layout.rightMargin: 4
|
||||
font.pixelSize: 15
|
||||
text: LocaleUtils.currencyAmountToLocaleString(currencyBalance, {onlyAmount: true})
|
||||
text: LocaleUtils.currencyAmountToLocaleString(currencyBalance, {noSymbol: true})
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
StatusBaseText {
|
||||
|
|
|
@ -8,6 +8,35 @@ QtObject {
|
|||
|
||||
readonly property var userInputLocale: Qt.locale("en_US")
|
||||
|
||||
function integralPartLength(num) {
|
||||
num = Math.abs(num)
|
||||
|
||||
// According to the JS Reference:
|
||||
//
|
||||
// Scientific notation is used if the radix is 10 and the number's
|
||||
// magnitude (ignoring sign) is greater than or equal to 10^21 or less
|
||||
// than 10^-6. In this case, the returned string always explicitly
|
||||
// specifies the sign of the exponent.
|
||||
//
|
||||
// In order to take it into account, numbers in scientific notation
|
||||
// is handled separately.
|
||||
|
||||
if (num < 1) {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (num >= 10**21) {
|
||||
const split = num.toString().split('e')
|
||||
if (split.length === 2) {
|
||||
const base = parseFloat(split[0])
|
||||
const exp = parseInt(split[1], 10)
|
||||
return integralPartLength(base) + exp
|
||||
}
|
||||
}
|
||||
|
||||
return num.toFixed().length
|
||||
}
|
||||
|
||||
function fractionalPartLength(num) {
|
||||
if (Number.isInteger(num))
|
||||
return 0
|
||||
|
@ -86,12 +115,16 @@ QtObject {
|
|||
return "N/A"
|
||||
|
||||
// Parse options
|
||||
var optShowOnlyAmount = false
|
||||
var optNoSymbol = false
|
||||
var optRawAmount = false
|
||||
var optDisplayDecimals = currencyAmount.displayDecimals
|
||||
var optStripTrailingZeroes = currencyAmount.stripTrailingZeroes
|
||||
if (options) {
|
||||
if (options.onlyAmount !== undefined) {
|
||||
optShowOnlyAmount = true
|
||||
if (options.noSymbol !== undefined) {
|
||||
optNoSymbol = true
|
||||
}
|
||||
if (options.rawAmount !== undefined) {
|
||||
optRawAmount = true
|
||||
}
|
||||
if (options.minDecimals !== undefined && options.minDecimals > optDisplayDecimals) {
|
||||
optDisplayDecimals = options.minDecimals
|
||||
|
@ -101,23 +134,40 @@ QtObject {
|
|||
}
|
||||
}
|
||||
|
||||
var amountStr
|
||||
var amountStr = ""
|
||||
var amountSuffix = ""
|
||||
|
||||
let minAmount = 10**-optDisplayDecimals
|
||||
if (currencyAmount.amount > 0 && currencyAmount.amount < minAmount && !optShowOnlyAmount)
|
||||
if (currencyAmount.amount > 0 && currencyAmount.amount < minAmount && !optRawAmount)
|
||||
{
|
||||
// Handle amounts smaller than resolution
|
||||
amountStr = "<%1".arg(numberToLocaleString(minAmount, optDisplayDecimals, locale))
|
||||
amountStr = "<%1".arg(numberToLocaleString(minAmount, displayDecimals, locale))
|
||||
} else {
|
||||
// Normal formatting
|
||||
amountStr = numberToLocaleString(currencyAmount.amount, optDisplayDecimals, locale)
|
||||
var amount
|
||||
var displayDecimals
|
||||
const numIntegerDigits = integralPartLength(currencyAmount.amount)
|
||||
const maxDigits = 10
|
||||
// For large numbers, we use the short scale system (https://en.wikipedia.org/wiki/Long_and_short_scales)
|
||||
// and 2 decimal digits.
|
||||
if (numIntegerDigits > maxDigits && !optRawAmount) {
|
||||
amount = currencyAmount.amount/10**9 // Billion => 9 zeroes
|
||||
displayDecimals = 2
|
||||
amountSuffix = qsTr("B", "Billion")
|
||||
} else {
|
||||
// For normal numbers, we show the whole integral part and as many decimal places not
|
||||
// not to exceed the maximum
|
||||
amount = currencyAmount.amount
|
||||
displayDecimals = Math.min(optDisplayDecimals, Math.max(0, maxDigits - numIntegerDigits))
|
||||
}
|
||||
amountStr = numberToLocaleString(amount, displayDecimals, locale)
|
||||
if (optStripTrailingZeroes) {
|
||||
amountStr = stripTrailingZeroes(amountStr, locale)
|
||||
}
|
||||
}
|
||||
|
||||
// Add symbol
|
||||
if (currencyAmount.symbol && !optShowOnlyAmount) {
|
||||
amountStr = "%1 %2".arg(amountStr).arg(currencyAmount.symbol)
|
||||
if (currencyAmount.symbol && !optNoSymbol) {
|
||||
amountStr = "%1%2 %3".arg(amountStr).arg(amountSuffix).arg(currencyAmount.symbol)
|
||||
}
|
||||
|
||||
return amountStr
|
||||
|
|
|
@ -132,7 +132,7 @@ ColumnLayout {
|
|||
onClicked: {
|
||||
topAmountToSendInput.validate()
|
||||
if(!!topAmountToSendInput.text) {
|
||||
topAmountToSendInput.text = root.formatCurrencyAmount(bottomItem.bottomAmountToSend, bottomItem.bottomAmountSymbol, {onlyAmount: true}, LocaleUtils.userInputLocale)
|
||||
topAmountToSendInput.text = root.formatCurrencyAmount(bottomItem.bottomAmountToSend, bottomItem.bottomAmountSymbol, {noSymbol: true, rawAmount: true}, LocaleUtils.userInputLocale)
|
||||
}
|
||||
inputIsFiat = !inputIsFiat
|
||||
d.waitTimer.restart()
|
||||
|
|
|
@ -11,3 +11,4 @@ ProfileDialogView 1.0 ProfileDialogView.qml
|
|||
AssetsView 1.0 AssetsView.qml
|
||||
HistoryView 1.0 HistoryView.qml
|
||||
DeviceSyncingView 1.0 DeviceSyncingView.qml
|
||||
AmountToSend 1.0 AmountToSend.qml
|
||||
|
|
Loading…
Reference in New Issue