feat(@desktop/communities) Permissions, 'who holds' section - handling localiezed amounts
Closes #7162
This commit is contained in:
parent
9addf1221b
commit
34625ad1c4
|
@ -4,7 +4,8 @@ import QtQuick.Layouts 1.14
|
|||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
@ -13,10 +14,16 @@ ColumnLayout {
|
|||
property alias collectibleName: pickerButton.text
|
||||
property url collectibleImage
|
||||
|
||||
property alias amount: amountInput.text
|
||||
property alias amountText: amountInput.text
|
||||
property alias amount: amountInput.amount
|
||||
readonly property bool amountValid: amountInput.valid && amountInput.text.length > 0
|
||||
|
||||
signal pickerClicked
|
||||
|
||||
function setAmount(amount) {
|
||||
amountInput.setAmount(amount)
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
|
||||
StatusPickerButton {
|
||||
|
@ -50,30 +57,14 @@ ColumnLayout {
|
|||
StatusSwitch { id: specificAmountSwitch }
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
AmountInput {
|
||||
id: amountInput
|
||||
|
||||
visible: specificAmountSwitch.checked
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 8
|
||||
visible: specificAmountSwitch.checked
|
||||
minimumHeight: 36
|
||||
maximumHeight: 36
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
font.pixelSize: 13
|
||||
rightPadding: amountText.implicitWidth + amountText.anchors.rightMargin + leftPadding
|
||||
input.placeholderText: "0"
|
||||
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
|
||||
validators: StatusFloatValidator { bottom: 0 }
|
||||
|
||||
StatusBaseText {
|
||||
id: amountText
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 13
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Amount")
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 13
|
||||
}
|
||||
allowDecimals: false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ StatusDropdown {
|
|||
property var store
|
||||
|
||||
property string tokenKey: ""
|
||||
property string collectibleKey: ""
|
||||
|
||||
property real tokenAmount: 0
|
||||
|
||||
property string collectibleKey: ""
|
||||
property real collectibleAmount: 1
|
||||
property bool collectiblesSpecificAmount: false
|
||||
|
||||
|
@ -36,6 +36,8 @@ StatusDropdown {
|
|||
function reset() {
|
||||
d.currentHoldingType = HoldingTypes.Type.Token
|
||||
d.operator = SQ.Utils.Operators.None
|
||||
d.tokenAmountText = ""
|
||||
d.collectibleAmountText = ""
|
||||
|
||||
root.tokenKey = ""
|
||||
root.collectibleKey = ""
|
||||
|
@ -96,6 +98,9 @@ StatusDropdown {
|
|||
property int holdingsTabMode: HoldingsTabs.Mode.Add
|
||||
property int extendedDropdownType: ExtendedDropdownContent.Type.Tokens
|
||||
|
||||
property string tokenAmountText: ""
|
||||
property string collectibleAmountText: ""
|
||||
|
||||
property int currentHoldingType: HoldingTypes.Type.Token
|
||||
|
||||
property int operator: SQ.Utils.Operators.None
|
||||
|
@ -279,26 +284,17 @@ StatusDropdown {
|
|||
id: tokensPanel
|
||||
|
||||
tokenName: d.defaultTokenNameText
|
||||
amount: root.tokenAmount === 0 ? "" : root.tokenAmount.toString()
|
||||
onAmountChanged: root.tokenAmount = Number(amount)
|
||||
amountText: d.tokenAmountText
|
||||
onAmountTextChanged: d.tokenAmountText = amountText
|
||||
|
||||
readonly property real effectiveAmount: amountValid ? amount : 0
|
||||
onEffectiveAmountChanged: root.tokenAmount = effectiveAmount
|
||||
|
||||
onPickerClicked: {
|
||||
d.extendedDropdownType = ExtendedDropdownContent.Type.Tokens
|
||||
statesStack.push(d.extendedState)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: d
|
||||
|
||||
function onAddClicked() {
|
||||
root.addToken(root.tokenKey, root.tokenAmount, d.operator)
|
||||
}
|
||||
|
||||
function onUpdateClicked() {
|
||||
root.updateToken(root.tokenKey, root.tokenAmount)
|
||||
}
|
||||
}
|
||||
|
||||
readonly property string tokenKey: root.tokenKey
|
||||
|
||||
onTokenKeyChanged: {
|
||||
|
@ -312,6 +308,23 @@ StatusDropdown {
|
|||
tokensPanel.tokenImage = ""
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (d.tokenAmountText.length === 0 && root.tokenAmount)
|
||||
tokensPanel.setAmount(root.tokenAmount)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: d
|
||||
|
||||
function onAddClicked() {
|
||||
root.addToken(root.tokenKey, root.tokenAmount, d.operator)
|
||||
}
|
||||
|
||||
function onUpdateClicked() {
|
||||
root.updateToken(root.tokenKey, root.tokenAmount)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,9 +335,11 @@ StatusDropdown {
|
|||
id: collectiblesPanel
|
||||
|
||||
collectibleName: d.defaultCollectibleNameText
|
||||
amountText: d.collectibleAmountText
|
||||
onAmountTextChanged: d.collectibleAmountText = amountText
|
||||
|
||||
amount: root.collectibleAmount === 0 ? "" : root.collectibleAmount.toString()
|
||||
onAmountChanged: root.collectibleAmount = Number(amount)
|
||||
readonly property real effectiveAmount: amountValid ? amount : 0
|
||||
onEffectiveAmountChanged: root.collectibleAmount = effectiveAmount
|
||||
|
||||
specificAmount: root.collectiblesSpecificAmount
|
||||
onSpecificAmountChanged: root.collectiblesSpecificAmount = specificAmount
|
||||
|
@ -334,15 +349,24 @@ StatusDropdown {
|
|||
statesStack.push(d.extendedState)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (d.collectibleAmountText.length === 0 && root.collectibleAmount)
|
||||
collectiblesPanel.setAmount(root.collectibleAmount)
|
||||
}
|
||||
|
||||
function getAmount() {
|
||||
return specificAmount ? effectiveAmount : 1
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: d
|
||||
|
||||
function onAddClicked() {
|
||||
root.addCollectible(root.collectibleKey, root.collectibleAmount, d.operator)
|
||||
root.addCollectible(root.collectibleKey, collectiblesPanel.getAmount(), d.operator)
|
||||
}
|
||||
|
||||
function onUpdateClicked() {
|
||||
root.updateCollectible(root.collectibleKey, root.collectibleAmount)
|
||||
root.updateCollectible(root.collectibleKey, collectiblesPanel.getAmount())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,5 +440,5 @@ StatusDropdown {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,17 +4,24 @@ import QtQuick.Layouts 1.14
|
|||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property alias tokenName: pickerButton.text
|
||||
property url tokenImage
|
||||
property alias amount: amountInput.text
|
||||
property alias amountText: amountInput.text
|
||||
property alias amount: amountInput.amount
|
||||
readonly property bool amountValid: amountInput.valid && amountInput.text.length > 0
|
||||
|
||||
signal pickerClicked
|
||||
|
||||
function setAmount(amount) {
|
||||
amountInput.setAmount(amount)
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
|
||||
StatusPickerButton {
|
||||
|
@ -31,29 +38,10 @@ ColumnLayout {
|
|||
onClicked: pickerClicked()
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
AmountInput {
|
||||
id: amountInput
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 8
|
||||
minimumHeight: 36
|
||||
maximumHeight: 36
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
font.pixelSize: 13
|
||||
rightPadding: amountText.implicitWidth + amountText.anchors.rightMargin + leftPadding
|
||||
input.placeholderText: "0"
|
||||
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
|
||||
validators: StatusFloatValidator { bottom: 0 }
|
||||
|
||||
StatusBaseText {
|
||||
id: amountText
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 13
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Amount")
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 13
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ Flickable {
|
|||
switch (type) {
|
||||
case HoldingTypes.Type.Token:
|
||||
case HoldingTypes.Type.Collectible:
|
||||
return qsTr("%1 %2").arg(amount.toString()).arg(name)
|
||||
return `${LocaleUtils.numberToLocaleString(amount)} ${name}`
|
||||
case HoldingTypes.Type.Ens:
|
||||
if (name)
|
||||
return qsTr("ENS username on '%1' domain").arg(name)
|
||||
|
@ -182,9 +182,6 @@ Flickable {
|
|||
|
||||
const modelItem = tokensSelector.itemsModel.get(index)
|
||||
|
||||
dropdown.openFlow(HoldingsDropdown.FlowType.Update)
|
||||
dropdown.setActiveTab(modelItem.type)
|
||||
|
||||
switch(modelItem.type) {
|
||||
case HoldingTypes.Type.Token:
|
||||
dropdown.tokenKey = modelItem.key
|
||||
|
@ -204,6 +201,9 @@ Flickable {
|
|||
console.warn("Unsupported holdings type.")
|
||||
}
|
||||
|
||||
dropdown.openFlow(HoldingsDropdown.FlowType.Update)
|
||||
dropdown.setActiveTab(modelItem.type)
|
||||
|
||||
editedIndex = index
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
Input {
|
||||
id: root
|
||||
|
||||
property int maximumLength: 10
|
||||
property var locale: Qt.locale()
|
||||
|
||||
readonly property alias amount: d.amount
|
||||
readonly property bool valid: validationError.length === 0
|
||||
property bool allowDecimals: true
|
||||
|
||||
validationErrorTopMargin: 8
|
||||
fontPixelSize: 13
|
||||
customHeight: 36
|
||||
placeholderText: locale.zeroDigit
|
||||
|
||||
textField.rightPadding: labelText.implicitWidth + labelText.anchors.rightMargin
|
||||
+ textField.leftPadding
|
||||
|
||||
function setAmount(amount) {
|
||||
root.text = LocaleUtils.numberToLocaleString(amount, -1, root.locale)
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property real amount: 0
|
||||
}
|
||||
|
||||
validator: DoubleValidator {
|
||||
id: doubleValidator
|
||||
|
||||
decimals: root.allowDecimals ? 100 : 0
|
||||
bottom: 0
|
||||
notation: DoubleValidator.StandardNotation
|
||||
locale: root.locale.name
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
if (!allowDecimals)
|
||||
text = text.replace(root.locale.decimalPoint, "")
|
||||
|
||||
if(text.length === 0) {
|
||||
d.amount = 0
|
||||
root.validationError = ""
|
||||
return
|
||||
}
|
||||
|
||||
if (text.length > root.maximumLength) {
|
||||
root.validationError = qsTr("The maximum number of characters is %1").arg(root.maximumLength)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
d.amount = Number.fromLocaleString(root.locale, text) || 0
|
||||
root.validationError = ""
|
||||
} catch (err) {
|
||||
root.validationError = qsTr("Invalid amount format")
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: labelText
|
||||
|
||||
parent: root.textField
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 13
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Amount")
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 13
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
AddressInput 1.0 AddressInput.qml
|
||||
AmountInput 1.0 AmountInput.qml
|
||||
AssetAndAmountInput 1.0 AssetAndAmountInput.qml
|
||||
AssetDelegate 1.0 AssetDelegate.qml
|
||||
ContactSelector 1.0 ContactSelector.qml
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQml 2.14
|
||||
|
||||
QtObject {
|
||||
|
||||
function fractionalPartLength(num) {
|
||||
if (Number.isInteger(num))
|
||||
return 0
|
||||
|
||||
return num.toString().split('.')[1].length
|
||||
}
|
||||
|
||||
function numberToLocaleString(num, precision = -1, locale = null) {
|
||||
locale = locale || Qt.locale()
|
||||
|
||||
if (precision === -1)
|
||||
precision = fractionalPartLength(num)
|
||||
|
||||
return num.toLocaleString(locale, 'f', precision)
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
singleton Style 1.0 Style.qml
|
||||
singleton Utils 1.0 Utils.qml
|
||||
singleton Global 1.0 Global.qml
|
||||
singleton Constants 1.0 Constants.qml
|
||||
singleton SelectedMessage 1.0 SelectedMessage.qml
|
||||
singleton Backpressure 1.0 Backpressure/Backpressure.qml
|
||||
Audio 1.0 Audio.qml
|
||||
Tracer 1.0 Tracer.qml
|
||||
singleton Backpressure 1.0 Backpressure/Backpressure.qml
|
||||
singleton Constants 1.0 Constants.qml
|
||||
singleton Global 1.0 Global.qml
|
||||
singleton LocaleUtils 1.0 LocaleUtils.qml
|
||||
singleton SelectedMessage 1.0 SelectedMessage.qml
|
||||
singleton Style 1.0 Style.qml
|
||||
singleton Utils 1.0 Utils.qml
|
||||
|
|
Loading…
Reference in New Issue