mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-20 11:29:20 +00:00
feat(@desktop/wallet): Entering asset value + using max button in its current state
fixes #16903
This commit is contained in:
parent
889f46b392
commit
909f518d3d
@ -5,6 +5,7 @@ import QtQuick.Controls 2.15
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import Models 1.0
|
||||
import Storybook 1.0
|
||||
@ -33,6 +34,15 @@ SplitView {
|
||||
}
|
||||
|
||||
readonly property var walletAccountsModel: WalletAccountsModel{}
|
||||
|
||||
function getCurrencyAmount(amount, symbol) {
|
||||
return ({
|
||||
amount: amount,
|
||||
symbol: symbol ? symbol.toUpperCase() : root.currentCurrency,
|
||||
displayDecimals: 2,
|
||||
stripTrailingZeroes: false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
PopupBackground {
|
||||
@ -60,11 +70,22 @@ SplitView {
|
||||
modal: false
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
|
||||
interactive: interactiveCheckbox.checked
|
||||
|
||||
accountsModel: d.walletAccountsModel
|
||||
assetsModel: assetsSelectorViewAdaptor.outputAssetsModel
|
||||
collectiblesModel: collectiblesSelectionAdaptor.model
|
||||
networksModel: d.filteredNetworksModel
|
||||
|
||||
currentCurrency: "USD"
|
||||
fnFormatCurrencyAmount: function(amount, symbol, options = null, locale = null) {
|
||||
if (isNaN(amount)) {
|
||||
return "N/A"
|
||||
}
|
||||
var currencyAmount = d.getCurrencyAmount(amount, symbol)
|
||||
return LocaleUtils.currencyAmountToLocaleString(currencyAmount, options, locale)
|
||||
}
|
||||
|
||||
Binding on selectedAccountAddress {
|
||||
value: accountsCombobox.currentValue ?? ""
|
||||
}
|
||||
@ -123,7 +144,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityImage: Qt.resolvedUrl("")
|
||||
communityImage: Qt.resolvedUrl(""),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_4",
|
||||
@ -144,7 +166,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityImage: Qt.resolvedUrl("")
|
||||
communityImage: Qt.resolvedUrl(""),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_5",
|
||||
@ -165,7 +188,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityImage: Qt.resolvedUrl("")
|
||||
communityImage: Qt.resolvedUrl(""),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
// collection 1
|
||||
{
|
||||
@ -192,7 +216,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityImage: Qt.resolvedUrl("")
|
||||
communityImage: Qt.resolvedUrl(""),
|
||||
tokenType: Constants.TokenType.ERC1155
|
||||
},
|
||||
{
|
||||
tokenId: "id_2",
|
||||
@ -213,7 +238,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityImage: Qt.resolvedUrl("")
|
||||
communityImage: Qt.resolvedUrl(""),
|
||||
tokenType: Constants.TokenType.ERC1155
|
||||
},
|
||||
// collection 3, community token
|
||||
{
|
||||
@ -235,7 +261,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_1",
|
||||
communityName: "My community",
|
||||
communityImage: Constants.tokenIcon("KIN", false)
|
||||
communityImage: Constants.tokenIcon("KIN", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_7",
|
||||
@ -256,7 +283,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_1",
|
||||
communityName: "My community",
|
||||
communityImage: Constants.tokenIcon("KIN", false)
|
||||
communityImage: Constants.tokenIcon("KIN", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_8",
|
||||
@ -277,7 +305,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_1",
|
||||
communityName: "My community",
|
||||
communityImage: Constants.tokenIcon("KIN", false)
|
||||
communityImage: Constants.tokenIcon("KIN", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_9",
|
||||
@ -298,7 +327,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_1",
|
||||
communityName: "My community",
|
||||
communityImage: Constants.tokenIcon("KIN", false)
|
||||
communityImage: Constants.tokenIcon("KIN", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_10",
|
||||
@ -319,7 +349,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_2",
|
||||
communityName: "My community 2",
|
||||
communityImage: Constants.tokenIcon("ICOS", false)
|
||||
communityImage: Constants.tokenIcon("ICOS", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_11",
|
||||
@ -340,7 +371,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_2",
|
||||
communityName: "My community 2",
|
||||
communityImage: Constants.tokenIcon("ICOS", false)
|
||||
communityImage: Constants.tokenIcon("ICOS", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_11",
|
||||
@ -361,7 +393,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_2",
|
||||
communityName: "My community 2",
|
||||
communityImage: Constants.tokenIcon("ICOS", false)
|
||||
communityImage: Constants.tokenIcon("ICOS", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_12",
|
||||
@ -382,7 +415,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_2",
|
||||
communityName: "My community 2",
|
||||
communityImage: Constants.tokenIcon("ICOS", false)
|
||||
communityImage: Constants.tokenIcon("ICOS", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
},
|
||||
{
|
||||
tokenId: "id_13",
|
||||
@ -403,7 +437,8 @@ SplitView {
|
||||
mediaUrl: Qt.resolvedUrl(""),
|
||||
communityId: "community_2",
|
||||
communityName: "My community 2",
|
||||
communityImage: Constants.tokenIcon("ICOS", false)
|
||||
communityImage: Constants.tokenIcon("ICOS", false),
|
||||
tokenType: Constants.TokenType.ERC721
|
||||
}
|
||||
]
|
||||
|
||||
@ -420,8 +455,10 @@ SplitView {
|
||||
ColumnLayout {
|
||||
spacing: 20
|
||||
|
||||
Text {
|
||||
text: "Values to set before popup is launched"
|
||||
CheckBox {
|
||||
id: interactiveCheckbox
|
||||
text: "Is interactive"
|
||||
checked: true
|
||||
}
|
||||
|
||||
Text {
|
||||
@ -491,6 +528,28 @@ SplitView {
|
||||
text: "token selected is: " + simpleSend.selectedTokenKey
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
TextField {
|
||||
id: amountInput
|
||||
Layout.preferredWidth: 200
|
||||
Layout.preferredHeight: 50
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^\d*\.?\d*$/
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "update in modal"
|
||||
onClicked: simpleSend.selectedAmount = amountInput.text
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: "amount selected in base unit: " + simpleSend.selectedAmountInBaseUnit
|
||||
}
|
||||
Text {
|
||||
text: "amount entered is: " + simpleSend.selectedAmount
|
||||
}
|
||||
|
||||
RolesRenamingModel {
|
||||
id: collectiblesKeyModel
|
||||
sourceModel: collectiblesSelectionAdaptor.model
|
||||
|
@ -58,10 +58,6 @@ RowLayout {
|
||||
/** input property for programatic selection of network **/
|
||||
property int selectedChainId
|
||||
|
||||
/** input property for programatic selection of token
|
||||
(asset/collectible/collection) **/
|
||||
property string selectedTokenKey
|
||||
|
||||
/** signal to propagate that an asset was selected **/
|
||||
signal assetSelected(string key)
|
||||
/** signal to propagate that a collection was selected **/
|
||||
@ -71,32 +67,10 @@ RowLayout {
|
||||
/** signal to propagate that a network was selected **/
|
||||
signal networkSelected(string chainId)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property bool selectedTokenNotAvailableOnAssetsOrCollectiblesList: !selectedAssetEntry.available && !selectedCollectibleEntry.available
|
||||
onSelectedTokenNotAvailableOnAssetsOrCollectiblesListChanged: {
|
||||
if(selectedTokenNotAvailableOnAssetsOrCollectiblesList) {
|
||||
// reset token selector in case selected tokens doesnt exist in either models
|
||||
tokenSelector.setSelection("", "", "")
|
||||
}
|
||||
}
|
||||
|
||||
function updateAssetInTokenSelector(available, item) {
|
||||
if(available) {
|
||||
tokenSelector.setSelection(item.symbol,
|
||||
Constants.tokenIcon(item.symbol),
|
||||
item.tokensKey)
|
||||
}
|
||||
}
|
||||
|
||||
function updateCollectibleInTokenSelector(available, item) {
|
||||
if(available) {
|
||||
const id = item.communityId ? item.collectionUid : item.uid
|
||||
tokenSelector.setSelection(item.name,
|
||||
item.imageUrl || item.mediaUrl,
|
||||
id)
|
||||
}
|
||||
}
|
||||
/** input function for programatic selection of token
|
||||
(asset/collectible/collection) **/
|
||||
function setToken(name, icon, key) {
|
||||
tokenSelector.setSelection(name, icon, key)
|
||||
}
|
||||
|
||||
implicitHeight: sendModalTitleText.height
|
||||
@ -181,22 +155,4 @@ RowLayout {
|
||||
|
||||
onToggleNetwork: root.networkSelected(chainId)
|
||||
}
|
||||
|
||||
ModelEntry {
|
||||
id: selectedAssetEntry
|
||||
sourceModel: root.assetsModel
|
||||
key: "tokensKey"
|
||||
value: root.selectedTokenKey
|
||||
onAvailableChanged: d.updateAssetInTokenSelector(available, item)
|
||||
onItemChanged: d.updateAssetInTokenSelector(available, item)
|
||||
}
|
||||
|
||||
ModelEntry {
|
||||
id: selectedCollectibleEntry
|
||||
sourceModel: root.collectiblesModel
|
||||
key: "symbol"
|
||||
value: root.selectedTokenKey
|
||||
onAvailableChanged: d.updateCollectibleInTokenSelector(available, item)
|
||||
onItemChanged: d.updateCollectibleInTokenSelector(available, item)
|
||||
}
|
||||
}
|
||||
|
@ -53,10 +53,6 @@ Rectangle {
|
||||
/** input property for programatic selection of network **/
|
||||
property int selectedChainId: -1
|
||||
|
||||
/** input property for programatic selection of token
|
||||
(asset/collectible/collection) **/
|
||||
property string selectedTokenKey
|
||||
|
||||
/** signal to propagate that an asset was selected **/
|
||||
signal assetSelected(string key)
|
||||
/** signal to propagate that a collection was selected **/
|
||||
@ -66,6 +62,12 @@ Rectangle {
|
||||
/** signal to propagate that a network was selected **/
|
||||
signal networkSelected(string chainId)
|
||||
|
||||
/** input function for programatic selection of token
|
||||
(asset/collectible/collection) **/
|
||||
function setToken(name, icon, key) {
|
||||
sendModalHeader.setToken(name, icon, key)
|
||||
}
|
||||
|
||||
enabled: root.isScrolling
|
||||
color: Theme.palette.baseColor3
|
||||
radius: 8
|
||||
@ -114,7 +116,6 @@ Rectangle {
|
||||
collectiblesModel: root.collectiblesModel
|
||||
|
||||
selectedChainId: root.selectedChainId
|
||||
selectedTokenKey: root.selectedTokenKey
|
||||
|
||||
onCollectibleSelected: root.collectibleSelected(key)
|
||||
onCollectionSelected: root.collectionSelected(key)
|
||||
|
@ -1,15 +1,22 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
import StatusQ.Core.Backpressure 0.1
|
||||
|
||||
import shared.popups.send.views 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import AppLayouts.Wallet.panels 1.0
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
import AppLayouts.Wallet 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
StatusDialog {
|
||||
id: root
|
||||
@ -64,33 +71,124 @@ StatusDialog {
|
||||
Only networks valid as per mainnet/testnet selection
|
||||
**/
|
||||
required property var networksModel
|
||||
/** Input property holds currently selected Fiat currency **/
|
||||
required property string currentCurrency
|
||||
/** Input function to format currency amount to locale string **/
|
||||
required property var fnFormatCurrencyAmount
|
||||
|
||||
/** input property to decide if send mdoal is interactive or prefilled**/
|
||||
property bool interactive
|
||||
|
||||
/** property to set and expose currently selected account **/
|
||||
property string selectedAccountAddress
|
||||
|
||||
/** property to set and expose currently selected network **/
|
||||
property int selectedChainId
|
||||
|
||||
/** property to set and expose currently selected token key **/
|
||||
property string selectedTokenKey
|
||||
/** property to set and expose the amount to send from outside without any localization **/
|
||||
property string selectedAmount
|
||||
/** output property to set currently set amount to send
|
||||
Crypto value in a base unit as a string integer,
|
||||
e.g. 1000000000000000000 for 1 ETH **/
|
||||
readonly property string selectedAmountInBaseUnit: amountToSend.amount
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property bool isScrolling:
|
||||
scrollView.flickable.contentY > sendModalHeader.height
|
||||
|
||||
// Used to get asset entry if selected token is an asset
|
||||
readonly property var selectedAssetEntry: ModelEntry {
|
||||
sourceModel: root.assetsModel
|
||||
key: "tokensKey"
|
||||
value: root.selectedTokenKey
|
||||
}
|
||||
|
||||
// Used to get collectible entry if selected token is a collectible
|
||||
readonly property var selectedCollectibleEntry: ModelEntry {
|
||||
sourceModel: root.collectiblesModel
|
||||
key: "symbol"
|
||||
value: root.selectedTokenKey
|
||||
}
|
||||
|
||||
/** exposes the currently selected token entry **/
|
||||
readonly property var selectedTokenEntry: selectedAssetEntry.available ?
|
||||
selectedAssetEntry.item :
|
||||
selectedCollectibleEntry.available ?
|
||||
selectedCollectibleEntry.item: null
|
||||
onSelectedTokenEntryChanged: {
|
||||
if(!selectedAssetEntry.available && !selectedCollectibleEntry.available) {
|
||||
d.debounceResetTokenSelector()
|
||||
}
|
||||
if(selectedAssetEntry.available && !!selectedTokenEntry) {
|
||||
d.setTokenOnBothHeaders(selectedTokenEntry.symbol,
|
||||
Constants.tokenIcon(selectedTokenEntry.symbol),
|
||||
selectedTokenEntry.tokensKey)
|
||||
}
|
||||
else if(selectedCollectibleEntry.available && !!selectedTokenEntry) {
|
||||
const id = selectedTokenEntry.communityId ?
|
||||
selectedTokenEntry.collectionUid :
|
||||
selectedTokenEntry.uid
|
||||
d.setTokenOnBothHeaders(selectedTokenEntry.name,
|
||||
selectedTokenEntry.imageUrl || selectedTokenEntry.mediaUrl,
|
||||
id)
|
||||
}
|
||||
}
|
||||
|
||||
function setTokenOnBothHeaders(name, icon, key) {
|
||||
sendModalHeader.setToken(name, icon, key)
|
||||
stickySendModalHeader.setToken(name, icon, key)
|
||||
}
|
||||
|
||||
readonly property var debounceResetTokenSelector: Backpressure.debounce(root, 0, function() {
|
||||
if(!selectedAssetEntry.available && !selectedCollectibleEntry.available) {
|
||||
// reset token selector in case selected tokens doesnt exist in either models
|
||||
d.setTokenOnBothHeaders("", "", "")
|
||||
root.selectedTokenKey = ""
|
||||
}
|
||||
})
|
||||
|
||||
readonly property bool isCollectibleSelected: {
|
||||
if(!selectedTokenEntry)
|
||||
return false
|
||||
const type = selectedAssetEntry.available ? selectedAssetEntry.item.type :
|
||||
selectedCollectibleEntry.available ? selectedCollectibleEntry.item.tokenType :
|
||||
Constants.TokenType.Unknown
|
||||
return (type === Constants.TokenType.ERC721 || type === Constants.TokenType.ERC1155)
|
||||
}
|
||||
|
||||
readonly property string selectedCryptoTokenSymbol: !!d.selectedTokenEntry ?
|
||||
d.selectedTokenEntry.symbol: ""
|
||||
|
||||
readonly property double maxSafeCryptoValue: {
|
||||
const maxCryptoBalance = !!d.selectedTokenEntry && !!d.selectedTokenEntry.currentBalance ?
|
||||
d.selectedTokenEntry.currentBalance : 0
|
||||
return WalletUtils.calculateMaxSafeSendAmount(maxCryptoBalance, d.selectedCryptoTokenSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
width: 556
|
||||
padding: 0
|
||||
leftPadding: Theme.xlPadding
|
||||
rightPadding: Theme.xlPadding
|
||||
bottomPadding: Theme.xlPadding
|
||||
topMargin: margins + accountSelector.height + Theme.padding
|
||||
|
||||
background: StatusDialogBackground {
|
||||
color: Theme.palette.baseColor3
|
||||
}
|
||||
|
||||
// Bindings needed for exposing and setting raw values from AmountToSend
|
||||
Binding on selectedAmount {
|
||||
value: amountToSend.text
|
||||
}
|
||||
onSelectedAmountChanged: {
|
||||
if(!!selectedAmount && amountToSend.text !== root.selectedAmount) {
|
||||
amountToSend.setValue(root.selectedAmount)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: sendModalcontentItem
|
||||
|
||||
@ -121,6 +219,8 @@ StatusDialog {
|
||||
|
||||
// Sticky header only visible when scrolling
|
||||
StickySendModalHeader {
|
||||
id: stickySendModalHeader
|
||||
|
||||
width: root.width
|
||||
anchors.top: accountSelector.bottom
|
||||
anchors.topMargin:Theme.padding
|
||||
@ -135,7 +235,6 @@ StatusDialog {
|
||||
collectiblesModel: root.collectiblesModel
|
||||
|
||||
selectedChainId: root.selectedChainId
|
||||
selectedTokenKey: root.selectedTokenKey
|
||||
|
||||
onCollectibleSelected: root.selectedTokenKey = key
|
||||
onCollectionSelected: root.selectedTokenKey = key
|
||||
@ -148,7 +247,6 @@ StatusDialog {
|
||||
id: scrollView
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 28
|
||||
contentWidth: availableWidth
|
||||
|
||||
padding: 0
|
||||
@ -171,6 +269,7 @@ StatusDialog {
|
||||
id: sendModalHeader
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 28
|
||||
|
||||
isScrolling: d.isScrolling
|
||||
|
||||
@ -179,7 +278,6 @@ StatusDialog {
|
||||
collectiblesModel: root.collectiblesModel
|
||||
|
||||
selectedChainId: root.selectedChainId
|
||||
selectedTokenKey: root.selectedTokenKey
|
||||
|
||||
onCollectibleSelected: root.selectedTokenKey = key
|
||||
onCollectionSelected: root.selectedTokenKey = key
|
||||
@ -187,31 +285,66 @@ StatusDialog {
|
||||
onNetworkSelected: root.selectedChainId = chainId
|
||||
}
|
||||
|
||||
// TODO: Remove these Dummy items added only to test dialog resizing
|
||||
readonly property string longLoremIpsum: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
|
||||
Text {
|
||||
// Amount to send entry
|
||||
AmountToSend {
|
||||
id: amountToSend
|
||||
|
||||
Layout.fillWidth: true
|
||||
text: scrollViewLayout.longLoremIpsum.repeat(3)
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
interactive: root.interactive
|
||||
dividerVisible: true
|
||||
progressivePixelReduction: false
|
||||
/** TODO: connect this with suggested routes being fetched as price
|
||||
gets updated each time a new proposal is fetched
|
||||
bottomTextLoading: root.suggestedRoutesLoading **/
|
||||
|
||||
/** TODO: connect to max safe value for eth.
|
||||
For now simply checking balance in case of both eth and other ERC20's **/
|
||||
markAsInvalid: SQUtils.AmountsArithmetic.fromNumber(d.maxSafeCryptoValue, multiplierIndex).cmp(amount) === -1
|
||||
|
||||
selectedSymbol: amountToSend.fiatMode ?
|
||||
root.currentCurrency:
|
||||
d.selectedCryptoTokenSymbol
|
||||
price: !!d.selectedTokenEntry &&
|
||||
!!d.selectedTokenEntry.marketDetails ?
|
||||
d.selectedTokenEntry.marketDetails.currencyPrice.amount : 1
|
||||
multiplierIndex: !!d.selectedTokenEntry &&
|
||||
!!d.selectedTokenEntry.decimals ?
|
||||
d.selectedTokenEntry.decimals : 0
|
||||
formatFiat: amount => root.fnFormatCurrencyAmount(
|
||||
amount, root.currentCurrency)
|
||||
formatBalance: amount => root.fnFormatCurrencyAmount(
|
||||
amount, d.selectedCryptoTokenSymbol)
|
||||
|
||||
visible: !!root.selectedTokenKey && !d.isCollectibleSelected
|
||||
onVisibleChanged: if(visible) forceActiveFocus()
|
||||
|
||||
bottomRightComponent: MaxSendButton {
|
||||
id: maxButton
|
||||
|
||||
formattedValue: {
|
||||
const price = !!d.selectedTokenEntry && !!d.selectedTokenEntry.marketDetails ?
|
||||
d.selectedTokenEntry.marketDetails.currencyPrice.amount : 0
|
||||
let maxSafeValue = amountToSend.fiatMode ? d.maxSafeCryptoValue * price : d.maxSafeCryptoValue
|
||||
return root.fnFormatCurrencyAmount(
|
||||
maxSafeValue,
|
||||
amountToSend.selectedSymbol,
|
||||
{ noSymbol: !amountToSend.fiatMode,
|
||||
roundingMode: LocaleUtils.RoundingMode.Down
|
||||
})
|
||||
}
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 200
|
||||
opacity: 0.2
|
||||
color: "red"
|
||||
markAsInvalid: amountToSend.markAsInvalid
|
||||
/** TODO: Remove below customisations after
|
||||
https://github.com/status-im/status-desktop/issues/15709
|
||||
and make the button clickable **/
|
||||
enabled: false
|
||||
background: Rectangle {
|
||||
radius: 20
|
||||
color: type === StatusBaseButton.Type.Danger ? Theme.palette.dangerColor3 : Theme.palette.primaryColor3
|
||||
}
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: scrollViewLayout.longLoremIpsum.repeat(3)
|
||||
wrapMode: Text.WordWrap
|
||||
disabledTextColor: type === StatusBaseButton.Type.Danger ? Theme.palette.dangerColor1 : Theme.palette.primaryColor1
|
||||
}
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 200
|
||||
opacity: 0.2
|
||||
color: "red"
|
||||
}
|
||||
// End Dummy items
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -660,6 +660,7 @@ Item {
|
||||
|
||||
simpleSendEnabled: appMain.featureFlagsStore.simpleSendEnabled
|
||||
|
||||
// for simple send
|
||||
walletAccountsModel: WalletStores.RootStore.accounts
|
||||
flatNetworksModel: WalletStores.RootStore.flatNetworks
|
||||
areTestNetworksEnabled: WalletStores.RootStore.areTestNetworksEnabled
|
||||
@ -667,6 +668,9 @@ Item {
|
||||
currentCurrency: appMain.currencyStore.currentCurrency
|
||||
showCommunityAssetsInSend: appMain.tokensStore.showCommunityAssetsInSend
|
||||
collectiblesBySymbolModel: WalletStores.RootStore.collectiblesStore.jointCollectiblesBySymbolModel
|
||||
fnFormatCurrencyAmount: function(amount, symbol, options = null, locale = null) {
|
||||
return appMain.currencyStore.formatCurrencyAmount(amount, symbol)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// It's requested from many nested places, so as a workaround we use
|
||||
|
@ -86,6 +86,8 @@ QtObject {
|
||||
/** whether community tokens are shown in send modal
|
||||
based on a global setting **/
|
||||
required property var showCommunityAssetsInSend
|
||||
/** required function to format currency amount to locale string **/
|
||||
required property var fnFormatCurrencyAmount
|
||||
|
||||
function openSend(params = {}) {
|
||||
// TODO remove once simple send is feature complete
|
||||
@ -230,6 +232,9 @@ QtObject {
|
||||
collectiblesModel: collectiblesSelectionAdaptor.model
|
||||
networksModel: root.filteredFlatNetworksModel
|
||||
|
||||
currentCurrency: root.currentCurrency
|
||||
fnFormatCurrencyAmount: root.fnFormatCurrencyAmount
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
TokenSelectorViewAdaptor {
|
||||
@ -252,7 +257,13 @@ QtObject {
|
||||
enabledChainIds: [simpleSendModal.selectedChainId]
|
||||
|
||||
networksModel: root.filteredFlatNetworksModel
|
||||
collectiblesModel: root.collectiblesBySymbolModel
|
||||
collectiblesModel: SortFilterProxyModel {
|
||||
sourceModel: root.collectiblesBySymbolModel
|
||||
filters: ValueFilter {
|
||||
roleName: "soulbound"
|
||||
value: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,10 @@ Control {
|
||||
property bool mainInputLoading
|
||||
property bool bottomTextLoading
|
||||
|
||||
/* This allows user to add a component to the right of bottom text
|
||||
Not set = not shown */
|
||||
property alias bottomRightComponent: bottomRightComponent.sourceComponent
|
||||
|
||||
/* Allows mark input as invalid when it's valid number but doesn't satisfy
|
||||
* arbitrary external criteria, e.g. is higher than maximum expected value. */
|
||||
property bool markAsInvalid: false
|
||||
@ -193,14 +197,11 @@ Control {
|
||||
return validator.maxDecimalDigits + validator.maxIntegralDigits
|
||||
} else {
|
||||
let availableSpaceForAmount = root.availableWidth - currencyField.contentWidth - layout.spacing
|
||||
return Math.floor(availableSpaceForAmount/textMetrics.tightBoundingRect.width)
|
||||
// k is a coefficient based on the font style (typically 𝑘 ≈ 0.6)
|
||||
let digitWidth = textField.font.pixelSize * 0.6
|
||||
return Math.floor(availableSpaceForAmount/digitWidth)
|
||||
}
|
||||
}
|
||||
|
||||
readonly property TextMetrics textMetrics: TextMetrics {
|
||||
font: textField.font
|
||||
text: "0"
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
@ -285,10 +286,12 @@ Control {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
Layout.bottomMargin: 12
|
||||
color: Theme.palette.separator
|
||||
color: Theme.palette.directColor8
|
||||
visible: root.dividerVisible
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
StatusBaseText {
|
||||
id: bottomItem
|
||||
|
||||
@ -346,6 +349,11 @@ Control {
|
||||
}
|
||||
visible: !root.bottomTextLoading
|
||||
}
|
||||
Loader {
|
||||
id: bottomRightComponent
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
LoadingComponent {
|
||||
objectName: "bottomItemTextLoadingComponent"
|
||||
|
Loading…
x
Reference in New Issue
Block a user