feat(@desktop/wallet): Implements the Send Modal Footer required for simple send
fixes #16918
This commit is contained in:
parent
77003fb052
commit
16e67a2137
|
@ -0,0 +1,56 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import AppLayouts.Wallet.views 1.0
|
||||
|
||||
SplitView {
|
||||
orientation: Qt.Vertical
|
||||
Logs { id: logs }
|
||||
|
||||
Rectangle {
|
||||
SplitView.fillHeight: true
|
||||
SplitView.fillWidth: true
|
||||
color: Theme.palette.indirectColor1
|
||||
|
||||
SendModalFooter {
|
||||
id: footer
|
||||
anchors.centerIn: parent
|
||||
width: 595
|
||||
|
||||
loading: loadingCheckbox.checked
|
||||
|
||||
onReviewSendClicked: console.log("review send clicked")
|
||||
}
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
id: logsAndControlsPanel
|
||||
|
||||
SplitView.minimumHeight: 100
|
||||
SplitView.preferredHeight: 200
|
||||
|
||||
logsView.logText: logs.logText
|
||||
|
||||
Column {
|
||||
CheckBox {
|
||||
id: loadingCheckbox
|
||||
text: "loading"
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "set fees values"
|
||||
onClicked: {
|
||||
loadingCheckbox.checked = false
|
||||
footer.estimateTime = "~60s"
|
||||
footer.estimatedFees = "1.45 EUR"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Views
|
|
@ -60,6 +60,12 @@ SplitView {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
property var setFees: Backpressure.debounce(root, 1500, function () {
|
||||
simpleSend.estimatedTime = "~60s"
|
||||
simpleSend.estimatedFiatFees = "1.45 EUR"
|
||||
simpleSend.estimatedCryptoFees = "0.0007 ETH"
|
||||
})
|
||||
}
|
||||
|
||||
PopupBackground {
|
||||
|
@ -87,7 +93,6 @@ SplitView {
|
|||
modal: false
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
|
||||
feesLoading: feesLoadingCheckbox.checked
|
||||
interactive: interactiveCheckbox.checked
|
||||
|
||||
accountsModel: d.walletAccountsModel
|
||||
|
@ -116,6 +121,12 @@ SplitView {
|
|||
}
|
||||
})
|
||||
|
||||
onFetchFees: {
|
||||
console.log("Fetch fees...")
|
||||
d.setFees()
|
||||
}
|
||||
onReviewSendClicked: console.log("Review send clicked")
|
||||
|
||||
Binding on selectedAccountAddress {
|
||||
value: accountsCombobox.currentValue ?? ""
|
||||
}
|
||||
|
@ -491,11 +502,6 @@ SplitView {
|
|||
checked: true
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: feesLoadingCheckbox
|
||||
text: "Fees loading"
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Select an accounts"
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ SplitView {
|
|||
anchors.centerIn: parent
|
||||
width: 400
|
||||
|
||||
cryptoFees: qsTr("0.0007 ETH")
|
||||
fiatFees: qsTr("1.45 EUR")
|
||||
loading: loadingCheckbox.checked
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import StatusQ.Controls 0.1
|
|||
import StatusQ.Components 0.1
|
||||
|
||||
import shared.controls 1.0 as SharedControls
|
||||
// TODO: remove all files and dependecies with this location once old send modal is removed
|
||||
// TODO: remove all files and dependencies with this location once old send modal is removed
|
||||
import shared.popups.send.controls 1.0
|
||||
import shared.popups.send 1.0
|
||||
|
||||
|
|
|
@ -11,13 +11,18 @@ Control {
|
|||
id: root
|
||||
|
||||
/** property to set fees in fiat along with fiat symbol **/
|
||||
property alias cryptoFees: cryptoFeesText.text
|
||||
property string cryptoFees
|
||||
/** property to set fees in crypto along with crypto symbol **/
|
||||
property alias fiatFees: fiatFeesText.text
|
||||
|
||||
property string fiatFees
|
||||
/** property to set loading state in the fees component **/
|
||||
property bool loading
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property string loadingText: "----------"
|
||||
}
|
||||
|
||||
implicitHeight: 64
|
||||
|
||||
padding: Theme.padding
|
||||
|
@ -63,7 +68,8 @@ Control {
|
|||
lineHeightMode: Text.FixedHeight
|
||||
lineHeight: 22
|
||||
|
||||
text: qsTr("0.0007 ETH")
|
||||
text: !!root.cryptoFees ? root.cryptoFees:
|
||||
d.loadingText
|
||||
}
|
||||
}
|
||||
StatusTextWithLoadingState {
|
||||
|
@ -76,7 +82,8 @@ Control {
|
|||
lineHeightMode: Text.FixedHeight
|
||||
lineHeight: 22
|
||||
|
||||
text: qsTr("1.45 EUR")
|
||||
text: !!root.fiatFees ? root.fiatFees:
|
||||
d.loadingText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,9 +80,14 @@ StatusDialog {
|
|||
required property var fnFormatCurrencyAmount
|
||||
|
||||
/** input property to decide if send modal is interactive or prefilled **/
|
||||
property bool interactive
|
||||
/** input property to decide if fees are loading **/
|
||||
property bool feesLoading
|
||||
property bool interactive: true
|
||||
|
||||
/** input property to set estimated time **/
|
||||
property string estimatedTime
|
||||
/** input property to set estimated fees in fiat **/
|
||||
property string estimatedFiatFees
|
||||
/** input property to set estimated fees in crypto **/
|
||||
property string estimatedCryptoFees
|
||||
|
||||
/** property to set and expose currently selected account **/
|
||||
property string selectedAccountAddress
|
||||
|
@ -100,11 +105,18 @@ StatusDialog {
|
|||
/** TODO: replace with new and improved recipient selector StatusDateRangePicker
|
||||
TBD under https://github.com/status-im/status-desktop/issues/16916 **/
|
||||
property alias selectedRecipientAddress: recipientsPanel.selectedRecipientAddress
|
||||
/** Input function to resolve Ens Name **/
|
||||
required property var fnResolveENS
|
||||
/** Output function to set resolved ens name values **/
|
||||
function ensNameResolved(resolvedPubKey, resolvedAddress, uuid) {
|
||||
recipientsPanel.ensNameResolved(resolvedPubKey, resolvedAddress, uuid)
|
||||
}
|
||||
|
||||
/** Output signal to request signing of the transaction **/
|
||||
signal reviewSendClicked()
|
||||
/** Output signal to request fetching fees **/
|
||||
signal fetchFees()
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
|
@ -162,6 +174,10 @@ StatusDialog {
|
|||
}
|
||||
})
|
||||
|
||||
readonly property var debounceSetSelectedAmount: Backpressure.debounce(root, 1500, function() {
|
||||
root.selectedAmount = amountToSend.text
|
||||
})
|
||||
|
||||
readonly property bool isCollectibleSelected: {
|
||||
if(!selectedTokenEntry)
|
||||
return false
|
||||
|
@ -180,11 +196,43 @@ StatusDialog {
|
|||
return WalletUtils.calculateMaxSafeSendAmount(maxCryptoBalance, d.selectedCryptoTokenSymbol)
|
||||
}
|
||||
|
||||
readonly property bool allValuesFilled: !!root.selectedAccountAddress &&
|
||||
root.selectedChainId !== 0 &&
|
||||
!!root.selectedTokenKey &&
|
||||
!!root.selectedRecipientAddress &&
|
||||
!!root.selectedAmount
|
||||
function allValuesFilledCorrectly() {
|
||||
return !!root.selectedAccountAddress &&
|
||||
root.selectedChainId !== 0 &&
|
||||
!!root.selectedTokenKey &&
|
||||
!!root.selectedRecipientAddress &&
|
||||
!!root.selectedAmount &&
|
||||
!amountToSend.markAsInvalid &&
|
||||
amountToSend.valid
|
||||
}
|
||||
|
||||
// handle multiple property changes from single changed signal
|
||||
property var combinedPropertyChangedHandler: [
|
||||
root.selectedAccountAddress,
|
||||
root.selectedChainId,
|
||||
root.selectedTokenKey,
|
||||
root.selectedRecipientAddress,
|
||||
root.selectedAmount,
|
||||
amountToSend.markAsInvalid,
|
||||
amountToSend.valid]
|
||||
onCombinedPropertyChangedHandlerChanged: Qt.callLater(() => d.fetchFees())
|
||||
|
||||
function resetFees() {
|
||||
root.estimatedCryptoFees = ""
|
||||
root.estimatedFiatFees = ""
|
||||
root.estimatedTime = ""
|
||||
}
|
||||
|
||||
function fetchFees() {
|
||||
resetFees()
|
||||
if(allValuesFilledCorrectly()) {
|
||||
root.fetchFees()
|
||||
}
|
||||
}
|
||||
|
||||
readonly property bool feesIsLoading: !root.estimatedCryptoFees &&
|
||||
!root.estimatedFiatFees &&
|
||||
!root.estimatedTime
|
||||
}
|
||||
|
||||
width: 556
|
||||
|
@ -198,9 +246,6 @@ StatusDialog {
|
|||
}
|
||||
|
||||
// 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)
|
||||
|
@ -343,6 +388,8 @@ StatusDialog {
|
|||
visible: !!root.selectedTokenKey && !d.isCollectibleSelected
|
||||
onVisibleChanged: if(visible) forceActiveFocus()
|
||||
|
||||
onTextChanged: d.debounceSetSelectedAmount()
|
||||
|
||||
bottomRightComponent: MaxSendButton {
|
||||
id: maxButton
|
||||
|
||||
|
@ -414,20 +461,24 @@ StatusDialog {
|
|||
SimpleTransactionsFees {
|
||||
Layout.fillWidth: true
|
||||
|
||||
loading: root.feesLoading
|
||||
cryptoFees: root.estimatedCryptoFees
|
||||
fiatFees: root.estimatedFiatFees
|
||||
loading: d.feesIsLoading && d.allValuesFilledCorrectly()
|
||||
}
|
||||
visible: d.allValuesFilled
|
||||
visible: d.allValuesFilledCorrectly()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO:: move to new location and rework if needed
|
||||
footer: TransactionModalFooter {
|
||||
width: parent.width
|
||||
pending: false
|
||||
nextButtonText: qsTr("Review Send")
|
||||
maxFiatFees: "..."
|
||||
totalTimeEstimate: "..."
|
||||
footer: SendModalFooter {
|
||||
width: root.width
|
||||
|
||||
estimateTime: root.estimatedTime
|
||||
estimatedFees: root.estimatedFiatFees
|
||||
|
||||
loading: d.feesIsLoading && d.allValuesFilledCorrectly()
|
||||
|
||||
onReviewSendClicked: root.reviewSendClicked()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQml.Models 2.15
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
|
||||
StatusDialogFooter {
|
||||
id: root
|
||||
|
||||
/** property to set loading state **/
|
||||
property bool loading
|
||||
/** property to set estimated time **/
|
||||
property string estimateTime
|
||||
/** property to set estimates fees in fiat **/
|
||||
property string estimatedFees
|
||||
|
||||
// Signal to propogate Send clicked
|
||||
signal reviewSendClicked()
|
||||
|
||||
implicitHeight: 82
|
||||
spacing: Theme.bigPadding
|
||||
color: Theme.palette.baseColor3
|
||||
dropShadowEnabled: true
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property string emptyText: "--"
|
||||
readonly property string loadingText: "----------"
|
||||
}
|
||||
|
||||
leftButtons: ObjectModel {
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: Theme.padding
|
||||
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
color: Theme.palette.directColor5
|
||||
text: qsTr("Est time")
|
||||
}
|
||||
StatusTextWithLoadingState {
|
||||
id: estimatedTime
|
||||
|
||||
customColor: !!root.estimateTime ? Theme.palette.directColor1:
|
||||
Theme.palette.directColor5
|
||||
loading: root.loading
|
||||
|
||||
text: !!root.estimateTime ? root.estimateTime:
|
||||
root.loading ? d.loadingText : d.emptyText
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
color: Theme.palette.directColor5
|
||||
text: qsTr("Est fees")
|
||||
}
|
||||
StatusTextWithLoadingState {
|
||||
id: estimatedFees
|
||||
|
||||
customColor: !!root.estimatedFees ? Theme.palette.directColor1:
|
||||
Theme.palette.directColor5
|
||||
loading: root.loading
|
||||
|
||||
text: !!root.estimatedFees ? root.estimatedFees:
|
||||
loading ? d.loadingText : d.emptyText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rightButtons: ObjectModel {
|
||||
StatusButton {
|
||||
objectName: "transactionModalFooterButton"
|
||||
|
||||
Layout.rightMargin: Theme.padding
|
||||
|
||||
disabledColor: Theme.palette.directColor8
|
||||
enabled: !!root.estimateTime &&
|
||||
!!root.estimatedFees &&
|
||||
!root.loading
|
||||
|
||||
text: qsTr("Review Send")
|
||||
|
||||
onClicked: root.reviewSendClicked()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,3 +7,4 @@ TokenSelectorCollectibleDelegate 1.0 TokenSelectorCollectibleDelegate.qml
|
|||
TokenSelectorSectionDelegate 1.0 TokenSelectorSectionDelegate.qml
|
||||
AccountContextMenu 1.0 AccountContextMenu.qml
|
||||
RecipientView 1.0 RecipientView.qml
|
||||
SendModalFooter 1.0 SendModalFooter.qml
|
||||
|
|
|
@ -671,6 +671,11 @@ Item {
|
|||
fnFormatCurrencyAmount: function(amount, symbol, options = null, locale = null) {
|
||||
return appMain.currencyStore.formatCurrencyAmount(amount, symbol)
|
||||
}
|
||||
// TODO remove this call to mainModule under #16919
|
||||
fnResolveENS: function(ensName, uuid) {
|
||||
mainModule.resolveENS(name, uuid)
|
||||
}
|
||||
|
||||
savedAddressesModel: WalletStores.RootStore.savedAddresses
|
||||
recentRecipientsModel: appMain.transactionStore.tempActivityController1Model
|
||||
|
||||
|
@ -678,6 +683,8 @@ Item {
|
|||
// It's requested from many nested places, so as a workaround we use
|
||||
// Global to shorten the path via global signal.
|
||||
Global.sendToRecipientRequested.connect(sendToRecipient)
|
||||
// TODO remove this call to mainModule under #16919
|
||||
mainModule.resolvedENS.connect(ensNameResolved)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,9 +88,15 @@ QtObject {
|
|||
required property var showCommunityAssetsInSend
|
||||
/** required function to format currency amount to locale string **/
|
||||
required property var fnFormatCurrencyAmount
|
||||
|
||||
required property var savedAddressesModel
|
||||
required property var recentRecipientsModel
|
||||
|
||||
/** required function to resolve an ens name **/
|
||||
required property var fnResolveENS
|
||||
/** required signal to receive resolved ens name address **/
|
||||
signal ensNameResolved(string resolvedPubKey, string resolvedAddress, string uuid)
|
||||
|
||||
function openSend(params = {}) {
|
||||
// TODO remove once simple send is feature complete
|
||||
let sendModalCmp = root.simpleSendEnabled ? simpleSendModalComponent: sendModalComponent
|
||||
|
@ -228,6 +234,7 @@ QtObject {
|
|||
|
||||
currentCurrency: root.currentCurrency
|
||||
fnFormatCurrencyAmount: root.fnFormatCurrencyAmount
|
||||
fnResolveENS: root.fnResolveENS
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
|
@ -259,6 +266,10 @@ QtObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.ensNameResolved.connect(ensNameResolved)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ Control {
|
|||
|
||||
objectName: "amountToSend_textField"
|
||||
|
||||
implicitHeight: 44
|
||||
Layout.preferredHeight: 44
|
||||
padding: 0
|
||||
background: null
|
||||
|
||||
|
@ -240,7 +240,7 @@ Control {
|
|||
: Theme.palette.dangerColor1
|
||||
|
||||
placeholderText: {
|
||||
if (!d.fiatMode || root.fiatDecimalPlaces === 0)
|
||||
if (!d.fiatMode || root.fiatDecimalPlaces === 0 || !!text)
|
||||
return "0"
|
||||
|
||||
return "0" + root.decimalPoint
|
||||
|
|
Loading…
Reference in New Issue