chore(@desktop/wallet): Add logic to handle the selected account for the send and receive modal to nim

This commit is contained in:
Khushboo Mehta 2023-05-04 14:55:39 +02:00 committed by Khushboo-dev-cpp
parent 219eb04da9
commit 6779e15b28
17 changed files with 289 additions and 180 deletions

View File

@ -116,6 +116,7 @@ method switchAccount*(self: Module, accountIndex: int) =
self.collectiblesModule.switchAccount(accountIndex)
self.transactionsModule.switchAccount(accountIndex)
self.overviewModule.switchAccount(accountIndex)
self.sendModule.switchAccount(accountIndex)
method switchAccountByAddress*(self: Module, address: string) =
let accountIndex = self.controller.getIndex(address)

View File

@ -1,44 +1,71 @@
import strformat
import NimQml, strformat
import ../../../shared_models/wallet_account_item
import ../../../shared_models/token_model
import ../../../shared_models/currency_amount
export wallet_account_item
type
AccountItem* = ref object of WalletAccountItem
QtObject:
type AccountItem* = ref object of WalletAccountItem
assets: token_model.Model
currencyBalance: CurrencyAmount
proc initAccountItem*(
name: string = "",
address: string = "",
color: string = "",
walletType: string = "",
emoji: string = "",
assets: token_model.Model = nil,
currencyBalance: CurrencyAmount = nil,
): AccountItem =
result = AccountItem()
result.WalletAccountItem.setup(name,
proc setup*(self: AccountItem,
name: string,
address: string,
color: string,
emoji: string,
walletType: string,
assets: token_model.Model,
currencyBalance: CurrencyAmount
) =
self.QObject.setup
self.WalletAccountItem.setup(name,
address,
color,
emoji,
walletType,
path = "",
keyUid = "")
result.assets = assets
result.currencyBalance = currencyBalance
self.assets = assets
self.currencyBalance = currencyBalance
proc `$`*(self: AccountItem): string =
proc delete*(self: AccountItem) =
self.QObject.delete
proc newAccountItem*(
name: string = "",
address: string = "",
color: string = "",
emoji: string = "",
walletType: string = "",
assets: token_model.Model = nil,
currencyBalance: CurrencyAmount = nil,
): AccountItem =
new(result, delete)
result.setup(name, address, color, emoji, walletType, assets, currencyBalance)
proc `$`*(self: AccountItem): string =
result = "WalletSection-Send-Item("
result = result & $self.WalletAccountItem
result = result & "\nassets: " & $self.assets
result = result & "\ncurrencyBalance: " & $self.currencyBalance
result = result & ")"
proc assets*(self: AccountItem): token_model.Model =
proc assetsChanged*(self: AccountItem) {.signal.}
proc getAssets*(self: AccountItem): token_model.Model =
return self.assets
proc getAssetsAsQVariant*(self: AccountItem): QVariant {.slot.} =
if self.assets.isNil:
return newQVariant()
return newQVariant(self.assets)
QtProperty[QVariant] assets:
read = getAssetsAsQVariant
notify = assetsChanged
proc currencyBalance*(self: AccountItem): CurrencyAmount =
return self.currencyBalance
proc currencyBalanceChanged*(self: AccountItem) {.signal.}
proc getCurrencyBalanceAsQVariant*(self: AccountItem): QVariant {.slot.} =
return newQVariant(self.currencyBalance)
QtProperty[QVariant] currencyBalance:
read = getCurrencyBalanceAsQVariant
notify = currencyBalanceChanged

View File

@ -56,7 +56,6 @@ QtObject:
ModelRole.CurrencyBalance.int: "currencyBalance",
}.toTable
proc setItems*(self: AccountsModel, items: seq[AccountItem]) =
self.beginResetModel()
self.items = items
@ -85,7 +84,20 @@ QtObject:
of ModelRole.Emoji:
result = newQVariant(item.emoji())
of ModelRole.Assets:
result = newQVariant(item.assets())
result = newQVariant(item.getAssetsAsQVariant())
of ModelRole.CurrencyBalance:
result = newQVariant(item.currencyBalance())
result = newQVariant(item.getCurrencyBalanceAsQVariant())
method getItemByIndex*(self: AccountsModel, index: int): AccountItem =
if index < 0 or index >= self.items.len:
return
return self.items[index]
method getItemByAddress*(self: AccountsModel, address: string): tuple[account: AccountItem, index: int] =
for i in 0 ..< self.items.len:
if self.items[i].address() == address:
return (self.items[i], i)
if self.items.len > 0:
return (self.items[0], 0)

