parent
2c2f87f654
commit
b8f41e35c4
|
@ -5,10 +5,12 @@ import QtQuick.Layouts 1.15
|
||||||
import Storybook 1.0
|
import Storybook 1.0
|
||||||
import Models 1.0
|
import Models 1.0
|
||||||
|
|
||||||
|
import StatusQ 0.1
|
||||||
import StatusQ.Core.Backpressure 0.1
|
import StatusQ.Core.Backpressure 0.1
|
||||||
|
|
||||||
import AppLayouts.Wallet.popups.buy 1.0
|
import AppLayouts.Wallet.popups.buy 1.0
|
||||||
import AppLayouts.Wallet.stores 1.0
|
import AppLayouts.Wallet.stores 1.0
|
||||||
|
import AppLayouts.Wallet.adaptors 1.0
|
||||||
|
|
||||||
import shared.stores 1.0
|
import shared.stores 1.0
|
||||||
|
|
||||||
|
@ -47,6 +49,22 @@ SplitView {
|
||||||
d.debounceFetchProviderUrl()
|
d.debounceFetchProviderUrl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property var currencyStore: CurrenciesStore {}
|
||||||
|
readonly property var assetsStore: WalletAssetsStore {
|
||||||
|
id: thisWalletAssetStore
|
||||||
|
walletTokensStore: TokensStore {
|
||||||
|
plainTokensBySymbolModel: TokensBySymbolModel {}
|
||||||
|
}
|
||||||
|
readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {}
|
||||||
|
assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel
|
||||||
|
}
|
||||||
|
readonly property BuyCryptoParamsForm buyCryptoInputParamsForm: BuyCryptoParamsForm{
|
||||||
|
selectedWalletAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
|
||||||
|
selectedNetworkChainId: 11155111
|
||||||
|
selectedTokenKey: "ETH"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupBackground {
|
PopupBackground {
|
||||||
|
@ -61,7 +79,12 @@ SplitView {
|
||||||
text: "Reopen"
|
text: "Reopen"
|
||||||
enabled: !buySellModal.visible
|
enabled: !buySellModal.visible
|
||||||
|
|
||||||
onClicked: buySellModal.open()
|
onClicked: {
|
||||||
|
buySellModal.buyCryptoInputParamsForm.selectedWalletAddress = "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
|
||||||
|
buySellModal.buyCryptoInputParamsForm.selectedNetworkChainId = 11155111
|
||||||
|
buySellModal.buyCryptoInputParamsForm.selectedTokenKey = "ETH"
|
||||||
|
buySellModal.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BuyCryptoModal {
|
BuyCryptoModal {
|
||||||
|
@ -70,29 +93,19 @@ SplitView {
|
||||||
visible: true
|
visible: true
|
||||||
modal: false
|
modal: false
|
||||||
closePolicy: Popup.CloseOnEscape
|
closePolicy: Popup.CloseOnEscape
|
||||||
buyCryptoAdaptor: BuyCryptoModalAdaptor {
|
buyProvidersModel: d.buyCryptoStore.providersModel
|
||||||
buyCryptoStore: d.buyCryptoStore
|
isBuyProvidersModelLoading: d.buyCryptoStore.areProvidersLoading
|
||||||
readonly property var currencyStore: CurrenciesStore {}
|
|
||||||
readonly property var assetsStore: WalletAssetsStore {
|
|
||||||
id: thisWalletAssetStore
|
|
||||||
walletTokensStore: TokensStore {
|
|
||||||
plainTokensBySymbolModel: TokensBySymbolModel {}
|
|
||||||
}
|
|
||||||
readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {}
|
|
||||||
assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel
|
|
||||||
}
|
|
||||||
buyCryptoFormData: buySellModal.buyCryptoInputParamsForm
|
|
||||||
walletAccountsModel: WalletAccountsModel{}
|
walletAccountsModel: WalletAccountsModel{}
|
||||||
networksModel: NetworksModel.flatNetworks
|
networksModel: NetworksModel.flatNetworks
|
||||||
areTestNetworksEnabled: true
|
areTestNetworksEnabled: true
|
||||||
groupedAccountAssetsModel: assetsStore.groupedAccountAssetsModel
|
currentCurrency: d.currencyStore.currentCurrency
|
||||||
plainTokensBySymbolModel: assetsStore.walletTokensStore.plainTokensBySymbolModel
|
plainTokensBySymbolModel: d.assetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
currentCurrency: currencyStore.currentCurrency
|
groupedAccountAssetsModel: d.assetsStore.groupedAccountAssetsModel
|
||||||
}
|
buyCryptoInputParamsForm: d.buyCryptoInputParamsForm
|
||||||
buyCryptoInputParamsForm: BuyCryptoParamsForm{
|
Component.onCompleted: {
|
||||||
selectedWalletAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
|
fetchProviders.connect(d.buyCryptoStore.fetchProviders)
|
||||||
selectedNetworkChainId: 11155111
|
fetchProviderUrl.connect(d.buyCryptoStore.fetchProviderUrl)
|
||||||
selectedTokenKey: "ETH"
|
d.buyCryptoStore.providerUrlReady.connect(providerUrlReady)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ import QtTest 1.15
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import StatusQ 0.1
|
||||||
|
import StatusQ.Core.Utils 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||||
import StatusQ.Core.Backpressure 0.1
|
import StatusQ.Core.Backpressure 0.1
|
||||||
|
@ -22,22 +24,44 @@ Item {
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
property string uuid
|
|
||||||
property var debounceFetchProviderUrl: Backpressure.debounce(root, 500, function() {
|
}
|
||||||
d.buyCryptoStore.providerUrlReady(d.uuid, "xxxx")
|
|
||||||
})
|
Component {
|
||||||
property var debounceFetchProvidersList: Backpressure.debounce(root, 500, function() {
|
id: componentUnderTest
|
||||||
d.buyCryptoStore.areProvidersLoading = false
|
BuyCryptoModal {
|
||||||
})
|
id: buySellModal
|
||||||
|
|
||||||
|
buyProvidersModel: buyCryptoStore.providersModel
|
||||||
|
isBuyProvidersModelLoading: buyCryptoStore.areProvidersLoading
|
||||||
|
currentCurrency: currencyStore.currentCurrency
|
||||||
|
walletAccountsModel: WalletAccountsModel{}
|
||||||
|
networksModel: NetworksModel.flatNetworks
|
||||||
|
areTestNetworksEnabled: true
|
||||||
|
plainTokensBySymbolModel: assetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
groupedAccountAssetsModel: assetsStore.groupedAccountAssetsModel
|
||||||
|
buyCryptoInputParamsForm: BuyCryptoParamsForm {
|
||||||
|
selectedWalletAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
|
||||||
|
selectedNetworkChainId: 11155111
|
||||||
|
selectedTokenKey: "ETH"
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
fetchProviders.connect(buyCryptoStore.fetchProviders)
|
||||||
|
fetchProviderUrl.connect(buyCryptoStore.fetchProviderUrl)
|
||||||
|
buyCryptoStore.providerUrlReady.connect(buySellModal.providerUrlReady)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporary assignments to make tests run independently
|
||||||
|
readonly property var currencyStore: CurrenciesStore {}
|
||||||
readonly property var buyCryptoStore: BuyCryptoStore {
|
readonly property var buyCryptoStore: BuyCryptoStore {
|
||||||
readonly property var providersModel: _onRampProvidersModel
|
readonly property var providersModel: OnRampProvidersModel{}
|
||||||
property bool areProvidersLoading
|
property bool areProvidersLoading
|
||||||
signal providerUrlReady(string uuid ,string url)
|
signal providerUrlReady(string uuid ,string url)
|
||||||
|
|
||||||
function fetchProviders() {
|
function fetchProviders() {
|
||||||
console.warn("fetchProviders called >>")
|
console.warn("fetchProviders called >>")
|
||||||
areProvidersLoading = true
|
areProvidersLoading = true
|
||||||
d.debounceFetchProvidersList()
|
debounceFetchProvidersList()
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchProviderUrl(uuid, providerID,
|
function fetchProviderUrl(uuid, providerID,
|
||||||
|
@ -46,32 +70,27 @@ Item {
|
||||||
console.warn("fetchProviderUrl called >> uuid: ", uuid, "providerID: ",providerID
|
console.warn("fetchProviderUrl called >> uuid: ", uuid, "providerID: ",providerID
|
||||||
, "isRecurrent: ", isRecurrent, "accountAddress: ", accountAddress,
|
, "isRecurrent: ", isRecurrent, "accountAddress: ", accountAddress,
|
||||||
"chainID: ", chainID, "symbol: ", symbol)
|
"chainID: ", chainID, "symbol: ", symbol)
|
||||||
d.uuid = uuid
|
buySellModal.uuid = uuid
|
||||||
d.debounceFetchProviderUrl()
|
debounceFetchProviderUrl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
readonly property ModelEntry selectedAccountEntry: ModelEntry {
|
||||||
|
sourceModel: walletAccountsModel
|
||||||
|
key: "address"
|
||||||
|
value: buyCryptoInputParamsForm.selectedWalletAddress
|
||||||
}
|
}
|
||||||
|
readonly property ModelEntry selectedProviderEntry: ModelEntry {
|
||||||
OnRampProvidersModel{
|
sourceModel: buyCryptoStore.providersModel
|
||||||
id: _onRampProvidersModel
|
key: "id"
|
||||||
|
value: buyCryptoInputParamsForm.selectedProviderId
|
||||||
}
|
}
|
||||||
|
readonly property var recurrentOnRampProvidersModel: SortFilterProxyModel {
|
||||||
SortFilterProxyModel {
|
sourceModel: buyProvidersModel
|
||||||
id: recurrentOnRampProvidersModel
|
|
||||||
sourceModel: _onRampProvidersModel
|
|
||||||
filters: ValueFilter {
|
filters: ValueFilter {
|
||||||
roleName: "supportsRecurrentPurchase"
|
roleName: "supportsRecurrentPurchase"
|
||||||
value: true
|
value: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: componentUnderTest
|
|
||||||
BuyCryptoModal {
|
|
||||||
id: buySellModal
|
|
||||||
buyCryptoAdaptor: BuyCryptoModalAdaptor {
|
|
||||||
buyCryptoStore: d.buyCryptoStore
|
|
||||||
readonly property var currencyStore: CurrenciesStore {}
|
|
||||||
readonly property var assetsStore: WalletAssetsStore {
|
readonly property var assetsStore: WalletAssetsStore {
|
||||||
id: thisWalletAssetStore
|
id: thisWalletAssetStore
|
||||||
walletTokensStore: TokensStore {
|
walletTokensStore: TokensStore {
|
||||||
|
@ -80,19 +99,13 @@ Item {
|
||||||
readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {}
|
readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {}
|
||||||
assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel
|
assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel
|
||||||
}
|
}
|
||||||
buyCryptoFormData: buySellModal.buyCryptoInputParamsForm
|
property string uuid
|
||||||
walletAccountsModel: WalletAccountsModel{}
|
property var debounceFetchProviderUrl: Backpressure.debounce(root, 500, function() {
|
||||||
networksModel: NetworksModel.flatNetworks
|
buySellModal.buyCryptoStore.providerUrlReady(uuid, "xxxx")
|
||||||
areTestNetworksEnabled: true
|
})
|
||||||
groupedAccountAssetsModel: assetsStore.groupedAccountAssetsModel
|
property var debounceFetchProvidersList: Backpressure.debounce(root, 500, function() {
|
||||||
plainTokensBySymbolModel: assetsStore.walletTokensStore.plainTokensBySymbolModel
|
buySellModal.buyCryptoStore.areProvidersLoading = false
|
||||||
currentCurrency: currencyStore.currentCurrency
|
})
|
||||||
}
|
|
||||||
buyCryptoInputParamsForm: BuyCryptoParamsForm{
|
|
||||||
selectedWalletAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
|
|
||||||
selectedNetworkChainId: 11155111
|
|
||||||
selectedTokenKey: "ETH"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,11 +122,15 @@ Item {
|
||||||
property BuyCryptoModal controlUnderTest: null
|
property BuyCryptoModal controlUnderTest: null
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
notificationSpy.clear()
|
||||||
controlUnderTest = createTemporaryObject(componentUnderTest, root)
|
controlUnderTest = createTemporaryObject(componentUnderTest, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
function launchPopup() {
|
function launchPopup() {
|
||||||
verify(!!controlUnderTest)
|
verify(!!controlUnderTest)
|
||||||
|
controlUnderTest.buyCryptoInputParamsForm.selectedWalletAddress = "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
|
||||||
|
controlUnderTest.buyCryptoInputParamsForm.selectedNetworkChainId = 11155111
|
||||||
|
controlUnderTest.buyCryptoInputParamsForm.selectedTokenKey = "ETH"
|
||||||
controlUnderTest.open()
|
controlUnderTest.open()
|
||||||
verify(!!controlUnderTest.opened)
|
verify(!!controlUnderTest.opened)
|
||||||
}
|
}
|
||||||
|
@ -126,26 +143,152 @@ Item {
|
||||||
compare(delegateUnderTest.title, modelToCompareAgainst.get(i).name)
|
compare(delegateUnderTest.title, modelToCompareAgainst.get(i).name)
|
||||||
compare(delegateUnderTest.subTitle, modelToCompareAgainst.get(i).description)
|
compare(delegateUnderTest.subTitle, modelToCompareAgainst.get(i).description)
|
||||||
compare(delegateUnderTest.asset.name, modelToCompareAgainst.get(i).logoUrl)
|
compare(delegateUnderTest.asset.name, modelToCompareAgainst.get(i).logoUrl)
|
||||||
|
compare(delegateUnderTest.isUrlLoading, false)
|
||||||
|
|
||||||
const feesText = findChild(delegateUnderTest, "feesText")
|
const feesText = findChild(delegateUnderTest, "feesText")
|
||||||
verify(!!feesText)
|
verify(!!feesText)
|
||||||
compare(feesText.text, modelToCompareAgainst.get(i).fees)
|
compare(feesText.text, modelToCompareAgainst.get(i).fees)
|
||||||
|
|
||||||
/* TODO: fix when writing more tests for this functionality
|
const loadingIndicator = findChild(delegateUnderTest, "loadingIndicator")
|
||||||
const externalLinkIcon = findChild(delegateUnderTest, "externalLinkIcon")
|
verify(!!loadingIndicator)
|
||||||
verify(!!externalLinkIcon)
|
verify(!loadingIndicator.visible)
|
||||||
compare(externalLinkIcon.icon, "tiny/external")
|
|
||||||
compare(externalLinkIcon.color, Theme.palette.baseColor1) */
|
var extraIcon = null
|
||||||
|
if (modelToCompareAgainst.get(i).urlsNeedParameters) {
|
||||||
|
extraIcon = findChild(delegateUnderTest, "chevron-down-icon")
|
||||||
|
verify(!!extraIcon)
|
||||||
|
compare(extraIcon.icon, "chevron-down")
|
||||||
|
compare(extraIcon.rotation, 270)
|
||||||
|
compare(extraIcon.color, Theme.palette.baseColor1)
|
||||||
|
} else {
|
||||||
|
extraIcon = findChild(delegateUnderTest, "tiny/external-icon")
|
||||||
|
verify(!!extraIcon)
|
||||||
|
compare(extraIcon.icon, "tiny/external")
|
||||||
|
compare(extraIcon.rotation, 0)
|
||||||
|
compare(extraIcon.color, Theme.palette.baseColor1)
|
||||||
|
}
|
||||||
|
|
||||||
// Hover over the item and check hovered state
|
// Hover over the item and check hovered state
|
||||||
mouseMove(delegateUnderTest, delegateUnderTest.width/2, delegateUnderTest.height/2)
|
mouseMove(delegateUnderTest, delegateUnderTest.width/2, delegateUnderTest.height/2)
|
||||||
verify(delegateUnderTest.sensor.containsMouse)
|
verify(delegateUnderTest.sensor.containsMouse)
|
||||||
/* TODO: fix when writing more tests for this functionality
|
compare(extraIcon.color, Theme.palette.directColor1)
|
||||||
compare(externalLinkIcon.color, Theme.palette.directColor1) */
|
|
||||||
verify(delegateUnderTest.color, Theme.palette.baseColor2)
|
verify(delegateUnderTest.color, Theme.palette.baseColor2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testDelegateMouseClicksForProvidersThatNeedParams(delegateUnderTest, modelData) {
|
||||||
|
const loadingIndicator = findChild(delegateUnderTest, "loadingIndicator")
|
||||||
|
verify(!!loadingIndicator)
|
||||||
|
verify(!loadingIndicator.visible)
|
||||||
|
|
||||||
|
verify(!controlUnderTest.replaceItem)
|
||||||
|
|
||||||
|
// test mouse click
|
||||||
|
tryCompare(notificationSpy, "count", 0)
|
||||||
|
mouseClick(delegateUnderTest)
|
||||||
|
|
||||||
|
waitForRendering(controlUnderTest.replaceLoader)
|
||||||
|
verify(controlUnderTest.replaceItem)
|
||||||
|
|
||||||
|
const selectParamsPanel = findChild(controlUnderTest, "selectParamsPanel")
|
||||||
|
verify(!!selectParamsPanel)
|
||||||
|
|
||||||
|
// title should not change
|
||||||
|
verify(controlUnderTest.stackTitle, qsTr("Buy assets for %1").arg(!!controlUnderTest.selectedAccountEntry.item ? controlUnderTest.selectedAccountEntry.item.name: ""))
|
||||||
|
|
||||||
|
compare(controlUnderTest.rightButtons.length, 2)
|
||||||
|
verify(controlUnderTest.rightButtons[0].visible)
|
||||||
|
verify(controlUnderTest.rightButtons[1].enabled)
|
||||||
|
verify(controlUnderTest.rightButtons[0].text, qsTr("Buy via %1").arg(!!controlUnderTest.selectedProviderEntry.item ? controlUnderTest.selectedProviderEntry.item.name: ""))
|
||||||
|
verify(!controlUnderTest.rightButtons[1].visible)
|
||||||
|
verify(controlUnderTest.backButton.visible)
|
||||||
|
|
||||||
|
const selectParamsForBuyCryptoPanelHeader = findChild(selectParamsPanel, "selectParamsForBuyCryptoPanelHeader")
|
||||||
|
verify(!!selectParamsForBuyCryptoPanelHeader)
|
||||||
|
compare(selectParamsForBuyCryptoPanelHeader.title, qsTr("Buy via %1").arg(!!controlUnderTest.selectedProviderEntry.item ? controlUnderTest.selectedProviderEntry.item.name: ""))
|
||||||
|
compare(selectParamsForBuyCryptoPanelHeader.subTitle, qsTr("Select which network and asset"))
|
||||||
|
compare(selectParamsForBuyCryptoPanelHeader.statusListItemTitle.color, Theme.palette.directColor1)
|
||||||
|
compare(selectParamsForBuyCryptoPanelHeader.asset.name, !!controlUnderTest.selectedProviderEntry.item ? controlUnderTest.selectedProviderEntry.item .logoUrl: "")
|
||||||
|
compare(selectParamsForBuyCryptoPanelHeader.color, Theme.palette.transparent)
|
||||||
|
compare(selectParamsForBuyCryptoPanelHeader.enabled, false)
|
||||||
|
|
||||||
|
const networkFilter = findChild(selectParamsPanel, "networkFilter")
|
||||||
|
verify(!!networkFilter)
|
||||||
|
compare(networkFilter.selection, [controlUnderTest.buyCryptoInputParamsForm.selectedNetworkChainId])
|
||||||
|
|
||||||
|
const tokenSelector = findChild(selectParamsPanel, "tokenSelector")
|
||||||
|
verify(!!tokenSelector)
|
||||||
|
compare(tokenSelector.currentTokensKey, controlUnderTest.buyCryptoInputParamsForm.selectedTokenKey)
|
||||||
|
|
||||||
|
const selectedTokenItem = findChild(selectParamsPanel, "selectedTokenItem")
|
||||||
|
verify(!!selectedTokenItem)
|
||||||
|
|
||||||
|
const modelDataToTest = ModelUtils.getByKey(tokenSelector.model, "tokensKey", tokenSelector.currentTokensKey)
|
||||||
|
const tokenSelectorIcon = findChild(selectedTokenItem, "tokenSelectorIcon")
|
||||||
|
verify(!!tokenSelectorIcon)
|
||||||
|
compare(tokenSelectorIcon.image.source, modelDataToTest.iconSource)
|
||||||
|
|
||||||
|
const tokenSelectorContentItemName = findChild(selectedTokenItem, "tokenSelectorContentItemName")
|
||||||
|
verify(!!tokenSelectorContentItemName)
|
||||||
|
compare(tokenSelectorContentItemName.text, modelDataToTest.name)
|
||||||
|
|
||||||
|
const tokenSelectorContentItemSymbol = findChild(selectedTokenItem, "tokenSelectorContentItemSymbol")
|
||||||
|
verify(!!tokenSelectorContentItemSymbol)
|
||||||
|
compare(tokenSelectorContentItemSymbol.text, modelDataToTest.symbol)
|
||||||
|
|
||||||
|
//switch to a network that has no tokens and ensure its reset
|
||||||
|
controlUnderTest.buyCryptoInputParamsForm.selectedNetworkChainId = 421613
|
||||||
|
|
||||||
|
waitForRendering(selectParamsPanel)
|
||||||
|
|
||||||
|
const nothingSelectedContentItem = findChild(selectParamsPanel, "tokenSelectorContentItemText")
|
||||||
|
verify(!!nothingSelectedContentItem)
|
||||||
|
verify(!selectedTokenItem.visible)
|
||||||
|
verify(!controlUnderTest.rightButtons[0].enabled)
|
||||||
|
|
||||||
|
// switch back a network and token thats valid and check if clicking buy button works properly
|
||||||
|
controlUnderTest.buyCryptoInputParamsForm.selectedNetworkChainId = 11155111
|
||||||
|
controlUnderTest.buyCryptoInputParamsForm.selectedTokenKey = "ETH"
|
||||||
|
|
||||||
|
waitForRendering(selectParamsPanel)
|
||||||
|
verify(controlUnderTest.rightButtons[0].enabled)
|
||||||
|
|
||||||
|
mouseClick(controlUnderTest.rightButtons[0])
|
||||||
|
|
||||||
|
verify(controlUnderTest.rightButtons[0].loading)
|
||||||
|
tryCompare(notificationSpy, "count", 1)
|
||||||
|
compare(notificationSpy.signalArguments[0][0], "xxxx")
|
||||||
|
compare(notificationSpy.signalArguments[0][1], modelData.hostname)
|
||||||
|
notificationSpy.clear()
|
||||||
|
|
||||||
|
// popup should be closed
|
||||||
|
verify(!controlUnderTest.opened)
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDelegateMouseClicksForProvidersThatNeedNoParams(delegateUnderTest, modelData) {
|
||||||
|
// test provider that need no parameters and we directly redirect to the site
|
||||||
|
const loadingIndicator = findChild(delegateUnderTest, "loadingIndicator")
|
||||||
|
verify(!!loadingIndicator)
|
||||||
|
verify(!loadingIndicator.visible)
|
||||||
|
|
||||||
|
const extraIcon = findChild(delegateUnderTest, "tiny/external-icon")
|
||||||
|
verify(!!extraIcon)
|
||||||
|
verify(!extraIcon.visble)
|
||||||
|
|
||||||
|
// test mouse click
|
||||||
|
tryCompare(notificationSpy, "count", 0)
|
||||||
|
mouseClick(delegateUnderTest)
|
||||||
|
|
||||||
|
verify(loadingIndicator.visible)
|
||||||
|
tryCompare(notificationSpy, "count", 1)
|
||||||
|
compare(notificationSpy.signalArguments[0][0], "xxxx")
|
||||||
|
compare(notificationSpy.signalArguments[0][1], modelData.hostname)
|
||||||
|
notificationSpy.clear()
|
||||||
|
|
||||||
|
// popup should be closed
|
||||||
|
verify(!controlUnderTest.opened)
|
||||||
|
}
|
||||||
|
|
||||||
function test_launchAndCloseModal() {
|
function test_launchAndCloseModal() {
|
||||||
launchPopup()
|
launchPopup()
|
||||||
|
|
||||||
|
@ -165,6 +308,8 @@ Item {
|
||||||
compare(controlUnderTest.rightButtons[1].text, qsTr("Done"))
|
compare(controlUnderTest.rightButtons[1].text, qsTr("Done"))
|
||||||
mouseClick(controlUnderTest.rightButtons[1])
|
mouseClick(controlUnderTest.rightButtons[1])
|
||||||
|
|
||||||
|
verify(!controlUnderTest.backButton.visible)
|
||||||
|
|
||||||
// popup should be closed
|
// popup should be closed
|
||||||
verify(!controlUnderTest.opened)
|
verify(!controlUnderTest.opened)
|
||||||
}
|
}
|
||||||
|
@ -173,6 +318,8 @@ Item {
|
||||||
// Launch modal
|
// Launch modal
|
||||||
launchPopup()
|
launchPopup()
|
||||||
|
|
||||||
|
verify(controlUnderTest.stackTitle, qsTr("Buy assets for %1").arg(!!controlUnderTest.selectedAccountEntry.item ? controlUnderTest.selectedAccountEntry.item.name: ""))
|
||||||
|
|
||||||
// find tab bar
|
// find tab bar
|
||||||
const tabBar = findChild(controlUnderTest, "tabBar")
|
const tabBar = findChild(controlUnderTest, "tabBar")
|
||||||
verify(!!tabBar)
|
verify(!!tabBar)
|
||||||
|
@ -210,10 +357,9 @@ Item {
|
||||||
|
|
||||||
// find providers list
|
// find providers list
|
||||||
const providersList = findChild(controlUnderTest, "providersList")
|
const providersList = findChild(controlUnderTest, "providersList")
|
||||||
waitForRendering(providersList)
|
|
||||||
verify(!!providersList)
|
verify(!!providersList)
|
||||||
|
|
||||||
tryCompare(controlUnderTest.buyCryptoAdaptor.buyCryptoStore, "areProvidersLoading", false)
|
tryCompare(controlUnderTest, "isBuyProvidersModelLoading", false)
|
||||||
|
|
||||||
mouseClick(tabBar.itemAt(0))
|
mouseClick(tabBar.itemAt(0))
|
||||||
compare(tabBar.currentIndex, 0)
|
compare(tabBar.currentIndex, 0)
|
||||||
|
@ -222,21 +368,42 @@ Item {
|
||||||
compare(providersList.count, 4)
|
compare(providersList.count, 4)
|
||||||
|
|
||||||
// check if delegate contents are as expected
|
// check if delegate contents are as expected
|
||||||
testDelegateItems(providersList, _onRampProvidersModel)
|
testDelegateItems(providersList, controlUnderTest.buyProvidersModel)
|
||||||
|
|
||||||
let delegateUnderTest = providersList.itemAtIndex(0)
|
controlUnderTest.close()
|
||||||
verify(!!delegateUnderTest)
|
}
|
||||||
|
|
||||||
// test mouse click
|
function test_modalContent_OneTime_tab_mouseClicks() {
|
||||||
tryCompare(notificationSpy, "count", 0)
|
|
||||||
mouseClick(delegateUnderTest)
|
|
||||||
tryCompare(notificationSpy, "count", 1)
|
|
||||||
compare(notificationSpy.signalArguments[0][0], "xxxx")
|
|
||||||
compare(notificationSpy.signalArguments[0][1], _onRampProvidersModel.get(0).hostname)
|
|
||||||
notificationSpy.clear()
|
notificationSpy.clear()
|
||||||
|
// Launch modal
|
||||||
|
launchPopup()
|
||||||
|
|
||||||
// popup should be closed
|
// find providers list
|
||||||
verify(!controlUnderTest.opened)
|
const providersList = findChild(controlUnderTest, "providersList")
|
||||||
|
verify(!!providersList)
|
||||||
|
|
||||||
|
for(let i =0; i< controlUnderTest.buyProvidersModel.count; i++) {
|
||||||
|
notificationSpy.clear()
|
||||||
|
launchPopup()
|
||||||
|
verify(controlUnderTest.opened)
|
||||||
|
|
||||||
|
tryCompare(controlUnderTest, "isBuyProvidersModelLoading", false)
|
||||||
|
|
||||||
|
let delegateUnderTest = providersList.itemAtIndex(i)
|
||||||
|
verify(!!delegateUnderTest)
|
||||||
|
waitForRendering(delegateUnderTest)
|
||||||
|
|
||||||
|
// test provider that need parameters like network and token to be selected
|
||||||
|
const modelData = controlUnderTest.buyProvidersModel.get(i)
|
||||||
|
verify(!!modelData)
|
||||||
|
if (modelData.urlsNeedParameters) {
|
||||||
|
testDelegateMouseClicksForProvidersThatNeedParams(delegateUnderTest, modelData)
|
||||||
|
} else {
|
||||||
|
testDelegateMouseClicksForProvidersThatNeedNoParams(delegateUnderTest, modelData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controlUnderTest.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_modalContent_recurrent_tab() {
|
function test_modalContent_recurrent_tab() {
|
||||||
|
@ -252,7 +419,7 @@ Item {
|
||||||
const providersList = findChild(controlUnderTest, "providersList")
|
const providersList = findChild(controlUnderTest, "providersList")
|
||||||
verify(!!providersList)
|
verify(!!providersList)
|
||||||
|
|
||||||
tryCompare(controlUnderTest.buyCryptoAdaptor.buyCryptoStore, "areProvidersLoading", false)
|
tryCompare(controlUnderTest, "isBuyProvidersModelLoading", false)
|
||||||
|
|
||||||
// check data in "Recurrent" tab --------------------------------------------------------
|
// check data in "Recurrent" tab --------------------------------------------------------
|
||||||
mouseClick(tabBar.itemAt(1))
|
mouseClick(tabBar.itemAt(1))
|
||||||
|
@ -264,18 +431,48 @@ Item {
|
||||||
compare(providersList.count, 1)
|
compare(providersList.count, 1)
|
||||||
|
|
||||||
// check if delegate contents are as expected
|
// check if delegate contents are as expected
|
||||||
testDelegateItems(providersList, recurrentOnRampProvidersModel)
|
testDelegateItems(providersList, controlUnderTest.recurrentOnRampProvidersModel)
|
||||||
|
controlUnderTest.close()
|
||||||
|
}
|
||||||
|
|
||||||
let delegateUnderTest = providersList.itemAtIndex(0)
|
function test_modalContent_Recurrent_tab_mouseClicks() {
|
||||||
verify(!!delegateUnderTest)
|
|
||||||
|
|
||||||
// test mouse click
|
|
||||||
tryCompare(notificationSpy, "count", 0)
|
|
||||||
verify(controlUnderTest.opened)
|
|
||||||
mouseClick(delegateUnderTest)
|
|
||||||
tryCompare(notificationSpy, "count", 0)
|
|
||||||
notificationSpy.clear()
|
notificationSpy.clear()
|
||||||
//TODO: add more test logic here for second page of selecting params
|
// Launch modal
|
||||||
|
launchPopup()
|
||||||
|
|
||||||
|
// find tab bar
|
||||||
|
const tabBar = findChild(controlUnderTest, "tabBar")
|
||||||
|
verify(!!tabBar)
|
||||||
|
|
||||||
|
// find providers list
|
||||||
|
const providersList = findChild(controlUnderTest, "providersList")
|
||||||
|
verify(!!providersList)
|
||||||
|
|
||||||
|
mouseClick(tabBar.itemAt(1))
|
||||||
|
compare(tabBar.currentIndex, 1)
|
||||||
|
waitForRendering(providersList)
|
||||||
|
verify(!!providersList)
|
||||||
|
|
||||||
|
for(let i =0; i< controlUnderTest.recurrentOnRampProvidersModel.count; i++) {
|
||||||
|
notificationSpy.clear()
|
||||||
|
launchPopup()
|
||||||
|
verify(controlUnderTest.opened)
|
||||||
|
|
||||||
|
tryCompare(controlUnderTest, "isBuyProvidersModelLoading", false)
|
||||||
|
|
||||||
|
let delegateUnderTest = providersList.itemAtIndex(i)
|
||||||
|
verify(!!delegateUnderTest)
|
||||||
|
waitForRendering(delegateUnderTest)
|
||||||
|
|
||||||
|
// test provider that need parameters like network and token to be selected
|
||||||
|
const modelData = controlUnderTest.recurrentOnRampProvidersModel.get(i)
|
||||||
|
verify(!!modelData)
|
||||||
|
if (modelData.urlsNeedParameters) {
|
||||||
|
testDelegateMouseClicksForProvidersThatNeedParams(delegateUnderTest, modelData)
|
||||||
|
} else {
|
||||||
|
testDelegateMouseClicksForProvidersThatNeedNoParams(delegateUnderTest, modelData)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,13 @@ StatusListItem {
|
||||||
loading: root.loading
|
loading: root.loading
|
||||||
},
|
},
|
||||||
StatusIcon {
|
StatusIcon {
|
||||||
objectName: "externalLinkIcon"
|
|
||||||
icon: root.urlsNeedParameters ? "chevron-down": "tiny/external"
|
icon: root.urlsNeedParameters ? "chevron-down": "tiny/external"
|
||||||
rotation: root.urlsNeedParameters ? 270: 0
|
rotation: root.urlsNeedParameters ? 270: 0
|
||||||
color: sensor.containsMouse ? Theme.palette.directColor1: Theme.palette.baseColor1
|
color: sensor.containsMouse ? Theme.palette.directColor1: Theme.palette.baseColor1
|
||||||
visible: !root.loading && !root.isUrlLoading
|
visible: !root.loading && !root.isUrlLoading
|
||||||
},
|
},
|
||||||
StatusLoadingIndicator {
|
StatusLoadingIndicator {
|
||||||
|
objectName: "loadingIndicator"
|
||||||
visible: root.isUrlLoading
|
visible: root.isUrlLoading
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,7 +16,7 @@ ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// required properties
|
// required properties
|
||||||
required property var adaptor
|
required property var assetsModel
|
||||||
required property var selectedProvider
|
required property var selectedProvider
|
||||||
required property string selectedTokenKey
|
required property string selectedTokenKey
|
||||||
required property int selectedNetworkChainId
|
required property int selectedNetworkChainId
|
||||||
|
@ -27,9 +27,24 @@ ColumnLayout {
|
||||||
signal networkSelected(int chainId)
|
signal networkSelected(int chainId)
|
||||||
signal tokenSelected(string tokensKey)
|
signal tokenSelected(string tokensKey)
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
function updateTokenSelector() {
|
||||||
|
Qt.callLater(()=> {
|
||||||
|
if(!!holdingSelector.model && !!root.selectedTokenKey && root.selectedNetworkChainId !== -1) {
|
||||||
|
holdingSelector.selectToken(root.selectedTokenKey)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectedTokenKeyChanged: d.updateTokenSelector()
|
||||||
|
onSelectedNetworkChainIdChanged: d.updateTokenSelector()
|
||||||
|
|
||||||
spacing: 20
|
spacing: 20
|
||||||
|
|
||||||
StatusListItem {
|
StatusListItem {
|
||||||
|
objectName: "selectParamsForBuyCryptoPanelHeader"
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
|
@ -81,8 +96,9 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
TokenSelector {
|
TokenSelector {
|
||||||
id: holdingSelector
|
id: holdingSelector
|
||||||
|
objectName: "tokenSelector"
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
model: root.adaptor.outputAssetsModel
|
model: root.assetsModel
|
||||||
popup.width: parent.width
|
popup.width: parent.width
|
||||||
contentItem: Loader {
|
contentItem: Loader {
|
||||||
height: 40 // by design
|
height: 40 // by design
|
||||||
|
@ -93,7 +109,6 @@ ColumnLayout {
|
||||||
color: Theme.palette.transparent
|
color: Theme.palette.transparent
|
||||||
}
|
}
|
||||||
onTokenSelected: root.tokenSelected(tokensKey)
|
onTokenSelected: root.tokenSelected(tokensKey)
|
||||||
Component.onCompleted: holdingSelector.selectToken(root.selectedTokenKey)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +126,7 @@ ColumnLayout {
|
||||||
Component {
|
Component {
|
||||||
id: selectedTokenCmp
|
id: selectedTokenCmp
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
objectName: "selectedTokenItem"
|
||||||
spacing: Style.current.halfPadding
|
spacing: Style.current.halfPadding
|
||||||
StatusRoundedImage {
|
StatusRoundedImage {
|
||||||
objectName: "tokenSelectorIcon"
|
objectName: "tokenSelectorIcon"
|
||||||
|
@ -119,14 +135,14 @@ ColumnLayout {
|
||||||
image.source: ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey, "iconSource")
|
image.source: ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey, "iconSource")
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
objectName: "tokenSelectorContentItemText"
|
objectName: "tokenSelectorContentItemName"
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
text: ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey, "name")
|
text: ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey, "name")
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
objectName: "tokenSelectorContentItemText"
|
objectName: "tokenSelectorContentItemSymbol"
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
text: ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey, "symbol")
|
text: ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey, "symbol")
|
||||||
|
|
|
@ -17,78 +17,161 @@ import utils 1.0
|
||||||
import AppLayouts.Wallet.controls 1.0
|
import AppLayouts.Wallet.controls 1.0
|
||||||
import AppLayouts.Wallet.adaptors 1.0
|
import AppLayouts.Wallet.adaptors 1.0
|
||||||
import AppLayouts.Wallet.panels 1.0
|
import AppLayouts.Wallet.panels 1.0
|
||||||
|
import AppLayouts.Wallet.stores 1.0
|
||||||
|
|
||||||
StatusStackModal {
|
StatusStackModal {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
// required data
|
||||||
|
required property var buyProvidersModel
|
||||||
|
required property var isBuyProvidersModelLoading
|
||||||
|
|
||||||
required property BuyCryptoParamsForm buyCryptoInputParamsForm
|
required property BuyCryptoParamsForm buyCryptoInputParamsForm
|
||||||
required property BuyCryptoModalAdaptor buyCryptoAdaptor
|
required property var plainTokensBySymbolModel
|
||||||
|
required property var groupedAccountAssetsModel
|
||||||
|
required property var walletAccountsModel
|
||||||
|
required property var networksModel
|
||||||
|
required property bool areTestNetworksEnabled
|
||||||
|
required property string currentCurrency
|
||||||
|
|
||||||
|
signal fetchProviders()
|
||||||
|
signal fetchProviderUrl(string uuid,
|
||||||
|
string providerID,
|
||||||
|
bool isRecurrent,
|
||||||
|
string selectedWalletAddress,
|
||||||
|
int chainID,
|
||||||
|
string symbol)
|
||||||
|
|
||||||
|
// FIXME handling error in case the response is not successful
|
||||||
|
function providerUrlReady(uuid, url) {
|
||||||
|
if(uuid === d.uuid) {
|
||||||
|
d.urlIsBeingFetched = false
|
||||||
|
if (!!d.selectedProviderEntry.item && !!url)
|
||||||
|
Global.openLinkWithConfirmation(url, d.selectedProviderEntry.item.hostname)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
|
// States to track requests
|
||||||
|
property string uuid
|
||||||
|
property bool urlIsBeingFetched
|
||||||
|
|
||||||
readonly property var buyButton: StatusButton {
|
readonly property var buyButton: StatusButton {
|
||||||
height: root.finishButton.height
|
height: root.finishButton.height
|
||||||
visible: !!root.replaceItem
|
visible: !!root.replaceItem
|
||||||
borderColor: "transparent"
|
borderColor: "transparent"
|
||||||
text: qsTr("Buy via %1").arg(!!root.buyCryptoAdaptor.selectedProvider ? root.buyCryptoAdaptor.selectedProvider.name: "")
|
text: qsTr("Buy via %1").arg(!!d.selectedProviderEntry.item ? d.selectedProviderEntry.item.name: "")
|
||||||
loading: root.buyCryptoAdaptor.urlIsBeingFetched
|
loading: d.urlIsBeingFetched
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if(!!root.buyCryptoAdaptor.selectedProvider && !!root.buyCryptoAdaptor.selectedToken) {
|
if(!!d.selectedProviderEntry.item && !!d.selectedTokenEntry.item) {
|
||||||
root.buyCryptoAdaptor.fetchProviderUrl(
|
d.fetchProviderUrl(
|
||||||
root.buyCryptoInputParamsForm.selectedProviderId,
|
root.buyCryptoInputParamsForm.selectedProviderId,
|
||||||
buyCryptoProvidersListPanel.currentTabIndex,
|
buyCryptoProvidersListPanel.currentTabIndex,
|
||||||
root.buyCryptoInputParamsForm.selectedWalletAddress,
|
root.buyCryptoInputParamsForm.selectedWalletAddress,
|
||||||
root.buyCryptoInputParamsForm.selectedNetworkChainId,
|
root.buyCryptoInputParamsForm.selectedNetworkChainId,
|
||||||
root.buyCryptoAdaptor.selectedToken.symbol
|
d.selectedTokenEntry.item.symbol
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enabled: root.buyCryptoInputParamsForm.filledCorrectly
|
enabled: root.buyCryptoInputParamsForm.filledCorrectly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property ModelEntry selectedAccountEntry: ModelEntry {
|
||||||
|
sourceModel: root.walletAccountsModel
|
||||||
|
key: "address"
|
||||||
|
value: root.buyCryptoInputParamsForm.selectedWalletAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property ModelEntry selectedTokenEntry: ModelEntry {
|
||||||
|
sourceModel: root.plainTokensBySymbolModel
|
||||||
|
key: "key"
|
||||||
|
value: root.buyCryptoInputParamsForm.selectedTokenKey
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property ModelEntry selectedProviderEntry: ModelEntry {
|
||||||
|
id: selectedProviderEntry
|
||||||
|
sourceModel: root.buyProvidersModel
|
||||||
|
key: "id"
|
||||||
|
value: root.buyCryptoInputParamsForm.selectedProviderId
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchProviderUrl(
|
||||||
|
providerID,
|
||||||
|
isRecurrent,
|
||||||
|
accountAddress = "",
|
||||||
|
chainID = 0,
|
||||||
|
symbol = "") {
|
||||||
|
// Identify new search with a different uuid
|
||||||
|
d.uuid = Utils.uuid()
|
||||||
|
d.urlIsBeingFetched = true
|
||||||
|
root.fetchProviderUrl(d.uuid, providerID, isRecurrent,
|
||||||
|
accountAddress, chainID, symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to filter items based on search string in the token selector
|
||||||
|
property string searchString
|
||||||
|
readonly property var tokenSelectorViewAdaptor: TokenSelectorViewAdaptor {
|
||||||
|
assetsModel: root.groupedAccountAssetsModel
|
||||||
|
plainTokensBySymbolModel: root.plainTokensBySymbolModel
|
||||||
|
flatNetworksModel: root.networksModel
|
||||||
|
currentCurrency: root.currentCurrency
|
||||||
|
|
||||||
|
showAllTokens: true
|
||||||
|
enabledChainIds: root.buyCryptoInputParamsForm.selectedNetworkChainId !== -1 ? [root.buyCryptoInputParamsForm.selectedNetworkChainId] : []
|
||||||
|
accountAddress: root.buyCryptoInputParamsForm.selectedWalletAddress
|
||||||
|
searchString: d.searchString
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var buyCryptoAdaptor: BuyCryptoModalAdaptor {
|
||||||
|
networksModel: root.networksModel
|
||||||
|
areTestNetworksEnabled: root.areTestNetworksEnabled
|
||||||
|
processedTokenSelectorAssetsModel: d.tokenSelectorViewAdaptor.outputAssetsModel
|
||||||
|
selectedProviderSupportedAssetsArray: {
|
||||||
|
if (!!d.selectedProviderEntry.item && !!d.selectedProviderEntry.item.supportedAssets)
|
||||||
|
return ModelUtils.modelToFlatArray(d.selectedProviderEntry.item.supportedAssets, "key")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
selectedChainId: root.buyCryptoInputParamsForm.selectedNetworkChainId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
width: 560
|
width: 560
|
||||||
height: 515
|
height: 515
|
||||||
padding: Style.current.xlPadding
|
padding: Style.current.xlPadding
|
||||||
stackTitle: qsTr("Buy assets for %1").arg(!!buyCryptoAdaptor.selectedAccount ? buyCryptoAdaptor.selectedAccount.name: "")
|
stackTitle: qsTr("Buy assets for %1").arg(!!d.selectedAccountEntry.item ? d.selectedAccountEntry.item.name: "")
|
||||||
rightButtons: [d.buyButton, finishButton]
|
rightButtons: [d.buyButton, finishButton]
|
||||||
finishButton: StatusButton {
|
finishButton: StatusButton {
|
||||||
text: qsTr("Done")
|
text: qsTr("Done")
|
||||||
onClicked: root.close()
|
onClicked: root.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
onOpened: root.fetchProviders()
|
||||||
target: root.buyCryptoAdaptor
|
|
||||||
function onProviderUrlReady(url) {
|
|
||||||
if (!!root.buyCryptoAdaptor.selectedProvider && !!url)
|
|
||||||
Global.openLinkWithConfirmation(url, root.buyCryptoAdaptor.selectedProvider.hostname)
|
|
||||||
root.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpened: root.buyCryptoAdaptor.fetchProviders()
|
|
||||||
onClosed: {
|
onClosed: {
|
||||||
// reset the view
|
// reset the view
|
||||||
|
d.uuid = ""
|
||||||
|
d.urlIsBeingFetched = false
|
||||||
root.replaceItem = undefined
|
root.replaceItem = undefined
|
||||||
buyCryptoProvidersListPanel.currentTabIndex = 0
|
buyCryptoProvidersListPanel.currentTabIndex = 0
|
||||||
root.buyCryptoAdaptor.reset()
|
|
||||||
root.buyCryptoInputParamsForm.resetFormData()
|
root.buyCryptoInputParamsForm.resetFormData()
|
||||||
}
|
}
|
||||||
|
|
||||||
stackItems: [
|
stackItems: [
|
||||||
BuyCryptoProvidersListPanel {
|
BuyCryptoProvidersListPanel {
|
||||||
id: buyCryptoProvidersListPanel
|
id: buyCryptoProvidersListPanel
|
||||||
providersLoading: root.buyCryptoAdaptor.providersLoading
|
providersLoading: root.isBuyProvidersModelLoading
|
||||||
providersModel: root.buyCryptoAdaptor.providersModel
|
providersModel: root.buyProvidersModel
|
||||||
selectedProviderId: root.buyCryptoInputParamsForm.selectedProviderId
|
selectedProviderId: root.buyCryptoInputParamsForm.selectedProviderId
|
||||||
isUrlBeingFetched: root.buyCryptoAdaptor.urlIsBeingFetched
|
isUrlBeingFetched: d.urlIsBeingFetched
|
||||||
onProviderSelected: {
|
onProviderSelected: {
|
||||||
root.buyCryptoInputParamsForm.selectedProviderId = id
|
root.buyCryptoInputParamsForm.selectedProviderId = id
|
||||||
if(!!root.buyCryptoAdaptor.selectedProvider) {
|
if(!!d.selectedProviderEntry.item) {
|
||||||
if(root.buyCryptoAdaptor.selectedProvider.urlsNeedParameters) {
|
if(d.selectedProviderEntry.item.urlsNeedParameters) {
|
||||||
root.replace(selectParamsPanel)
|
root.replace(selectParamsPanel)
|
||||||
} else {
|
} else {
|
||||||
root.buyCryptoAdaptor.fetchProviderUrl(root.buyCryptoAdaptor.selectedProvider.id, currentTabIndex)
|
d.fetchProviderUrl(d.selectedProviderEntry.item.id, currentTabIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,36 +181,12 @@ StatusStackModal {
|
||||||
Component {
|
Component {
|
||||||
id: selectParamsPanel
|
id: selectParamsPanel
|
||||||
SelectParamsForBuyCryptoPanel {
|
SelectParamsForBuyCryptoPanel {
|
||||||
id: selectParamsPanelInst
|
objectName: "selectParamsPanel"
|
||||||
adaptor: TokenSelectorViewAdaptor {
|
assetsModel: d.buyCryptoAdaptor.filteredAssetsModel
|
||||||
/* TODO these should be hadbled and perhaps improved under
|
selectedProvider: d.selectedProviderEntry.item
|
||||||
https://github.com/status-im/status-desktop/issues/16025 */
|
|
||||||
assetsModel: SortFilterProxyModel {
|
|
||||||
sourceModel: root.buyCryptoAdaptor.groupedAccountAssetsModelWithKey
|
|
||||||
filters: FastExpressionFilter {
|
|
||||||
expression: model.addressPerChain.rowCount() > 0
|
|
||||||
expectedRoles: ["addressPerChain"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plainTokensBySymbolModel: SortFilterProxyModel {
|
|
||||||
sourceModel: root.buyCryptoAdaptor.plainTokensBySymbolModelWithKey
|
|
||||||
filters: FastExpressionFilter {
|
|
||||||
expression: model.addressPerChain.rowCount() > 0
|
|
||||||
expectedRoles: ["addressPerChain"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flatNetworksModel: root.buyCryptoAdaptor.networksModel
|
|
||||||
currentCurrency: root.buyCryptoAdaptor.currentCurrency
|
|
||||||
|
|
||||||
showAllTokens: true
|
|
||||||
enabledChainIds: root.buyCryptoInputParamsForm.selectedNetworkChainId !== -1 ? [root.buyCryptoInputParamsForm.selectedNetworkChainId] : []
|
|
||||||
accountAddress: root.buyCryptoInputParamsForm.selectedWalletAddress
|
|
||||||
searchString: selectParamsPanelInst.searchString
|
|
||||||
}
|
|
||||||
selectedProvider: root.buyCryptoAdaptor.selectedProvider
|
|
||||||
selectedTokenKey: root.buyCryptoInputParamsForm.selectedTokenKey
|
selectedTokenKey: root.buyCryptoInputParamsForm.selectedTokenKey
|
||||||
selectedNetworkChainId: root.buyCryptoInputParamsForm.selectedNetworkChainId
|
selectedNetworkChainId: root.buyCryptoInputParamsForm.selectedNetworkChainId
|
||||||
filteredFlatNetworksModel: root.buyCryptoAdaptor.filteredFlatNetworksModel
|
filteredFlatNetworksModel: d.buyCryptoAdaptor.filteredFlatNetworksModel
|
||||||
onNetworkSelected: {
|
onNetworkSelected: {
|
||||||
if (root.buyCryptoInputParamsForm.selectedNetworkChainId !== chainId) {
|
if (root.buyCryptoInputParamsForm.selectedNetworkChainId !== chainId) {
|
||||||
root.buyCryptoInputParamsForm.selectedNetworkChainId = chainId
|
root.buyCryptoInputParamsForm.selectedNetworkChainId = chainId
|
||||||
|
@ -138,6 +197,11 @@ StatusStackModal {
|
||||||
root.buyCryptoInputParamsForm.selectedTokenKey = tokensKey
|
root.buyCryptoInputParamsForm.selectedTokenKey = tokensKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binding {
|
||||||
|
target: d
|
||||||
|
property: "searchString"
|
||||||
|
value: searchString
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,143 +4,37 @@ import SortFilterProxyModel 0.2
|
||||||
import StatusQ 0.1
|
import StatusQ 0.1
|
||||||
import StatusQ.Core.Utils 0.1
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import shared.stores 1.0
|
|
||||||
import AppLayouts.Wallet 1.0
|
|
||||||
import AppLayouts.Wallet.stores 1.0 as WalletStore
|
|
||||||
|
|
||||||
QObject {
|
QObject {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property WalletStore.BuyCryptoStore buyCryptoStore
|
|
||||||
required property BuyCryptoParamsForm buyCryptoFormData
|
|
||||||
required property var walletAccountsModel
|
|
||||||
required property var networksModel
|
required property var networksModel
|
||||||
required property bool areTestNetworksEnabled
|
required property bool areTestNetworksEnabled
|
||||||
required property var groupedAccountAssetsModel
|
required property var processedTokenSelectorAssetsModel
|
||||||
required property var plainTokensBySymbolModel
|
required property var selectedProviderSupportedAssetsArray
|
||||||
required property string currentCurrency
|
required property int selectedChainId
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
property string uuid
|
|
||||||
property bool urlIsBeingFetched
|
|
||||||
readonly property var selectedProviderSupportedArray: !!selectedProvider && !!selectedProvider.supportedAssets ? ModelUtils.modelToFlatArray(selectedProvider.supportedAssets, "key"): null
|
|
||||||
}
|
|
||||||
|
|
||||||
signal providerUrlReady(string url)
|
|
||||||
|
|
||||||
readonly property bool providersLoading: root.buyCryptoStore.areProvidersLoading
|
|
||||||
readonly property var providersModel: root.buyCryptoStore.providersModel
|
|
||||||
|
|
||||||
readonly property bool urlIsBeingFetched: d.urlIsBeingFetched
|
|
||||||
|
|
||||||
readonly property var selectedAccount: selectedAccountEntry.item
|
|
||||||
readonly property var selectedToken: selectedTokenEntry.item
|
|
||||||
readonly property var selectedProvider: selectedProviderEntry.item
|
|
||||||
|
|
||||||
readonly property SortFilterProxyModel filteredFlatNetworksModel: SortFilterProxyModel {
|
readonly property SortFilterProxyModel filteredFlatNetworksModel: SortFilterProxyModel {
|
||||||
sourceModel: root.networksModel
|
sourceModel: root.networksModel
|
||||||
filters: ValueFilter { roleName: "isTest"; value: root.areTestNetworksEnabled }
|
filters: ValueFilter { roleName: "isTest"; value: root.areTestNetworksEnabled }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO evaluate if this is still needed after
|
// this proxy removes tokens not supported by selected on-ramp provider
|
||||||
https://github.com/status-im/status-desktop/issues/16025 */
|
readonly property SortFilterProxyModel filteredAssetsModel: SortFilterProxyModel {
|
||||||
readonly property ObjectProxyModel plainTokensBySymbolModelWithKey: ObjectProxyModel {
|
sourceModel: root.processedTokenSelectorAssetsModel.count ? root.processedTokenSelectorAssetsModel: null
|
||||||
sourceModel: root.plainTokensBySymbolModel
|
|
||||||
delegate: SortFilterProxyModel {
|
|
||||||
id: delegateRoot
|
|
||||||
readonly property var addressPerChain: this
|
|
||||||
sourceModel: model.addressPerChain
|
|
||||||
proxyRoles: JoinRole {
|
|
||||||
name: "key"
|
|
||||||
roleNames: ["chainId", "address"]
|
|
||||||
separator: ""
|
|
||||||
}
|
|
||||||
filters: FastExpressionFilter {
|
filters: FastExpressionFilter {
|
||||||
expression: !!d.selectedProviderSupportedArray ? d.selectedProviderSupportedArray.includes(model.key) : true
|
function isSupportedByProvider(addressPerChain) {
|
||||||
expectedRoles: ["key"]
|
if(!addressPerChain)
|
||||||
|
return true
|
||||||
|
return !!ModelUtils.getFirstModelEntryIf(
|
||||||
|
addressPerChain,
|
||||||
|
(addPerChain) => {
|
||||||
|
return root.selectedChainId === addPerChain.chainId &&
|
||||||
|
root.selectedProviderSupportedAssetsArray.includes(addPerChain.chainId+addPerChain.address)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
expression: isSupportedByProvider(model.addressPerChain)
|
||||||
|
|
||||||
exposedRoles: ["addressPerChain"]
|
|
||||||
expectedRoles: ["addressPerChain"]
|
expectedRoles: ["addressPerChain"]
|
||||||
}
|
enabled: !!root.selectedProviderSupportedAssetsArray && root.selectedProviderSupportedAssetsArray.length > 0 && root.selectedChainId !== -1
|
||||||
|
|
||||||
/* TODO evaluate if this is still needed after
|
|
||||||
https://github.com/status-im/status-desktop/issues/16025 */
|
|
||||||
readonly property ObjectProxyModel groupedAccountAssetsModelWithKey: ObjectProxyModel {
|
|
||||||
sourceModel: root.groupedAccountAssetsModel
|
|
||||||
delegate: SortFilterProxyModel {
|
|
||||||
id: delegateRoot1
|
|
||||||
readonly property var addressPerChain: this
|
|
||||||
sourceModel: model.addressPerChain
|
|
||||||
proxyRoles: JoinRole {
|
|
||||||
name: "key"
|
|
||||||
roleNames: ["chainId", "address"]
|
|
||||||
separator: ""
|
|
||||||
}
|
|
||||||
filters: FastExpressionFilter {
|
|
||||||
expression: !!d.selectedProviderSupportedArray ? d.selectedProviderSupportedArray.includes(model.key) : true
|
|
||||||
expectedRoles: ["key"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exposedRoles: ["addressPerChain"]
|
|
||||||
expectedRoles: ["addressPerChain"]
|
|
||||||
}
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
d.uuid = ""
|
|
||||||
d.urlIsBeingFetched = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchProviders() {
|
|
||||||
root.buyCryptoStore.fetchProviders()
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchProviderUrl(
|
|
||||||
providerID,
|
|
||||||
isRecurrent,
|
|
||||||
accountAddress = "",
|
|
||||||
chainID = 0,
|
|
||||||
symbol = "") {
|
|
||||||
// Identify new search with a different uuid
|
|
||||||
d.uuid = Utils.uuid()
|
|
||||||
d.urlIsBeingFetched = true
|
|
||||||
buyCryptoStore.fetchProviderUrl(d.uuid, providerID, isRecurrent,
|
|
||||||
accountAddress, chainID,symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.buyCryptoStore
|
|
||||||
function onProviderUrlReady(uuid, url) {
|
|
||||||
if(uuid === d.uuid) {
|
|
||||||
d.urlIsBeingFetched = false
|
|
||||||
root.providerUrlReady(url)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelEntry {
|
|
||||||
id: selectedAccountEntry
|
|
||||||
sourceModel: root.walletAccountsModel
|
|
||||||
key: "address"
|
|
||||||
value: root.buyCryptoFormData.selectedWalletAddress
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelEntry {
|
|
||||||
id: selectedTokenEntry
|
|
||||||
sourceModel: root.plainTokensBySymbolModel
|
|
||||||
key: "key"
|
|
||||||
value: root.buyCryptoFormData.selectedTokenKey
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelEntry {
|
|
||||||
id: selectedProviderEntry
|
|
||||||
sourceModel: root.providersModel
|
|
||||||
key: "id"
|
|
||||||
value: root.buyCryptoFormData.selectedProviderId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ Item {
|
||||||
tokensStore: appMain.tokensStore
|
tokensStore: appMain.tokensStore
|
||||||
currencyStore: appMain.currencyStore
|
currencyStore: appMain.currencyStore
|
||||||
}
|
}
|
||||||
|
readonly property WalletStores.BuyCryptoStore buyCryptoStore: WalletStores.BuyCryptoStore {}
|
||||||
|
|
||||||
readonly property FeatureFlagsStore featureFlagsStore: FeatureFlagsStore {
|
readonly property FeatureFlagsStore featureFlagsStore: FeatureFlagsStore {
|
||||||
readonly property var featureFlags: typeof featureFlagsRootContextProperty !== undefined ? featureFlagsRootContextProperty : null
|
readonly property var featureFlags: typeof featureFlagsRootContextProperty !== undefined ? featureFlagsRootContextProperty : null
|
||||||
|
|
||||||
|
@ -402,6 +404,7 @@ Item {
|
||||||
currencyStore: appMain.currencyStore
|
currencyStore: appMain.currencyStore
|
||||||
walletAssetsStore: appMain.walletAssetsStore
|
walletAssetsStore: appMain.walletAssetsStore
|
||||||
walletCollectiblesStore: appMain.walletCollectiblesStore
|
walletCollectiblesStore: appMain.walletCollectiblesStore
|
||||||
|
buyCryptoStore: appMain.buyCryptoStore
|
||||||
networkConnectionStore: appMain.networkConnectionStore
|
networkConnectionStore: appMain.networkConnectionStore
|
||||||
isDevBuild: !production
|
isDevBuild: !production
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ QtObject {
|
||||||
property WalletStore.WalletAssetsStore walletAssetsStore
|
property WalletStore.WalletAssetsStore walletAssetsStore
|
||||||
property WalletStore.CollectiblesStore walletCollectiblesStore
|
property WalletStore.CollectiblesStore walletCollectiblesStore
|
||||||
property NetworkConnectionStore networkConnectionStore
|
property NetworkConnectionStore networkConnectionStore
|
||||||
|
property WalletStore.BuyCryptoStore buyCryptoStore
|
||||||
property bool isDevBuild
|
property bool isDevBuild
|
||||||
|
|
||||||
signal openExternalLink(string link)
|
signal openExternalLink(string link)
|
||||||
|
@ -1249,15 +1250,18 @@ QtObject {
|
||||||
Component {
|
Component {
|
||||||
id: buyCryptoModal
|
id: buyCryptoModal
|
||||||
BuyCryptoModal {
|
BuyCryptoModal {
|
||||||
buyCryptoAdaptor: BuyCryptoModalAdaptor {
|
buyProvidersModel: root.buyCryptoStore.providersModel
|
||||||
buyCryptoStore: WalletStore.BuyCryptoStore {}
|
isBuyProvidersModelLoading: root.buyCryptoStore.areProvidersLoading
|
||||||
buyCryptoFormData: buyCryptoInputParamsForm
|
currentCurrency: root.currencyStore.currentCurrency
|
||||||
walletAccountsModel: root.rootStore.accounts
|
walletAccountsModel: root.rootStore.accounts
|
||||||
|
plainTokensBySymbolModel: root.walletAssetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
groupedAccountAssetsModel: root.walletAssetsStore.groupedAccountAssetsModel
|
||||||
networksModel: root.rootStore.profileSectionStore.walletStore.flatNetworks
|
networksModel: root.rootStore.profileSectionStore.walletStore.flatNetworks
|
||||||
areTestNetworksEnabled: root.rootStore.profileSectionStore.walletStore.areTestNetworksEnabled
|
areTestNetworksEnabled: root.rootStore.profileSectionStore.walletStore.areTestNetworksEnabled
|
||||||
groupedAccountAssetsModel: root.walletAssetsStore.groupedAccountAssetsModel
|
Component.onCompleted: {
|
||||||
plainTokensBySymbolModel: root.walletAssetsStore.walletTokensStore.plainTokensBySymbolModel
|
fetchProviders.connect(root.buyCryptoStore.fetchProviders)
|
||||||
currentCurrency: root.currencyStore.currentCurrency
|
fetchProviderUrl.connect(root.buyCryptoStore.fetchProviderUrl)
|
||||||
|
root.buyCryptoStore.providerUrlReady.connect(providerUrlReady)
|
||||||
}
|
}
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue