feat(@desktop/communities) Permissions, 'who holds' section - handling localiezed amounts

Closes #7162
This commit is contained in:
Michał Cieślak 2022-09-15 12:12:38 +02:00 committed by Michał
parent 9addf1221b
commit 34625ad1c4
8 changed files with 183 additions and 75 deletions

View File

@ -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
}
}

View File

@ -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 {
}
}
}
}
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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