fix(Send): Fine tune the Send action on collectibles

1. Show Send Button on wallet footer when all accounts is selected
2. Hide Send Button in collectibles context menu and collectibles details view when the collectible is not owned by the user
3. Disable the Send Button in collectibles context menu and collectibles details view when the collectible is soulbound

to squash: Fine tune send action on collectibles

to squash: Fine tune send on collectibles

to squash: Fine-tune collectibles
This commit is contained in:
Alex Jbanca 2024-07-17 17:55:52 +03:00 committed by Alex Jbanca
parent 7926d1f748
commit b36e2759af
5 changed files with 103 additions and 27 deletions

View File

@ -112,6 +112,7 @@ SplitView {
qsTr("%1 community collectibles are now visible").arg(communityName), "", "checkmark-circle", qsTr("%1 community collectibles are now visible").arg(communityName), "", "checkmark-circle",
false, Constants.ephemeralNotificationType.success, "") false, Constants.ephemeralNotificationType.success, "")
} }
ownedAccountsModel: WalletAccountsModel {}
networkFilters: d.networksChainsCurrentlySelected networkFilters: d.networksChainsCurrentlySelected
addressFilters: d.addressesSelected addressFilters: d.addressesSelected
filterVisible: ctrlFilterVisible.checked filterVisible: ctrlFilterVisible.checked

View File