View File

@ -73,9 +73,12 @@ proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
proc getMigratedKeyPairByKeyUid*(self: Controller, keyUid: string): seq[KeyPairDto] =
return self.walletAccountService.getMigratedKeyPairByKeyUid(keyUid)
proc getWalletAccount*(self: Controller, address: string): WalletAccountDto =
proc getAccountByAddress*(self: Controller, address: string): WalletAccountDto =
return self.walletAccountService.getAccountByAddress(address)
proc getWalletAccountByIndex*(self: Controller, accountIndex: int): WalletAccountDto =
return self.walletAccountService.getWalletAccount(accountIndex)
proc getTokenBalanceOnChain*(self: Controller, address: string, chainId: int, symbol: string): CurrencyAmount =
return currencyAmountToItem(self.walletAccountService.getTokenBalanceOnChain(address, chainId, symbol), self.currencyService.getCurrencyFormat(symbol))

View File

@ -56,3 +56,12 @@ method authenticateUser*(self: AccessInterface) {.base.} =
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
raise newException(ValueError, "No implementation available")
method switchAccount*(self: AccessInterface, accountIndex: int) =
raise newException(ValueError, "No implementation available")
method setSelectedSenderAccountIndex*(self: AccessInterface, index: int) =
raise newException(ValueError, "No implementation available")
method setSelectedReceiveAccountIndex*(self: AccessInterface, index: int) =
raise newException(ValueError, "No implementation available")

View File

@ -31,6 +31,9 @@ type
controller: Controller
moduleLoaded: bool
tmpSendTransactionDetails: TmpSendTransactionDetails
senderCurrentAccountIndex: int
# To-do we should create a dedicated module Receive
receiveCurrentAccountIndex: int
proc newModule*(
delegate: delegate_interface.AccessInterface,
@ -46,6 +49,8 @@ proc newModule*(
result.view = newView(result)
result.controller = controller.newController(result, events, walletAccountService, networkService, currencyService, transactionService)
result.moduleLoaded = false
result.senderCurrentAccountIndex = 0
result.receiveCurrentAccountIndex = 0
method delete*(self: Module) =
self.view.delete
@ -73,6 +78,8 @@ method refreshWalletAccounts*(self: Module) =
))
self.view.setItems(items)
self.view.switchSenderAccount(self.senderCurrentAccountIndex)
self.view.switchReceiveAccount(self.receiveCurrentAccountIndex)
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("walletSectionSend", newQVariant(self.view))
@ -187,3 +194,15 @@ method suggestedRoutesReady*(self: Module, suggestedRoutes: string) =
method getEstimatedTime*(self: Module, chainId: int, maxFeePerGas: string): int =
return self.controller.getEstimatedTime(chainId, maxFeePerGas).int
method switchAccount*(self: Module, accountIndex: int) =
var walletAccount = self.controller.getWalletAccountByIndex(accountIndex)
if not walletAccount.isNil:
self.view.switchSenderAccountByAddress(walletAccount.address)
self.view.switchReceiveAccount(accountIndex)
method setSelectedSenderAccountIndex*(self: Module, index: int) =
self.senderCurrentAccountIndex = index
method setSelectedReceiveAccountIndex*(self: Module, index: int) =
self.receiveCurrentAccountIndex = index

View File

