From dbd7937d8b58b0ba2b395a2c3c2fe727c6aab92e Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Wed, 14 Feb 2024 11:49:22 +0100 Subject: [PATCH] feat(savedaddresses): add save receiver address to the context menu in tx details view This commit handles saved addresses changes and reflect them to the history view and tx details view. In this context it handles the same way changes coming from sync devices. Also fix the issue when switching network mode. Closes: #13095 --- .../wallet_section/activity/controller.nim | 33 +++++++++++++++++-- .../main/wallet_section/activity/model.nim | 8 +++++ .../modules/main/wallet_section/module.nim | 6 ++-- .../saved_addresses/controller.nim | 3 ++ .../wallet_section/saved_addresses/module.nim | 16 +++++---- .../service/saved_address/service.nim | 7 ++-- .../AppLayouts/Wallet/views/RightTabView.qml | 6 ++-- .../Wallet/views/TransactionDetailView.qml | 17 ++++++++-- .../shared/controls/TransactionAddress.qml | 33 +++++++++---------- ui/imports/shared/views/HistoryView.qml | 7 ++-- 10 files changed, 96 insertions(+), 40 deletions(-) diff --git a/src/app/modules/main/wallet_section/activity/controller.nim b/src/app/modules/main/wallet_section/activity/controller.nim index 6aa734f16c..6d38b533bb 100644 --- a/src/app/modules/main/wallet_section/activity/controller.nim +++ b/src/app/modules/main/wallet_section/activity/controller.nim @@ -22,6 +22,8 @@ import app_service/common/types import app_service/service/currency/service as currency_service import app_service/service/transaction/service as transaction_service import app_service/service/token/service as token_service +import app_service/service/wallet_account/service as wallet_account_service +import app_service/service/saved_address/service as saved_address_service import app/modules/shared/wallet_utils import app/modules/shared_models/currency_amount @@ -47,6 +49,7 @@ QtObject: currentActivityFilter: backend_activity.ActivityFilter currencyService: currency_service.Service tokenService: token_service.Service + savedAddressService: saved_address_service.Service activityDetails: ActivityDetails eventsHandler: EventsHandler @@ -225,7 +228,29 @@ QtObject: error "error requesting oldest activity timestamp: ", resJson.error return - proc setupEventHandlers(self: Controller) = + proc checkAllSavedAddresses(self: Controller) = + let appNetwork = self.savedAddressService.areTestNetworksEnabled() + let addressesToSearchThrough = self.savedAddressService.getSavedAddresses().filter(x => x.isTest == appNetwork) + for saDto in addressesToSearchThrough: + self.model.refreshItemsContainingAddress(saDto.address) + + proc setupEventHandlers(self: Controller, events: EventEmitter) = + # setup in app direct event handlers + events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args): + self.checkAllSavedAddresses() + + events.on(SIGNAL_SAVED_ADDRESSES_UPDATED) do(e:Args): + self.checkAllSavedAddresses() + + events.on(SIGNAL_SAVED_ADDRESS_UPDATED) do(e:Args): + let args = SavedAddressArgs(e) + self.model.refreshItemsContainingAddress(args.address) + + events.on(SIGNAL_SAVED_ADDRESS_DELETED) do(e:Args): + let args = SavedAddressArgs(e) + self.model.refreshItemsContainingAddress(args.address) + + # setup other event handlers self.eventsHandler.onFilteringDone(proc (jsonObj: JsonNode) = self.processResponse(jsonObj) ) @@ -271,7 +296,7 @@ QtObject: error "error fetching collectibles: ", res.errorCode return - try: + try: let items = res.collectibles.map(header => collectibleToItem(header)) self.collectiblesModel.setItems(items, res.offset, res.hasMore) except Exception as e: @@ -285,6 +310,7 @@ QtObject: proc newController*(requestId: int32, currencyService: currency_service.Service, tokenService: token_service.Service, + savedAddressService: saved_address_service.Service, events: EventEmitter, collectiblesConverter: CollectiblesToTokenConverter): Controller = new(result, delete) @@ -294,6 +320,7 @@ QtObject: result.recipientsModel = newRecipientsModel() result.collectiblesModel = newCollectiblesModel() result.tokenService = tokenService + result.savedAddressService = savedAddressService result.currentActivityFilter = backend_activity.getIncludeAllActivityFilter() result.eventsHandler = newEventsHandler(result.requestId, events) @@ -311,7 +338,7 @@ QtObject: result.setup() - result.setupEventHandlers() + result.setupEventHandlers(events) proc setFilterStatus*(self: Controller, statusesArrayJsonString: string) {.slot.} = let statusesJson = parseJson(statusesArrayJsonString) diff --git a/src/app/modules/main/wallet_section/activity/model.nim b/src/app/modules/main/wallet_section/activity/model.nim index 34526d052a..41b2076117 100644 --- a/src/app/modules/main/wallet_section/activity/model.nim +++ b/src/app/modules/main/wallet_section/activity/model.nim @@ -127,3 +127,11 @@ QtObject: QtProperty[bool] hasMore: read = getHasMore notify = hasMoreChanged + + proc refreshItemsContainingAddress*(self: Model, address: string) = + for i in 0..self.entries.high: + if cmpIgnoreCase(self.entries[i].getSender(), address) == 0 or + cmpIgnoreCase(self.entries[i].getRecipient(), address) == 0: + let index = self.createIndex(i, 0, nil) + defer: index.delete + self.dataChanged(index, index, @[ModelRole.ActivityEntryRole.int]) \ No newline at end of file diff --git a/src/app/modules/main/wallet_section/module.nim b/src/app/modules/main/wallet_section/module.nim index 9b5322aa4e..2a8ee0a666 100644 --- a/src/app/modules/main/wallet_section/module.nim +++ b/src/app/modules/main/wallet_section/module.nim @@ -137,8 +137,10 @@ proc newModule*( result.transactionService = transactionService let collectiblesToTokenConverter = proc(id: string): backend_activity.Token = return allCollectiblesModule.getAllCollectiblesModel().getActivityToken(id) - result.activityController = activityc.newController(int32(ActivityID.History), currencyService, tokenService, events, collectiblesToTokenConverter) - result.tmpActivityController = activityc.newController(int32(ActivityID.Temporary), currencyService, tokenService, events, collectiblesToTokenConverter) + result.activityController = activityc.newController(int32(ActivityID.History), currencyService, tokenService, + savedAddressService, events, collectiblesToTokenConverter) + result.tmpActivityController = activityc.newController(int32(ActivityID.Temporary), currencyService, tokenService, + savedAddressService, events, collectiblesToTokenConverter) result.collectibleDetailsController = collectible_detailsc.newController(int32(backend_collectibles.CollectiblesRequestID.WalletAccount), networkService, events) result.filter = initFilter(result.controller) diff --git a/src/app/modules/main/wallet_section/saved_addresses/controller.nim b/src/app/modules/main/wallet_section/saved_addresses/controller.nim index 5c82430db5..06502c47ea 100644 --- a/src/app/modules/main/wallet_section/saved_addresses/controller.nim +++ b/src/app/modules/main/wallet_section/saved_addresses/controller.nim @@ -43,6 +43,9 @@ proc areTestNetworksEnabled*(self: Controller): bool = proc getSavedAddresses*(self: Controller): seq[saved_address_service.SavedAddressDto] = return self.savedAddressService.getSavedAddresses() +proc getSavedAddress*(self: Controller, address: string, ignoreNetworkMode: bool): SavedAddressDto = + return self.savedAddressService.getSavedAddress(address, ignoreNetworkMode) + proc createOrUpdateSavedAddress*(self: Controller, name: string, address: string, ens: string, colorId: string, chainShortNames: string) = self.savedAddressService.createOrUpdateSavedAddress(name, address, ens, colorId, chainShortNames) diff --git a/src/app/modules/main/wallet_section/saved_addresses/module.nim b/src/app/modules/main/wallet_section/saved_addresses/module.nim index ce7b4be648..ba7907f273 100644 --- a/src/app/modules/main/wallet_section/saved_addresses/module.nim +++ b/src/app/modules/main/wallet_section/saved_addresses/module.nim @@ -88,13 +88,15 @@ method savedAddressNameExists*(self: Module, name: string): bool = return self.view.getModel().nameExists(name, self.controller.areTestNetworksEnabled()) method getSavedAddressAsJson*(self: Module, address: string): string = - let item = self.view.getModel().getItemByAddress(address, self.controller.areTestNetworksEnabled()) + let saDto = self.controller.getSavedAddress(address, ignoreNetworkMode = false) + if saDto.isNil: + return "" let jsonObj = %* { - "name": item.getName(), - "address": item.getAddress(), - "ens": item.getEns(), - "colorId": item.getColorId(), - "chainShortNames": item.getChainShortNames(), - "isTest": item.getIsTest(), + "name": saDto.name, + "address": saDto.address, + "ens": saDto.ens, + "colorId": saDto.colorId, + "chainShortNames": saDto.chainShortNames, + "isTest": saDto.isTest, } return $jsonObj \ No newline at end of file diff --git a/src/app_service/service/saved_address/service.nim b/src/app_service/service/saved_address/service.nim index 3aad5b50d6..4febf65f66 100644 --- a/src/app_service/service/saved_address/service.nim +++ b/src/app_service/service/saved_address/service.nim @@ -82,10 +82,11 @@ QtObject: proc getSavedAddresses*(self: Service): seq[SavedAddressDto] = return self.savedAddresses - proc getSavedAddress*(self: Service, address: string): SavedAddressDto = + proc getSavedAddress*(self: Service, address: string, ignoreNetworkMode: bool = true): SavedAddressDto = for sa in self.savedAddresses: - if cmpIgnoreCase(sa.address, address) == 0: - return sa + if cmpIgnoreCase(sa.address, address) == 0 and + (ignoreNetworkMode or sa.isTest == self.areTestNetworksEnabled()): + return sa proc updateAddresses(self: Service, signal: string, arg: Args) = self.savedAddresses = self.getAddresses() diff --git a/ui/app/AppLayouts/Wallet/views/RightTabView.qml b/ui/app/AppLayouts/Wallet/views/RightTabView.qml index 8362d0e33f..10a8296473 100644 --- a/ui/app/AppLayouts/Wallet/views/RightTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/RightTabView.qml @@ -46,7 +46,7 @@ RightTabBaseView { target: walletSection function onFilterChanged() { - root.resetStack() + root.resetView() } } @@ -198,9 +198,9 @@ RightTabBaseView { showAllAccounts: RootStore.showAllAccounts sendModal: root.sendModal filterVisible: filterButton.checked - onLaunchTransactionDetail: function (entry, entryIndex) { + onLaunchTransactionDetail: function (entryIndex) { transactionDetailView.transactionIndex = entryIndex - transactionDetailView.transaction = entry + transactionDetailView.transaction = Qt.binding(() => selectedTransaction) stack.currentIndex = 3 } } diff --git a/ui/app/AppLayouts/Wallet/views/TransactionDetailView.qml b/ui/app/AppLayouts/Wallet/views/TransactionDetailView.qml index 7ff1c86bea..d8459fbed1 100644 --- a/ui/app/AppLayouts/Wallet/views/TransactionDetailView.qml +++ b/ui/app/AppLayouts/Wallet/views/TransactionDetailView.qml @@ -34,12 +34,23 @@ Item { property bool showAllAccounts: false readonly property bool isTransactionValid: transaction !== undefined && !!transaction - onTransactionChanged: d.updateTransactionDetails() + onTransactionChanged: { + d.reEvaluateSender = !d.reEvaluateSender + d.reEvaluateRecipient = !d.reEvaluateRecipient + d.reEvaluateSender = !d.reEvaluateSender + d.reEvaluateRecipient = !d.reEvaluateRecipient + + d.updateTransactionDetails() + } + Component.onCompleted: d.updateTransactionDetails() QtObject { id: d + property bool reEvaluateSender: true + property bool reEvaluateRecipient: true + property var details: null readonly property bool isDetailsValid: details !== undefined && !!details readonly property bool isIncoming: transactionType === Constants.TransactionType.Received || transactionType === Constants.TransactionType.ContractDeployment @@ -281,7 +292,7 @@ Item { width: parent.width title: d.transactionType === Constants.TransactionType.Swap || d.transactionType === Constants.TransactionType.Bridge ? qsTr("In") : qsTr("From") - addresses: root.isTransactionValid ? [root.transaction.sender] : [] + addresses: root.isTransactionValid && d.reEvaluateSender? [root.transaction.sender] : [] contactsStore: root.contactsStore rootStore: WalletStores.RootStore onButtonClicked: { @@ -324,7 +335,7 @@ Item { TransactionAddressTile { width: parent.width title: qsTr("To") - addresses: root.isTransactionValid && visible ? [root.transaction.recipient] : [] + addresses: root.isTransactionValid && visible && d.reEvaluateRecipient? [root.transaction.recipient] : [] contactsStore: root.contactsStore rootStore: WalletStores.RootStore onButtonClicked: addressMenu.openReceiverMenu(this, addresses[0], [d.networkShortName]) diff --git a/ui/imports/shared/controls/TransactionAddress.qml b/ui/imports/shared/controls/TransactionAddress.qml index 421a63b8bc..93c678a8d3 100644 --- a/ui/imports/shared/controls/TransactionAddress.qml +++ b/ui/imports/shared/controls/TransactionAddress.qml @@ -66,6 +66,14 @@ Item { implicitHeight: Math.max(44, contentColumn.height) + 12 + onAddressChanged: { + d.refresh() + } + + Component.onCompleted: { + d.refresh() + } + QtObject { id: d @@ -79,7 +87,7 @@ Item { property string walletAddressEmoji property string walletAddressColor - Component.onCompleted: { + function refresh() { refreshContactData() refreshSavedAddressName() refreshWalletAddress() @@ -105,21 +113,6 @@ Item { d.walletAddressColor = Utils.getColorForId(!!root.rootStore ? root.rootStore.getColorForWalletAddress(root.address) : "") } - function getName() { - let name = "" - if (d.isContact) { - name = ProfileUtils.displayName(d.contactData.localNickname, d.contactData.name, d.contactData.displayName, d.contactData.alias) - } - return name || d.walletAddressName || d.savedAddressName - } - - readonly property Connections savedAccountsConnection: Connections { - target: !!root.rootStore && !!root.rootStore.savedAddresses ? root.rootStore.savedAddresses.sourceModel ?? null : null - function onItemChanged(address) { - if (address === root.address) - d.refreshSavedAddressName() - } - } readonly property Connections walletAccountsConnection: Connections { target: !!root.rootStore ? root.rootStore.accounts ?? null : null @@ -182,7 +175,13 @@ Item { Layout.fillWidth: true font.pixelSize: 15 color: Theme.palette.directColor1 - text: d.getName() + text: { + let name = "" + if (d.isContact) { + name = ProfileUtils.displayName(d.contactData.localNickname, d.contactData.name, d.contactData.displayName, d.contactData.alias) + } + return name || d.walletAddressName || d.savedAddressName + } visible: !!text elide: Text.ElideRight } diff --git a/ui/imports/shared/views/HistoryView.qml b/ui/imports/shared/views/HistoryView.qml index 12d7228533..07ab9aab72 100644 --- a/ui/imports/shared/views/HistoryView.qml +++ b/ui/imports/shared/views/HistoryView.qml @@ -32,7 +32,9 @@ ColumnLayout { property var sendModal property bool filterVisible - signal launchTransactionDetail(var transaction, int entryIndex) + property var selectedTransaction + + signal launchTransactionDetail(int entryIndex) function resetView() { if (!!filterPanelLoader.item) { @@ -430,7 +432,8 @@ ColumnLayout { if (mouse.button === Qt.RightButton) { delegateMenu.openMenu(this, mouse, modelData) } else { - launchTransactionDetail(modelData, index) + root.selectedTransaction = Qt.binding(() => model.activityEntry) + launchTransactionDetail(index) } } }