@ -304,7 +304,7 @@ Item {
const ownership = StatusQUtils.ModelUtils.get(tokenItem.ownership, 0) const ownership = StatusQUtils.ModelUtils.get(tokenItem.ownership, 0)
Global.openTransferOwnershipPopup(tokenItem.communityId, Global.openTransferOwnershipPopup(tokenItem.communityId,
tokenItem.communityName, footer.communityName,
tokenItem.communityImage, tokenItem.communityImage,
{ {
"key": tokenItem.tokenId, "key": tokenItem.tokenId,
@ -316,14 +316,20 @@ Item {
"tokenAddress": tokenItem.contractAddress "tokenAddress": tokenItem.contractAddress
}, },
root.sendModalPopup) root.sendModalPopup)
} else { return
// Common send modal popup:
root.sendModalPopup.preSelectedSendType = Constants.SendType.Transfer
root.sendModalPopup.preSelectedHoldingID = walletStore.currentViewedHoldingID
root.sendModalPopup.preSelectedHoldingType = walletStore.currentViewedHoldingType
root.sendModalPopup.onlyAssets = false
root.sendModalPopup.open()
} }
if (isHoldingSelected) {
const tokenItem = walletStore.currentViewedCollectible
const ownership = StatusQUtils.ModelUtils.get(tokenItem.ownership, 0)
root.sendModalPopup.preSelectedAccountAddress = ownership.accountAddress
}
// Common send modal popup:
root.sendModalPopup.preSelectedSendType = Constants.SendType.Transfer
root.sendModalPopup.preSelectedHoldingID = walletStore.currentViewedHoldingID
root.sendModalPopup.preSelectedHoldingType = walletStore.currentViewedHoldingType
root.sendModalPopup.onlyAssets = false
root.sendModalPopup.open()
} }
onLaunchBridgeModal: { onLaunchBridgeModal: {
root.sendModalPopup.preSelectedSendType = Constants.SendType.Bridge root.sendModalPopup.preSelectedSendType = Constants.SendType.Bridge

View File

@ -2,9 +2,11 @@ import QtQuick 2.14
import QtQuick.Controls 2.14 import QtQuick.Controls 2.14
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import StatusQ 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as SQUtils
import utils 1.0 import utils 1.0
import shared.controls 1.0 import shared.controls 1.0
@ -37,6 +39,22 @@ Rectangle {
(walletStore.currentViewedHoldingType === Constants.TokenType.ERC721 || (walletStore.currentViewedHoldingType === Constants.TokenType.ERC721 ||
walletStore.currentViewedHoldingType === Constants.TokenType.ERC1155) walletStore.currentViewedHoldingType === Constants.TokenType.ERC1155)
readonly property bool isCollectibleSoulbound: isCollectibleViewed && !!walletStore.currentViewedCollectible && walletStore.currentViewedCollectible.soulbound readonly property bool isCollectibleSoulbound: isCollectibleViewed && !!walletStore.currentViewedCollectible && walletStore.currentViewedCollectible.soulbound
readonly property bool isCollectibleOwned: d.owningAccount.available
readonly property bool hideCollectibleTransferActions: isCollectibleViewed && !isCollectibleOwned
property string collectibleOwnerAddress
Binding on collectibleOwnerAddress {
when: d.isCollectibleViewed && !!root.walletStore.currentViewedCollectible && !!root.walletStore.currentViewedCollectible.ownership.ModelCount.count
value: SQUtils.ModelUtils.get(root.walletStore.currentViewedCollectible.ownership, 0).accountAddress
}
readonly property ModelEntry owningAccount: ModelEntry {
sourceModel: d.isCollectibleViewed ? root.walletStore.nonWatchAccounts : null
key: "address"
value: d.collectibleOwnerAddress ?? ""
}
} }
StatusModalDivider { StatusModalDivider {
@ -55,11 +73,14 @@ Rectangle {
text: root.isCommunityOwnershipTransfer ? qsTr("Send Owner token to transfer %1 Community ownership").arg(root.communityName) : qsTr("Send") text: root.isCommunityOwnershipTransfer ? qsTr("Send Owner token to transfer %1 Community ownership").arg(root.communityName) : qsTr("Send")
interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled
onClicked: { onClicked: {
root.transactionStore.setSenderAccount(root.walletStore.selectedAddress) if (!!root.walletStore.selectedAddress)
root.transactionStore.setSenderAccount(root.walletStore.selectedAddress)
root.launchSendModal() root.launchSendModal()
} }
tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be sent to another wallet") : networkConnectionStore.sendBuyBridgeToolTipText tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be sent to another wallet") : networkConnectionStore.sendBuyBridgeToolTipText
visible: !walletStore.overview.isWatchOnlyAccount && walletStore.overview.canSend && !root.walletStore.showAllAccounts visible: !walletStore.overview.isWatchOnlyAccount
&& walletStore.overview.canSend
&& !d.hideCollectibleTransferActions
} }
StatusFlatButton { StatusFlatButton {
@ -78,7 +99,11 @@ Rectangle {
interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled
onClicked: root.launchBridgeModal() onClicked: root.launchBridgeModal()
tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be bridged to another wallet") : networkConnectionStore.sendBuyBridgeToolTipText tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be bridged to another wallet") : networkConnectionStore.sendBuyBridgeToolTipText
visible: !walletStore.overview.isWatchOnlyAccount && !root.isCommunityOwnershipTransfer && walletStore.overview.canSend && !root.walletStore.showAllAccounts visible: !walletStore.overview.isWatchOnlyAccount
&& !root.isCommunityOwnershipTransfer
&& walletStore.overview.canSend
&& !root.walletStore.showAllAccounts
&& !d.hideCollectibleTransferActions
} }
StatusFlatButton { StatusFlatButton {
@ -94,7 +119,7 @@ Rectangle {
id: swap id: swap
interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled
visible: Global.featureFlags.swapEnabled && !walletStore.overview.isWatchOnlyAccount visible: Global.featureFlags.swapEnabled && !walletStore.overview.isWatchOnlyAccount && !d.hideCollectibleTransferActions
tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be swapped") : networkConnectionStore.sendBuyBridgeToolTipText tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be swapped") : networkConnectionStore.sendBuyBridgeToolTipText
icon.name: "swap" icon.name: "swap"
text: qsTr("Swap") text: qsTr("Swap")

View File

@ -28,6 +28,7 @@ import SortFilterProxyModel 0.2
ColumnLayout { ColumnLayout {
id: root id: root
required property var ownedAccountsModel
required property var controller required property var controller
required property string addressFilters required property string addressFilters
required property string networkFilters required property string networkFilters
@ -466,10 +467,17 @@ ColumnLayout {
onClicked: root.collectibleClicked(model.chainId, model.contractAddress, model.tokenId, model.symbol, model.tokenType) onClicked: root.collectibleClicked(model.chainId, model.contractAddress, model.tokenId, model.symbol, model.tokenType)
onRightClicked: { onRightClicked: {
let ownedByUser = false
const ownedByAccount = ModelUtils.get(model.ownership, 0)
if (!!ownedByAccount && !!ownedByAccount.accountAddress) {
ownedByUser = ModelUtils.contains(root.ownedAccountsModel, "address", ownedByAccount.accountAddress, Qt.CaseInsensitive)
}
Global.openMenu(tokenContextMenu, this, Global.openMenu(tokenContextMenu, this,
{symbol: model.symbol, tokenName: model.name, tokenImage: model.imageUrl, {symbol: model.symbol, tokenName: model.name, tokenImage: model.imageUrl,
communityId: model.communityId, communityName: model.communityName, communityId: model.communityId, communityName: model.communityName,
communityImage: model.communityImage, tokenType: model.tokenType}) communityImage: model.communityImage, tokenType: model.tokenType,
soulbound: model.soulbound, ownedByUser: ownedByUser})
} }
onSwitchToCommunityRequested: (communityId) => root.switchToCommunityRequested(communityId) onSwitchToCommunityRequested: (communityId) => root.switchToCommunityRequested(communityId)
} }
@ -478,6 +486,7 @@ ColumnLayout {
Component { Component {
id: tokenContextMenu id: tokenContextMenu
StatusMenu { StatusMenu {
id: tokenMenu
onClosed: destroy() onClosed: destroy()
property string symbol property string symbol
@ -487,14 +496,24 @@ ColumnLayout {
property string communityName property string communityName
property string communityImage property string communityImage
property int tokenType property int tokenType
property bool ownedByUser
property bool soulbound
StatusAction { // Show send button for owned collectibles
enabled: root.sendEnabled // Disable send button for owned soulbound collectibles
visibleOnDisabled: true Instantiator {
icon.name: "send" model: tokenMenu.ownedByUser ? 1 : 0
text: qsTr("Send") delegate: StatusAction {
onTriggered: root.sendRequested(symbol, tokenType) enabled: root.sendEnabled && !tokenMenu.soulbound
visibleOnDisabled: true
icon.name: "send"
text: qsTr("Send")
onTriggered: root.sendRequested(symbol, tokenType)
}
onObjectAdded: tokenMenu.insertAction(0, object)
onObjectRemoved: tokenMenu.removeAction(0)
} }
StatusAction { StatusAction {
icon.name: "receive" icon.name: "receive"
text: qsTr("Receive") text: qsTr("Receive")

View File

@ -248,6 +248,7 @@ RightTabBaseView {
Component { Component {
id: collectiblesView id: collectiblesView
CollectiblesView { CollectiblesView {
ownedAccountsModel: RootStore.nonWatchAccounts
controller: RootStore.collectiblesStore.collectiblesController controller: RootStore.collectiblesStore.collectiblesController
networkFilters: RootStore.networkFilters networkFilters: RootStore.networkFilters
addressFilters: RootStore.addressFilters addressFilters: RootStore.addressFilters
@ -265,14 +266,38 @@ RightTabBaseView {
stack.currentIndex = 1 stack.currentIndex = 1
} }
onSendRequested: (symbol, tokenType) => { onSendRequested: (symbol, tokenType) => {
root.sendModal.preSelectedHoldingID = symbol const collectible = ModelUtils.getByKey(controller.sourceModel, "symbol", symbol)
root.sendModal.preSelectedHoldingType = tokenType if (collectible.communityPrivilegesLevel === Constants.TokenPrivilegesLevel.Owner) {
root.sendModal.preSelectedSendType = tokenType === Constants.TokenType.ERC721 ? const ownerAccountItem = ModelUtils.get(collectible.ownership, 0)
Constants.SendType.ERC721Transfer: Global.openTransferOwnershipPopup(collectible.communityId,
Constants.SendType.ERC1155Transfer collectible.communityName,
root.sendModal.onlyAssets = false collectible.communityImage,
root.sendModal.open() {
} "key": collectible.tokenId,
"privilegesLevel": collectible.communityPrivilegesLevel,
"chainId": collectible.chainId,
"name": collectible.name,
"artworkSource": collectible.communityImage,
"accountAddress": ownerAccountItem.accountAddress,
"tokenAddress": collectible.contractAddress
},
root.sendModal)
return
}
if (!!collectible) {
const ownerAccountItem = ModelUtils.get(collectible.ownership, 0)
root.sendModal.preSelectedAccountAddress = ownerAccountItem.accountAddress
}
root.sendModal.preSelectedHoldingID = symbol
root.sendModal.preSelectedHoldingType = tokenType
root.sendModal.preSelectedSendType = tokenType === Constants.TokenType.ERC721 ?
Constants.SendType.ERC721Transfer:
Constants.SendType.ERC1155Transfer
root.sendModal.onlyAssets = false
root.sendModal.open()
}
onReceiveRequested: (symbol) => root.launchShareAddressModal() onReceiveRequested: (symbol) => root.launchShareAddressModal()
onSwitchToCommunityRequested: (communityId) => Global.switchToCommunity(communityId) onSwitchToCommunityRequested: (communityId) => Global.switchToCommunity(communityId)
onManageTokensRequested: Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.wallet, onManageTokensRequested: Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.wallet,