diff --git a/src/app/modules/main/communities/tokens/controller.nim b/src/app/modules/main/communities/tokens/controller.nim index de48791472..9bda7d781a 100644 --- a/src/app/modules/main/communities/tokens/controller.nim +++ b/src/app/modules/main/communities/tokens/controller.nim @@ -88,7 +88,7 @@ proc init*(self: Controller) = self.communityTokensModule.onOwnerTokenReceived(args.communityId, args.communityName, args.chainId, args.contractAddress) self.events.on(SIGNAL_COMMUNITY_TOKEN_RECEIVED) do(e: Args): let args = CommunityTokenReceivedArgs(e) - self.communityTokensModule.onCommunityTokenReceived(args.name, args.symbol, args.image, args.communityId, args.communityName, $args.amount, args.chainId, args.txHash, args.isFirst, args.tokenType, args.accountName) + self.communityTokensModule.onCommunityTokenReceived(args.name, args.symbol, args.image, args.communityId, args.communityName, $args.amount, args.chainId, args.txHash, args.isFirst, args.tokenType, args.accountName, args.accountAddress) self.events.on(SIGNAL_SET_SIGNER_STATUS) do(e: Args): let args = SetSignerArgs(e) self.communityTokensModule.onSetSignerStateChanged(args.communityId, args.chainId, args.transactionHash, args.status) diff --git a/src/app/modules/main/communities/tokens/io_interface.nim b/src/app/modules/main/communities/tokens/io_interface.nim index 9e958b14b6..770bdb9050 100644 --- a/src/app/modules/main/communities/tokens/io_interface.nim +++ b/src/app/modules/main/communities/tokens/io_interface.nim @@ -96,7 +96,7 @@ method removeCommunityToken*(self: AccessInterface, communityId: string, chainId method onOwnerTokenReceived*(self: AccessInterface, communityId: string, communityName: string, chainId: int, contractAddress: string) {.base.} = raise newException(ValueError, "No implementation available") -method onCommunityTokenReceived*(self: AccessInterface, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string) {.base.} = +method onCommunityTokenReceived*(self: AccessInterface, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) {.base.} = raise newException(ValueError, "No implementation available") method onSendOwnerTokenStateChanged*(self: AccessInterface, chainId: int, transactionHash: string, tokenName: string, status: ContractTransactionStatus) {.base.} = diff --git a/src/app/modules/main/communities/tokens/module.nim b/src/app/modules/main/communities/tokens/module.nim index a39023c8a1..fc89e12aee 100644 --- a/src/app/modules/main/communities/tokens/module.nim +++ b/src/app/modules/main/communities/tokens/module.nim @@ -334,8 +334,8 @@ method onAirdropStateChanged*(self: Module, communityId: string, tokenName: stri method onOwnerTokenReceived*(self: Module, communityId: string, communityName: string, chainId: int, contractAddress: string) = self.view.emitOwnerTokenReceived(communityId, communityName, chainId, contractAddress) -method onCommunityTokenReceived*(self: Module, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string) = - self.view.emitCommunityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, accountName) +method onCommunityTokenReceived*(self: Module, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) = + self.view.emitCommunityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, accountName, accountAddress) method onSetSignerStateChanged*(self: Module, communityId: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) = let communityDto = self.controller.getCommunityById(communityId) diff --git a/src/app/modules/main/communities/tokens/view.nim b/src/app/modules/main/communities/tokens/view.nim index c373300b67..ad39ebf18f 100644 --- a/src/app/modules/main/communities/tokens/view.nim +++ b/src/app/modules/main/communities/tokens/view.nim @@ -55,7 +55,7 @@ QtObject: proc burnFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int, responseId: string) {.signal.} proc setSignerFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int, responseId: string) {.signal.} proc ownerTokenReceived*(self: View, communityId: string, communityName: string, chainId: int, contractAddress: string) {.signal.} - proc communityTokenReceived*(self: View, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string) {.signal.} + proc communityTokenReceived*(self: View, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) {.signal.} proc setSignerStateChanged*(self: View, communityId: string, communityName: string, status: int, url: string) {.signal.} proc ownershipNodeLost*(self: View, communityId: string, communityName: string) {.signal.} proc sendOwnerTokenStateChanged*(self: View, tokenName: string, status: int, url: string) {.signal.} @@ -117,8 +117,8 @@ QtObject: proc emitOwnerTokenReceived*(self: View, communityId: string, communityName: string, chainId: int, contractAddress: string) = self.ownerTokenReceived(communityId, communityName, chainId, contractAddress) - proc emitCommunityTokenReceived*(self: View, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string) = - self.communityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, accountName) + proc emitCommunityTokenReceived*(self: View, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) = + self.communityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, accountName, accountAddress) proc emitSetSignerStateChanged*(self: View, communityId: string, communityName: string, status: int, url: string) = self.setSignerStateChanged(communityId, communityName, status, url) diff --git a/src/app/modules/main/wallet_section/activity/model.nim b/src/app/modules/main/wallet_section/activity/model.nim index 41b2076117..ee2a912f84 100644 --- a/src/app/modules/main/wallet_section/activity/model.nim +++ b/src/app/modules/main/wallet_section/activity/model.nim @@ -128,6 +128,12 @@ QtObject: read = getHasMore notify = hasMoreChanged + proc getIndex*(self: Model, txHash: string): int {.slot.} = + for i, e in self.entries: + if e.getId() == txHash: + return i + return -1 + proc refreshItemsContainingAddress*(self: Model, address: string) = for i in 0..self.entries.high: if cmpIgnoreCase(self.entries[i].getSender(), address) == 0 or diff --git a/ui/app/AppLayouts/Wallet/WalletLayout.qml b/ui/app/AppLayouts/Wallet/WalletLayout.qml index 54a947d39c..16ba4a3cb8 100644 --- a/ui/app/AppLayouts/Wallet/WalletLayout.qml +++ b/ui/app/AppLayouts/Wallet/WalletLayout.qml @@ -89,10 +89,15 @@ Item { if (leftPanelSelection === WalletLayout.LeftPanelSelection.SavedAddresses) { d.displaySavedAddresses() } else { + let address = data.address ?? "" if (leftPanelSelection === WalletLayout.LeftPanelSelection.AllAddresses) { d.displayAllAddresses() } else if (leftPanelSelection === WalletLayout.LeftPanelSelection.Address) { - d.displayAddress(address) + if (!!address) { + d.displayAddress(address) + } else { + d.displayAllAddresses() + } } if (rightPanelSelection !== WalletLayout.RightPanelSelection.Collectibles && @@ -105,10 +110,14 @@ Item { rightPanelStackView.currentItem.resetView() rightPanelStackView.currentItem.currentTabIndex = rightPanelSelection + let txHash = data.txHash?? "" let savedAddress = data.savedAddress?? "" if (!!savedAddress) { RootStore.currentActivityFiltersStore.resetAllFilters() RootStore.currentActivityFiltersStore.toggleSavedAddress(savedAddress) + } else if (!!txHash) { + RootStore.currentActivityFiltersStore.resetAllFilters() + RootStore.currentActivityFiltersStore.displayTxDetails(txHash) } } } diff --git a/ui/app/AppLayouts/Wallet/stores/ActivityFiltersStore.qml b/ui/app/AppLayouts/Wallet/stores/ActivityFiltersStore.qml index ced78c9565..2a527b27f0 100644 --- a/ui/app/AppLayouts/Wallet/stores/ActivityFiltersStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/ActivityFiltersStore.qml @@ -20,6 +20,8 @@ QtObject { recentsFilters.length !== 0 || savedAddressFilters.length !== 0 + signal displayTxDetails(string txHash) + readonly property QtObject _d: QtObject { id: d diff --git a/ui/app/mainui/ToastsManager.qml b/ui/app/mainui/ToastsManager.qml index 05c7c30670..d314848e37 100644 --- a/ui/app/mainui/ToastsManager.qml +++ b/ui/app/mainui/ToastsManager.qml @@ -129,7 +129,7 @@ QtObject { } // Community token received in the user wallet: - function onCommunityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName) { + function onCommunityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAddress, walletAccountName) { // Some error control: if(tokenType !== Constants.TokenType.ERC20 && tokenType !== Constants.TokenType.ERC721) { @@ -155,7 +155,8 @@ QtObject { tokenName: name, tokenSymbol: symbol, tokenImage: image, - tokenAmount: balance + tokenAmount: balance, + walletAddress: walletAddress } if(isFirst) { @@ -217,17 +218,18 @@ QtObject { root.sendModalPopup.open() return case ToastsManager.ActionType.ViewTransactionDetails: - var txHash = "" if(actionData) { var parsedData = JSON.parse(actionData) - txHash = parsedData.txHash + const txHash = parsedData.txHash + const walletAddress = parsedData.walletAddress Global.changeAppSectionBySectionType(Constants.appSection.wallet, - WalletLayout.LeftPanelSelection.AllAddresses, - WalletLayout.RightPanelSelection.Activity) - // TODO: Final navigation to the specific transaction entry --> {transaction: txHash}) --> Issue #13249 + WalletLayout.LeftPanelSelection.Address, + WalletLayout.RightPanelSelection.Activity, + {address: walletAddress, + txHash: txHash}) return } - console.warn("Unexpected transaction hash while trying to navigate to the details page: " + txHash) + console.warn("Unexpected transaction hash while trying to navigate to the details page") return case ToastsManager.ActionType.OpenFirstCommunityTokenPopup: if(actionData) { diff --git a/ui/app/mainui/activitycenter/views/ActivityNotificationCommunityTokenReceived.qml b/ui/app/mainui/activitycenter/views/ActivityNotificationCommunityTokenReceived.qml index 3faf14bec8..95b05d3e24 100644 --- a/ui/app/mainui/activitycenter/views/ActivityNotificationCommunityTokenReceived.qml +++ b/ui/app/mainui/activitycenter/views/ActivityNotificationCommunityTokenReceived.qml @@ -46,8 +46,8 @@ ActivityNotificationBase { property int tokenType: root.tokenData.tokenType // Wallet related: - property string walletAccountName: !!root.store ? root.store.walletStore.getNameForWalletAddress(root.tokenData.walletAddress) : "" property string txHash: root.tokenData.txHash + property string walletAccountName: !!root.store && !root.isFirstTokenReceived ? root.store.walletStore.getNameForWalletAddress(root.tokenData.walletAddress) : "" QtObject { id: d @@ -57,8 +57,13 @@ ActivityNotificationBase { readonly property string ctaText: root.isFirstTokenReceived ? qsTr("Learn more") : qsTr("Transaction details") readonly property string title: root.isFirstTokenReceived ? (root.isAssetType ? qsTr("You received your first community asset") : qsTr("You received your first community collectible")) : qsTr("Tokens received") - readonly property string info: root.isFirstTokenReceived ? qsTr("%1 %2 was airdropped to you from the %3 community").arg(root.tokenAmount).arg(d.formattedTokenName).arg(root.communityName) : - qsTr("You were airdropped %1 %2 from %3 to %4").arg(root.tokenAmount).arg(root.tokenName).arg(root.communityName).arg(root.walletAccountName) + readonly property string info: { + if (root.isFirstTokenReceived) { + return qsTr("%1 %2 was airdropped to you from the %3 community").arg(root.tokenAmount).arg(d.formattedTokenName).arg(root.communityName) + } else { + return qsTr("You were airdropped %1 %2 from %3 to %4").arg(root.tokenAmount).arg(root.tokenName).arg(root.communityName).arg(root.walletAccountName) + } + } } bodyComponent: RowLayout { @@ -121,9 +126,10 @@ ActivityNotificationBase { } else { Global.changeAppSectionBySectionType(Constants.appSection.wallet, - WalletLayout.LeftPanelSelection.AllAddresses, - WalletLayout.RightPanelSelection.Activity) - // TODO: Final navigation to the specific transaction entry --> {transaction: txHash}) --> Issue #13249 + WalletLayout.LeftPanelSelection.Address, + WalletLayout.RightPanelSelection.Activity, + {address: root.tokenData.walletAddress, + txHash: root.txHash}) } } } diff --git a/ui/imports/shared/stores/CommunityTokensStore.qml b/ui/imports/shared/stores/CommunityTokensStore.qml index 2da54790a9..ce752b52ce 100644 --- a/ui/imports/shared/stores/CommunityTokensStore.qml +++ b/ui/imports/shared/stores/CommunityTokensStore.qml @@ -38,7 +38,8 @@ QtObject { string communityId, string communityName, string balance, int chainId, string txHash, bool isFirst, - int tokenType, string walletAccountName) + int tokenType, string walletAccountName, + string walletAddress) // Minting tokens: function deployCollectible(communityId, collectibleItem) @@ -136,8 +137,8 @@ QtObject { root.ownerTokenReceived(communityId, communityName) } - function onCommunityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName) { - root.communityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName) + function onCommunityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName, walletAccountName, walletAddress) { + root.communityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName, walletAccountName, walletAddress) } function onSetSignerStateChanged(communityId, communityName, status, url) { diff --git a/ui/imports/shared/views/HistoryView.qml b/ui/imports/shared/views/HistoryView.qml index 952c37f958..7c7f8092e0 100644 --- a/ui/imports/shared/views/HistoryView.qml +++ b/ui/imports/shared/views/HistoryView.qml @@ -48,6 +48,10 @@ ColumnLayout { } } + onVisibleChanged: { + d.openTxDetailsHash = "" + } + Component.onCompleted: { if (RootStore.transactionActivityStatus.isFilterDirty) { WalletStores.RootStore.currentActivityFiltersStore.applyAllFilters() @@ -69,6 +73,16 @@ ColumnLayout { } } + Connections { + target: WalletStores.RootStore.currentActivityFiltersStore + enabled: root.visible + function onDisplayTxDetails(txHash) { + if (!d.openTxDetails(txHash)) { + d.openTxDetailsHash = txHash + } + } + } + QtObject { id: d readonly property bool isInitialLoading: RootStore.loadingHistoryTransactions && transactionListRoot.count === 0 @@ -84,6 +98,23 @@ ColumnLayout { d.lastRefreshTime = Date.now() newTransactions.visible = false } + + property string openTxDetailsHash + + function openTxDetails(txHash) { + // Prevent opening details when loading, that will invalidate the model data + if (RootStore.loadingHistoryTransactions) { + return false + } + + const index = WalletStores.RootStore.currentActivityFiltersStore.transactionsList.getIndex(txHash) + if (index < 0) + return false + const entry = transactionListRoot.itemAtIndex(index) + root.selectedTransaction = Qt.binding(() => entry.modelData) + root.launchTransactionDetail(index) + return true + } } StyledText { @@ -142,6 +173,16 @@ ColumnLayout { objectName: "walletAccountTransactionList" anchors.fill: parent + onCountChanged: { + if (!!d.openTxDetailsHash && root.visible) { + if (d.openTxDetails(d.openTxDetailsHash)) { + d.openTxDetailsHash = "" + } else { + RootStore.fetchMoreTransactions() + } + } + } + model: SortFilterProxyModel { id: txModel