231 lines
8.6 KiB
QML
231 lines
8.6 KiB
QML
|
import QtQuick 2.13
|
||
|
import QtQuick.Layouts 1.13
|
||
|
|
||
|
import StatusQ.Controls 0.1
|
||
|
import StatusQ.Core 0.1
|
||
|
import StatusQ.Core.Theme 0.1
|
||
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||
|
|
||
|
import AppLayouts.Wallet 1.0
|
||
|
|
||
|
import utils 1.0
|
||
|
|
||
|
import "../controls"
|
||
|
|
||
|
Loader {
|
||
|
id: root
|
||
|
|
||
|
property var store
|
||
|
property bool isBridgeTx: false
|
||
|
property bool interactive: true
|
||
|
property bool showUnpreferredNetworks: false
|
||
|
property var selectedAsset
|
||
|
property var selectedRecipient: null
|
||
|
property int selectedRecipientType
|
||
|
|
||
|
readonly property bool ready: (d.isAddressValid || root.isENSValid) && !d.isPending
|
||
|
property string addressText
|
||
|
property bool isENSValid: false
|
||
|
property string resolvedENSAddress
|
||
|
|
||
|
signal recalculateRoutesAndFees()
|
||
|
signal isLoading()
|
||
|
|
||
|
onAddressTextChanged: d.isPending = false
|
||
|
|
||
|
onSelectedRecipientChanged: {
|
||
|
root.isLoading()
|
||
|
d.waitTimer.restart()
|
||
|
if(!!root.selectedRecipient && root.selectedRecipientType !== TabAddressSelectorView.Type.None) {
|
||
|
switch(root.selectedRecipientType) {
|
||
|
case TabAddressSelectorView.Type.SavedAddress: {
|
||
|
if (root.selectedRecipient.ens.length > 0) {
|
||
|
d.isPending = true
|
||
|
return store.resolveENS(root.selectedRecipient.ens)
|
||
|
}
|
||
|
}
|
||
|
case TabAddressSelectorView.Type.RecentsAddress: {
|
||
|
let isIncoming = root.selectedRecipient.to === root.selectedRecipient.address
|
||
|
root.addressText = isIncoming ? root.selectedRecipient.from : root.selectedRecipient.to
|
||
|
root.item.input.text = root.addressText
|
||
|
return
|
||
|
}
|
||
|
case TabAddressSelectorView.Type.Address: {
|
||
|
root.item.input.text = root.selectedRecipient.address
|
||
|
}
|
||
|
}
|
||
|
root.addressText = root.selectedRecipient.address
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QtObject {
|
||
|
id: d
|
||
|
property bool isAddressValid: Utils.isValidAddress(root.addressText)
|
||
|
readonly property var resolveENS: Backpressure.debounce(root, 500, function (ensName) {
|
||
|
store.resolveENS(ensName)
|
||
|
})
|
||
|
property bool isPending: false
|
||
|
function clearValues() {
|
||
|
root.addressText = ""
|
||
|
root.isENSValid = false
|
||
|
root.resolvedENSAddress = ""
|
||
|
root.selectedRecipientType = TabAddressSelectorView.Type.None
|
||
|
root.selectedRecipient = null
|
||
|
}
|
||
|
property Timer waitTimer: Timer {
|
||
|
interval: 1500
|
||
|
onTriggered: {
|
||
|
if(!!root.item) {
|
||
|
if (d.isPending) {
|
||
|
return
|
||
|
}
|
||
|
if (root.isENSValid) {
|
||
|
if(!!root.item.input)
|
||
|
root.item.input.text = root.resolvedENSAddress
|
||
|
root.addressText = root.resolvedENSAddress
|
||
|
store.splitAndFormatAddressPrefix(root.address, root.isBridgeTx, root.showUnpreferredNetworks)
|
||
|
} else {
|
||
|
let address = d.getAddress()
|
||
|
let result = store.splitAndFormatAddressPrefix(address, root.isBridgeTx, root.showUnpreferredNetworks)
|
||
|
if(!!result.address) {
|
||
|
root.addressText = result.address
|
||
|
if(!!root.item.input)
|
||
|
root.item.input.text = result.formattedText
|
||
|
}
|
||
|
}
|
||
|
root.recalculateRoutesAndFees()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function getAddress() {
|
||
|
if(root.selectedRecipientType === TabAddressSelectorView.Type.SavedAddress || root.selectedRecipientType === TabAddressSelectorView.Type.Account){
|
||
|
return root.item.chainShortNames + root.selectedRecipient.address
|
||
|
}
|
||
|
else {
|
||
|
return !!root.item.input && !!root.store.plainText(root.item.input.text) ? root.store.plainText(root.item.input.text): ""
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sourceComponent: root.selectedRecipientType === TabAddressSelectorView.Type.SavedAddress ? savedAddressRecipient:
|
||
|
root.selectedRecipientType === TabAddressSelectorView.Type.Account ? myAccountRecipient : addressRecipient
|
||
|
|
||
|
Component {
|
||
|
id: savedAddressRecipient
|
||
|
SavedAddressListItem {
|
||
|
property string chainShortNames: !!modelData ? modelData.chainShortNames: ""
|
||
|
implicitWidth: parent.width
|
||
|
modelData: root.selectedRecipient
|
||
|
radius: 8
|
||
|
clearVisible: true
|
||
|
color: Theme.palette.indirectColor1
|
||
|
sensor.enabled: false
|
||
|
subTitle: {
|
||
|
if(!!modelData) {
|
||
|
if (!!modelData && !!modelData.ens && modelData.ens.length > 0)
|
||
|
return Utils.richColorText(modelData.ens, Theme.palette.directColor1)
|
||
|
else
|
||
|
return WalletUtils.colorizedChainPrefix(modelData.chainShortNames) + StatusQUtils.Utils.elideText(modelData.address,6,4)
|
||
|
}
|
||
|
return ""
|
||
|
}
|
||
|
onCleared: d.clearValues()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Component {
|
||
|
id: myAccountRecipient
|
||
|
WalletAccountListItem {
|
||
|
implicitWidth: parent.width
|
||
|
chainShortNames: store.getAllNetworksSupportedString()
|
||
|
modelData: root.selectedRecipient
|
||
|
radius: 8
|
||
|
clearVisible: true
|
||
|
color: Theme.palette.indirectColor1
|
||
|
sensor.enabled: false
|
||
|
subTitle: {
|
||
|
if(!!modelData) {
|
||
|
let elidedAddress = StatusQUtils.Utils.elideText(modelData.address,6,4)
|
||
|
return WalletUtils.colorizedChainPrefix(chainShortNames) + StatusQUtils.Utils.elideText(elidedAddress,6,4)
|
||
|
}
|
||
|
return ""
|
||
|
}
|
||
|
onCleared: d.clearValues()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Component {
|
||
|
id: addressRecipient
|
||
|
StatusInput {
|
||
|
id: recipientInput
|
||
|
width: parent.width
|
||
|
height: visible ? implicitHeight: 0
|
||
|
visible: !root.isBridgeTx && !!root.selectedAsset
|
||
|
|
||
|
placeholderText: qsTr("Enter an ENS name or address")
|
||
|
input.background.color: Theme.palette.indirectColor1
|
||
|
input.background.border.width: 0
|
||
|
input.implicitHeight: 56
|
||
|
input.clearable: root.interactive
|
||
|
input.edit.readOnly: !root.interactive
|
||
|
multiline: false
|
||
|
input.edit.textFormat: TextEdit.RichText
|
||
|
|
||
|
input.rightComponent: RowLayout {
|
||
|
StatusButton {
|
||
|
font.weight: Font.Normal
|
||
|
borderColor: Theme.palette.primaryColor1
|
||
|
size: StatusBaseButton.Size.Tiny
|
||
|
text: qsTr("Paste")
|
||
|
visible: !store.plainText(recipientInput.text)
|
||
|
onClicked: recipientInput.input.edit.paste()
|
||
|
}
|
||
|
StatusIcon {
|
||
|
Layout.preferredWidth: 16
|
||
|
Layout.preferredHeight: 16
|
||
|
icon: "tiny/checkmark"
|
||
|
color: Theme.palette.primaryColor1
|
||
|
visible: !!store.plainText(recipientInput.text)
|
||
|
}
|
||
|
ClearButton {
|
||
|
Layout.preferredWidth: 24
|
||
|
Layout.preferredHeight: 24
|
||
|
visible: !!store.plainText(recipientInput.text)
|
||
|
onClicked: {
|
||
|
recipientInput.input.edit.clear()
|
||
|
d.clearValues()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Keys.onReleased: {
|
||
|
let plainText = store.plainText(input.edit.text)
|
||
|
if(!plainText) {
|
||
|
d.clearValues()
|
||
|
}
|
||
|
else {
|
||
|
root.isLoading()
|
||
|
d.waitTimer.restart()
|
||
|
if(!Utils.isValidAddress(plainText)) {
|
||
|
d.isPending = true
|
||
|
d.resolveENS(plainText)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Connections {
|
||
|
target: store.mainModuleInst
|
||
|
function onResolvedENS(resolvedPubKey: string, resolvedAddress: string, uuid: string) {
|
||
|
d.isPending = false
|
||
|
if(Utils.isValidAddress(resolvedAddress)) {
|
||
|
root.resolvedENSAddress = resolvedAddress
|
||
|
root.isENSValid = true
|
||
|
}
|
||
|
d.waitTimer.restart()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|