@ -1,4 +1,4 @@
import NimQml, sequtils, strutils, stint
import NimQml, sequtils, strutils, stint, sugar
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../shared_models/token_model
@ -12,7 +12,12 @@ QtObject:
View* = ref object of QObject
delegate: io_interface.AccessInterface
accounts: AccountsModel
accountsVariant: QVariant
# this one doesn't include watch accounts and its what the user switches when using the sendModal
senderAccounts: AccountsModel
# for send modal
selectedSenderAccount: AccountItem
# for receive modal
selectedReceiveAccount: AccountItem
tmpAddress: string # shouldn't be used anywhere except in prepare*/getPrepared* procs
tmpSymbol: string # shouldn't be used anywhere except in prepare*/getPrepared* procs
@ -20,7 +25,9 @@ QtObject:
proc delete*(self: View) =
self.accounts.delete
self.accountsVariant.delete
self.senderAccounts.delete
self.selectedSenderAccount.delete
self.selectedReceiveAccount.delete
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
@ -28,22 +35,52 @@ QtObject:
result.QObject.setup
result.delegate = delegate
result.accounts = newAccountsModel()
result.accountsVariant = newQVariant(result.accounts)
result.senderAccounts = newAccountsModel()
proc load*(self: View) =
self.delegate.viewDidLoad()
proc accountsChanged*(self: View) {.signal.}
proc getAccounts(self: View): QVariant {.slot.} =
return self.accountsVariant
return newQVariant(self.accounts)
QtProperty[QVariant] accounts:
read = getAccounts
notify = accountsChanged
proc senderAccountsChanged*(self: View) {.signal.}
proc getSenderAccounts(self: View): QVariant {.slot.} =
return newQVariant(self.senderAccounts)
QtProperty[QVariant] senderAccounts:
read = getSenderAccounts
notify = senderAccountsChanged
proc selectedSenderAccountChanged*(self: View) {.signal.}
proc getSelectedSenderAccount(self: View): QVariant {.slot.} =
return newQVariant(self.selectedSenderAccount)
proc setSelectedSenderAccount*(self: View, account: AccountItem) =
self.selectedSenderAccount = account
self.selectedSenderAccountChanged()
QtProperty[QVariant] selectedSenderAccount:
read = getSelectedSenderAccount
notify = selectedSenderAccountChanged
proc selectedReceiveAccountChanged*(self: View) {.signal.}
proc getSelectedReceiveAccount(self: View): QVariant {.slot.} =
return newQVariant(self.selectedReceiveAccount)
proc setSelectetReceiveAccount*(self: View, account: AccountItem) =
self.selectedReceiveAccount = account
self.selectedReceiveAccountChanged()
QtProperty[QVariant] selectedReceiveAccount:
read = getSelectedReceiveAccount
notify = selectedReceiveAccountChanged
proc setItems*(self: View, items: seq[AccountItem]) =
self.accounts.setItems(items)
self.accountsChanged()
# need to remove watch only accounts as a user cant send a tx with a watch only account
self.senderAccounts.setItems(items.filter(a => a.walletType() != WalletTypeWatch))
self.senderAccountsChanged()
proc prepareTokenBalanceOnChain*(self: View, address: string, chainId: int, tokenSymbol: string) {.slot.} =
self.tmpAddress = address
@ -108,6 +145,19 @@ QtObject:
proc hasGas*(self: View, address: string, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
for account in self.accounts.items:
if account.address() == address:
return account.assets().hasGas(chainId, nativeGasSymbol, requiredGas)
return account.getAssets().hasGas(chainId, nativeGasSymbol, requiredGas)
return false
proc switchSenderAccountByAddress*(self: View, address: string) =
let (account, index) = self.senderAccounts.getItemByAddress(address)
self.setSelectedSenderAccount(account)
self.delegate.setSelectedSenderAccountIndex(index)
proc switchSenderAccount*(self: View, index: int) {.slot.} =
self.setSelectedSenderAccount(self.senderAccounts.getItemByIndex(index))
self.delegate.setSelectedSenderAccountIndex(index)
proc switchReceiveAccount*(self: View, index: int) {.slot.} =
self.setSelectetReceiveAccount(self.accounts.getItemByIndex(index))
self.delegate.setSelectedReceiveAccountIndex(index)

View File

@ -105,12 +105,12 @@ proc walletAccountToWalletSendAccountItem*(w: WalletAccountDto, chainIds: seq[in
assets.setItems(
w.tokens.map(t => walletTokenToItem(t, chainIds, enabledChainIds, currency, currencyFormat, tokenFormats[t.symbol]))
)
return wallet_send_account_item.initAccountItem(
return wallet_send_account_item.newAccountItem(
w.name,
w.address,
w.color,
w.walletType,
w.emoji,
w.walletType,
assets,
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
)

View File

@ -1,7 +1,7 @@
import strformat
import NimQml, strformat
type
WalletAccountItem* = ref object of RootObj
QtObject:
type WalletAccountItem* = ref object of QObject
name: string
address: string
color: string
@ -10,7 +10,7 @@ type
path: string
keyUid: string
proc setup*(self: WalletAccountItem,
proc setup*(self: WalletAccountItem,
name: string = "",
address: string = "",
color: string = "",
@ -19,6 +19,7 @@ proc setup*(self: WalletAccountItem,
path: string = "",
keyUid: string = ""
) =
self.QObject.setup
self.name = name
self.address = address
self.color = color
@ -27,26 +28,10 @@ proc setup*(self: WalletAccountItem,
self.path = path
self.keyUid = keyUid
proc initWalletAccountItem*(
name: string = "",
address: string = "",
color: string = "",
emoji: string = "",
walletType: string = "",
path: string = "",
keyUid: string = ""
): WalletAccountItem =
result = WalletAccountItem()
result.setup(name,
address,
color,
emoji,
walletType,
path,
keyUid)
proc delete*(self: WalletAccountItem) =
self.QObject.delete
proc `$`*(self: WalletAccountItem): string =
proc `$`*(self: WalletAccountItem): string =
result = fmt"""WalletAccountItem(
name: {self.name},
address: {self.address},
@ -57,32 +42,65 @@ proc `$`*(self: WalletAccountItem): string =
keyUid: {self.keyUid},
]"""
proc name*(self: WalletAccountItem): string {.inline.} =
proc nameChanged*(self: WalletAccountItem) {.signal.}
proc name*(self: WalletAccountItem): string {.slot.} =
return self.name
proc `name=`*(self: WalletAccountItem, value: string) {.inline.} =
proc `name=`*(self: WalletAccountItem, value: string) {.inline.} =
self.name = value
self.nameChanged()
QtProperty[string] name:
read = name
notify = nameChanged
proc address*(self: WalletAccountItem): string {.inline.} =
proc addressChanged*(self: WalletAccountItem) {.signal.}
proc address*(self: WalletAccountItem): string {.slot.} =
return self.address
# proc setAddress*(self: WalletAccountItem, value: string) {.slot.} =
# self.address = value
# self.addressChanged()
QtProperty[string] address:
read = address
notify = addressChanged
proc emoji*(self: WalletAccountItem): string {.inline.} =
return self.emoji
proc `emoji=`*(self: WalletAccountItem, value: string) {.inline.} =
self.emoji = value
proc color*(self: WalletAccountItem): string {.inline.} =
proc colorChanged*(self: WalletAccountItem) {.signal.}
proc color*(self: WalletAccountItem): string {.slot.} =
return self.color
proc `color=`*(self: WalletAccountItem, value: string) {.inline.} =
proc `color=`*(self: WalletAccountItem, value: string) {.inline.} =
self.color = value
self.colorChanged()
QtProperty[string] color:
read = color
notify = colorChanged
proc walletType*(self: WalletAccountItem): string {.inline.} =
proc emojiChanged*(self: WalletAccountItem) {.signal.}
proc emoji*(self: WalletAccountItem): string {.slot.} =
return self.emoji
proc `emoji=`*(self: WalletAccountItem, value: string) {.inline.} =
self.emoji = value
self.emojiChanged()
QtProperty[string] emoji:
read = emoji
notify = emojiChanged
proc walletTypeChanged*(self: WalletAccountItem) {.signal.}
proc walletType*(self: WalletAccountItem): string {.slot.} =
return self.walletType
QtProperty[string] walletType:
read = walletType
notify = walletTypeChanged
proc path*(self: WalletAccountItem): string {.inline.} =
proc pathChanged*(self: WalletAccountItem) {.signal.}
proc path*(self: WalletAccountItem): string {.slot.} =
return self.path
QtProperty[string] path:
read = path
notify = pathChanged
proc keyUid*(self: WalletAccountItem): string {.inline.} =
proc keyUidChanged*(self: WalletAccountItem) {.signal.}
proc keyUid*(self: WalletAccountItem): string {.slot.} =
return self.keyUid
QtProperty[string] keyUid:
read = keyUid
notify = keyUidChanged

View File

@ -6,8 +6,6 @@ QtObject {
property var stickersModule
property var walletAccounts: Global.appIsReady? walletSectionAccounts.model : null
function getSigningPhrase() {
if(!root.stickersModule)
return ""

View File

@ -24,8 +24,6 @@ QtObject {
property string username: !!Global.userProfile? Global.userProfile.username : ""
property var walletAccounts: Global.appIsReady? walletSectionSend.accounts : null
function setPrefferedEnsUsername(ensName) {
if(!root.ensUsernamesModule)
return

View File

@ -16,8 +16,6 @@ import utils 1.0
import shared.controls 1.0
import shared.popups 1.0
import SortFilterProxyModel 0.2
import AppLayouts.stores 1.0
import "../stores"
@ -26,7 +24,7 @@ StatusModal {
QtObject {
id: d
property string selectedAccountAddress
property string selectedAccountAddress: RootStore.selectedReceiveAccount.address
property string networkPrefix
property string completeAddressWithNetworkPrefix
}
@ -40,19 +38,9 @@ StatusModal {
hasFloatingButtons: true
advancedHeaderComponent: AccountsModalHeader {
id: header
model: SortFilterProxyModel {
sourceModel: RootStore.accounts
}
selectedIndex: RootStore.getUserSelectedAccountIndex(header.model)
onSelectedIndexChanged: selectedAccount = header.model.get(header.selectedIndex)
onSelectedAccountChanged: d.selectedAccountAddress = selectedAccount.address
Connections {
target: RootStore.accounts
function onModelReset() {
header.selectedAccount = header.model.get(header.selectedIndex)
}
}
model: RootStore.receiveAccounts
selectedAccount: RootStore.selectedReceiveAccount
onSelectedIndexChanged: RootStore.switchReceiveAccount(selectedIndex)
}
contentItem: Column {

View File

@ -21,7 +21,8 @@ QtObject {
property var assets: walletSectionAssets.assets
property bool assetsLoading: walletSectionAssets.assetsLoading
property var accounts: walletSectionAccounts.accounts
property var sendAccounts: walletSectionSend.accounts
property var receiveAccounts: walletSectionSend.accounts
property var selectedReceiveAccount: walletSectionSend.selectedReceiveAccount
property var appSettings: localAppSettings
property var accountSensitiveSettings: localAccountSensitiveSettings
property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal
@ -199,11 +200,7 @@ QtObject {
walletSection.runEditAccountPopup(address)
}
function getUserSelectedAccountIndex(model) {
for (let i = 0; i < model.count; i++) {
if(model.get(i).address.toUpperCase() === root.overview.mixedcaseAddress.toUpperCase()) {
return i
}
}
function switchReceiveAccount(index) {
walletSectionSend.switchReceiveAccount(index)
}
}

View File

@ -81,6 +81,10 @@ StatusComboBox {
selectedIndex = index
control.popup.close()
}
Component.onCompleted:{
if(selectedAccount.address === model.address)
selectedIndex = index
}
}
}

View File

@ -15,8 +15,6 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls.Validators 0.1
import SortFilterProxyModel 0.2
import "../panels"
import "../controls"
import "../views"
@ -36,7 +34,7 @@ StatusDialog {
property var store: TransactionStore{}
property var contactsStore: store.contactStore
property var currencyStore: store.currencyStore
property var selectedAccount
property var selectedAccount: store.selectedSenderAccount
property var bestRoutes
property alias addressText: recipientLoader.addressText
property bool isLoading: false
@ -95,12 +93,6 @@ StatusDialog {
if(errorType === Constants.SendAmountExceedsBalance)
bestRoutes = []
}
function setSelectedAccount() {
popup.selectedAccount = header.model.get(header.selectedIndex)
if(!!assetSelector.selectedAsset)
assetSelector.selectedAsset = store.getAsset(selectedAccount.assets, assetSelector.selectedAsset.symbol)
}
}
width: 556
@ -155,27 +147,12 @@ StatusDialog {
onClosed: popup.store.resetTxStoreProperties()
header: AccountsModalHeader {
id: header
anchors.top: parent.top
anchors.topMargin: -height - 18
model: SortFilterProxyModel {
sourceModel: popup.store.accounts
filters: ValueFilter {
roleName: "walletType"
value: Constants.watchWalletType
inverted: true
}
}
selectedIndex: store.getUserSelectedAccountIndex(header.model)
model: popup.store.senderAccounts
selectedAccount: !!popup.selectedAccount ? popup.selectedAccount: {}
chainShortNames: store.getAllNetworksSupportedString()
onSelectedIndexChanged: d.setSelectedAccount()
Connections {
target: popup.store.accounts
function onModelReset() {
d.setSelectedAccount()
}
}
onSelectedIndexChanged: store.switchSenderAccount(selectedIndex)
}
StackLayout {
@ -244,6 +221,11 @@ StatusDialog {
getNetworkIcon: function(chainId){
return RootStore.getNetworkIcon(chainId)
}
onAssetsChanged: {
// Todo we should not need to do this, this should be automatic when selected account changes
if(!!selectedAccount && !!assetSelector.selectedAsset)
assetSelector.selectedAsset = store.getAsset(selectedAccount.assets, assetSelector.selectedAsset.symbol)
}
onSelectedAssetChanged: {
if (!assetSelector.selectedAsset || !amountToSendInput.inputNumberValid) {
return

View File

@ -21,6 +21,8 @@ QtObject {
property var allNetworks: networksModule.all
property var overview: walletSectionOverview
property var accounts: walletSectionSendInst.accounts
property var senderAccounts: walletSectionSendInst.senderAccounts
property var selectedSenderAccount: walletSectionSendInst.selectedSenderAccount
property string signingPhrase: walletSection.signingPhrase
property var savedAddressesModel: SortFilterProxyModel {
sourceModel: walletSectionSavedAddresses.model
@ -308,11 +310,7 @@ QtObject {
return result
}
function getUserSelectedAccountIndex(model) {
for (let i = 0; i < model.count; i++) {
if(model.get(i).address.toUpperCase() === root.overview.mixedcaseAddress.toUpperCase()) {
return i
}
}
function switchSenderAccount(index) {
walletSectionSendInst.switchSenderAccount(index)
}
}

View File

@ -139,7 +139,12 @@ Item {
implicitWidth: ListView.view.width
modelData: model
chainShortNames: root.store.getAllNetworksSupportedString()
onClicked: recipientSelected(modelData, TabAddressSelectorView.Type.Account )
onClicked: recipientSelected({name: modelData.name,
address: modelData.address,
color: modelData.color,
emoji: modelData.emoji,
walletType: modelData.walletType,
currencyBalance: modelData.currencyBalance}, TabAddressSelectorView.Type.Account )
}
model: root.store.accounts