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
This commit is contained in:
Sale Djenic 2024-02-14 11:49:22 +01:00 committed by saledjenic
parent 1410b03dd3
commit dbd7937d8b
10 changed files with 96 additions and 40 deletions

View File

@ -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)

View File

@ -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])

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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
}
}

View File

@ -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])

View File

@ -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
}

View File

@ -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)
}
}
}