From 8e8f194eb7b9cb8774cbe6fb102eb434038788b5 Mon Sep 17 00:00:00 2001 From: Anthony Laibe Date: Fri, 12 May 2023 09:11:44 +0200 Subject: [PATCH] feat(@wallet): add all account action --- .../main/wallet_section/controller.nim | 4 +- .../modules/main/wallet_section/filter.nim | 19 ++- .../main/wallet_section/io_interface.nim | 6 + .../modules/main/wallet_section/module.nim | 12 +- .../main/wallet_section/networks/module.nim | 5 +- .../main/wallet_section/networks/view.nim | 6 +- .../wallet_section/overview/io_interface.nim | 2 +- .../main/wallet_section/overview/module.nim | 5 +- src/app/modules/main/wallet_section/view.nim | 6 + .../service/wallet_account/service.nim | 4 +- ui/app/AppLayouts/Wallet/WalletLayout.qml | 4 +- ui/app/AppLayouts/Wallet/controls/qmldir | 2 +- .../AppLayouts/Wallet/panels/WalletHeader.qml | 1 - ui/app/AppLayouts/Wallet/stores/RootStore.qml | 8 + .../AppLayouts/Wallet/views/LeftTabView.qml | 150 +++++++++++------- .../AppLayouts/Wallet/views/RightTabView.qml | 1 + 16 files changed, 157 insertions(+), 78 deletions(-) diff --git a/src/app/modules/main/wallet_section/controller.nim b/src/app/modules/main/wallet_section/controller.nim index f1eb75daa5..d1578e28ab 100644 --- a/src/app/modules/main/wallet_section/controller.nim +++ b/src/app/modules/main/wallet_section/controller.nim @@ -45,8 +45,8 @@ proc getSigningPhrase*(self: Controller): string = proc isMnemonicBackedUp*(self: Controller): bool = return self.settingsService.getMnemonic().len > 0 -proc getCurrencyBalance*(self: Controller): CurrencyAmount = - return currencyAmountToItem(self.walletAccountService.getTotalCurrencyBalance(), self.currencyService.getCurrencyFormat(self.getCurrency())) +proc getCurrencyBalance*(self: Controller, addresses: seq[string]): CurrencyAmount = + return currencyAmountToItem(self.walletAccountService.getTotalCurrencyBalance(addresses), self.currencyService.getCurrencyFormat(self.getCurrency())) proc getCurrencyAmount*(self: Controller, amount: float64, symbol: string): CurrencyAmount = return currencyAmountToItem(amount, self.currencyService.getCurrencyFormat(symbol)) diff --git a/src/app/modules/main/wallet_section/filter.nim b/src/app/modules/main/wallet_section/filter.nim index e569b528bf..9bf90e14a5 100644 --- a/src/app/modules/main/wallet_section/filter.nim +++ b/src/app/modules/main/wallet_section/filter.nim @@ -1,4 +1,4 @@ -import strformat +import strformat, sequtils, sugar import ./controller @@ -7,6 +7,7 @@ type Filter* = ref object controller: Controller addresses*: seq[string] chainIds*: seq[int] + excludeWatchOnly*: bool proc initFilter*( controller: Controller, @@ -15,7 +16,7 @@ proc initFilter*( result.controller = controller result.addresses = @[] result.chainIds = @[] - + result.excludeWatchOnly = false proc `$`*(self: Filter): string = result = fmt"""WalletFilter( @@ -24,9 +25,19 @@ proc `$`*(self: Filter): string = )""" +proc setFillterAllAddresses*(self: Filter) = + self.addresses = self.controller.getWalletAccounts().map(a => a.address) + +proc toggleWatchOnlyAccounts*(self: Filter) = + self.excludeWatchOnly = not self.excludeWatchOnly + + if self.excludeWatchOnly: + self.addresses = self.controller.getWalletAccounts().filter(a => a.walletType != "watch").map(a => a.address) + else: + self.setFillterAllAddresses() + proc load*(self: Filter) = - let accounts = self.controller.getWalletAccounts() - self.addresses = @[accounts[0].address] + self.setFillterAllAddresses() self.chainIds = self.controller.getEnabledChainIds() proc setAddress*(self: Filter, address: string) = diff --git a/src/app/modules/main/wallet_section/io_interface.nim b/src/app/modules/main/wallet_section/io_interface.nim index 01ef2bb9df..c2537f74ce 100644 --- a/src/app/modules/main/wallet_section/io_interface.nim +++ b/src/app/modules/main/wallet_section/io_interface.nim @@ -18,6 +18,12 @@ method isLoaded*(self: AccessInterface): bool {.base.} = method setFilterAddress*(self: AccessInterface, address: string) {.base.} = raise newException(ValueError, "No implementation available") +method setFillterAllAddresses*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method toggleWatchOnlyAccounts*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + method updateCurrency*(self: AccessInterface, currency: string) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/wallet_section/module.nim b/src/app/modules/main/wallet_section/module.nim index fe432ff3e4..5c3f64830e 100644 --- a/src/app/modules/main/wallet_section/module.nim +++ b/src/app/modules/main/wallet_section/module.nim @@ -118,10 +118,10 @@ method updateCurrency*(self: Module, currency: string) = self.controller.updateCurrency(currency) method setTotalCurrencyBalance*(self: Module) = - self.view.setTotalCurrencyBalance(self.controller.getCurrencyBalance()) + self.view.setTotalCurrencyBalance(self.controller.getCurrencyBalance(self.filter.addresses)) method notifyFilterChanged(self: Module) = - self.overviewModule.filterChanged(self.filter.addresses, self.filter.chainIds) + self.overviewModule.filterChanged(self.filter.addresses, self.filter.chainIds, self.filter.excludeWatchOnly) self.assetsModule.filterChanged(self.filter.addresses, self.filter.chainIds) self.collectiblesModule.filterChanged(self.filter.addresses, self.filter.chainIds) self.transactionsModule.filterChanged(self.filter.addresses, self.filter.chainIds) @@ -130,11 +130,19 @@ method notifyFilterChanged(self: Module) = method getCurrencyAmount*(self: Module, amount: float64, symbol: string): CurrencyAmount = return self.controller.getCurrencyAmount(amount, symbol) +method toggleWatchOnlyAccounts*(self: Module) = + self.filter.toggleWatchOnlyAccounts() + self.notifyFilterChanged() + self.setTotalCurrencyBalance() method setFilterAddress*(self: Module, address: string) = self.filter.setAddress(address) self.notifyFilterChanged() +method setFillterAllAddresses*(self: Module) = + self.filter.setFillterAllAddresses() + self.notifyFilterChanged() + method load*(self: Module) = singletonInstance.engine.setRootContextProperty("walletSection", newQVariant(self.view)) diff --git a/src/app/modules/main/wallet_section/networks/module.nim b/src/app/modules/main/wallet_section/networks/module.nim index 70a948f471..ad4d0a6475 100644 --- a/src/app/modules/main/wallet_section/networks/module.nim +++ b/src/app/modules/main/wallet_section/networks/module.nim @@ -40,11 +40,12 @@ method delete*(self: Module) = method refreshNetworks*(self: Module) = self.view.setAreTestNetworksEnabled(self.controller.areTestNetworksEnabled()) - self.view.load(self.controller.getNetworks()) + self.view.setItems(self.controller.getNetworks()) method load*(self: Module) = self.controller.init() - self.refreshNetworks() + self.view.setAreTestNetworksEnabled(self.controller.areTestNetworksEnabled()) + self.view.load(self.controller.getNetworks()) method isLoaded*(self: Module): bool = return self.moduleLoaded diff --git a/src/app/modules/main/wallet_section/networks/view.nim b/src/app/modules/main/wallet_section/networks/view.nim index 066ef682ac..f9596b1c6c 100644 --- a/src/app/modules/main/wallet_section/networks/view.nim +++ b/src/app/modules/main/wallet_section/networks/view.nim @@ -82,8 +82,8 @@ QtObject: QtProperty[QVariant] enabled: read = getEnabled notify = enabledChanged - - proc load*(self: View, networks: seq[NetworkDto]) = + + proc setItems*(self: View, networks: seq[NetworkDto]) = var items: seq[Item] = @[] let allEnabled = areAllEnabled(networks) for n in networks: @@ -115,6 +115,8 @@ QtObject: self.layer2Changed() self.enabledChanged() + proc load*(self: View, networks: seq[NetworkDto]) = + self.setItems(networks) self.delegate.viewDidLoad() proc toggleNetwork*(self: View, chainId: int) {.slot.} = diff --git a/src/app/modules/main/wallet_section/overview/io_interface.nim b/src/app/modules/main/wallet_section/overview/io_interface.nim index b8ebd4ec40..2f48df77b6 100644 --- a/src/app/modules/main/wallet_section/overview/io_interface.nim +++ b/src/app/modules/main/wallet_section/overview/io_interface.nim @@ -17,5 +17,5 @@ method isLoaded*(self: AccessInterface): bool {.base.} = method viewDidLoad*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") -method filterChanged*(self: AccessInterface, addresses: seq[string], chainIds: seq[int]) {.base.} = +method filterChanged*(self: AccessInterface, addresses: seq[string], chainIds: seq[int], excludeWatchOnly: bool) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/wallet_section/overview/module.nim b/src/app/modules/main/wallet_section/overview/module.nim index df50f4920d..2b8495dda8 100644 --- a/src/app/modules/main/wallet_section/overview/module.nim +++ b/src/app/modules/main/wallet_section/overview/module.nim @@ -65,7 +65,7 @@ proc getWalletAccoutColors(self: Module, walletAccounts: seq[WalletAccountDto]) colors.add(account.color) return colors -method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) = +method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int], excludeWatchOnly: bool) = let walletAccounts = self.controller.getWalletAccountsByAddresses(addresses) if addresses.len > 1: let item = initItem( @@ -76,7 +76,7 @@ method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) "", "", isAllAccounts=true, - hideWatchAccounts=false, # TODO(alaibe): need update when doing the action + hideWatchAccounts=excludeWatchOnly, self.getWalletAccoutColors(walletAccounts) ) self.view.setData(item) @@ -90,7 +90,6 @@ method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) walletAccount.color, walletAccount.emoji, ) - self.view.setData(item) let walletTokens = self.controller.getWalletTokensByAddresses(addresses) diff --git a/src/app/modules/main/wallet_section/view.nim b/src/app/modules/main/wallet_section/view.nim index a3b1a71bd7..6f37086d08 100644 --- a/src/app/modules/main/wallet_section/view.nim +++ b/src/app/modules/main/wallet_section/view.nim @@ -66,6 +66,12 @@ QtObject: proc setFilterAddress(self: View, address: string) {.slot.} = self.delegate.setFilterAddress(address) + proc setFillterAllAddresses(self: View) {.slot.} = + self.delegate.setFillterAllAddresses() + + proc toggleWatchOnlyAccounts(self: View) {.slot.} = + self.delegate.toggleWatchOnlyAccounts() + proc setTotalCurrencyBalance*(self: View, totalCurrencyBalance: CurrencyAmount) = self.totalCurrencyBalance = totalCurrencyBalance self.totalCurrencyBalanceChanged() diff --git a/src/app_service/service/wallet_account/service.nim b/src/app_service/service/wallet_account/service.nim index 83c0bfe25c..a0d936183f 100644 --- a/src/app_service/service/wallet_account/service.nim +++ b/src/app_service/service/wallet_account/service.nim @@ -689,9 +689,9 @@ QtObject: result.balance = 0.0 result.fetched = false - proc getTotalCurrencyBalance*(self: Service, currency: string = ""): float64 = + proc getTotalCurrencyBalance*(self: Service, addresses: seq[string], currency: string = ""): float64 = let chainIds = self.networkService.getNetworks().filter(a => a.enabled).map(a => a.chainId) - let accounts = self.getWalletAccounts() + let accounts = self.getWalletAccounts().filter(w => addresses.contains(w.address)) return accounts.map(a => a.getCurrencyBalance(chainIds, self.getCurrentCurrencyIfEmpty(currency))).foldl(a + b, 0.0) proc getTokenBalanceOnChain*(self: Service, address: string, chainId: int, symbol: string): float64 = diff --git a/ui/app/AppLayouts/Wallet/WalletLayout.qml b/ui/app/AppLayouts/Wallet/WalletLayout.qml index 5d272f3f90..7095daedcc 100644 --- a/ui/app/AppLayouts/Wallet/WalletLayout.qml +++ b/ui/app/AppLayouts/Wallet/WalletLayout.qml @@ -89,7 +89,9 @@ Item { anchors.fill: parent changeSelectedAccount: function(address) { RootStore.setFilterAddress(address) - + } + selectAllAccounts: function() { + RootStore.setFillterAllAddresses() } onShowSavedAddressesChanged: { if(showSavedAddresses) diff --git a/ui/app/AppLayouts/Wallet/controls/qmldir b/ui/app/AppLayouts/Wallet/controls/qmldir index 12d0d1db09..e18452098d 100644 --- a/ui/app/AppLayouts/Wallet/controls/qmldir +++ b/ui/app/AppLayouts/Wallet/controls/qmldir @@ -1,3 +1,3 @@ NetworkFilter 1.0 NetworkFilter.qml NetworkSelectItemDelegate 1.0 NetworkSelectItemDelegate.qml -AccountHeaderGradient 1.0 AccountHeaderGradient.qml +AccountHeaderGradient 1.0 AccountHeaderGradient.qml \ No newline at end of file diff --git a/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml b/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml index 72f717422f..b43b05fcf3 100644 --- a/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml +++ b/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml @@ -104,7 +104,6 @@ Item { icon.width: 16 icon.color: Theme.palette.baseColor1 - // To-do once all accounts view is implemented, filter watch only accounts onClicked: switchHideWatchOnlyAccounts() visible: overview.isAllAccounts } diff --git a/ui/app/AppLayouts/Wallet/stores/RootStore.qml b/ui/app/AppLayouts/Wallet/stores/RootStore.qml index ac7a3e87f5..e5013c0329 100644 --- a/ui/app/AppLayouts/Wallet/stores/RootStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/RootStore.qml @@ -132,6 +132,10 @@ QtObject { walletSection.setFilterAddress(address) } + function setFillterAllAddresses() { + walletSection.setFillterAllAddresses() + } + function deleteAccount(address) { return walletSectionAccounts.deleteAccount(address) } @@ -208,4 +212,8 @@ QtObject { function switchReceiveAccount(index) { walletSectionSend.switchReceiveAccount(index) } + + function toggleWatchOnlyAccounts() { + walletSection.toggleWatchOnlyAccounts() + } } diff --git a/ui/app/AppLayouts/Wallet/views/LeftTabView.qml b/ui/app/AppLayouts/Wallet/views/LeftTabView.qml index 6cc91b3e8b..978270b980 100644 --- a/ui/app/AppLayouts/Wallet/views/LeftTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/LeftTabView.qml @@ -27,10 +27,20 @@ Rectangle { objectName: "walletLeftTab" property var networkConnectionStore + property var selectAllAccounts: function(){} property var changeSelectedAccount: function(){} property bool showSavedAddresses: false + property bool showAllAccounts: true + onShowSavedAddressesChanged: { - walletAccountsListView.footerItem.button.highlighted = showSavedAddresses + walletAccountsListView.headerItem.highlighted = root.showAllAccounts + walletAccountsListView.footerItem.button.highlighted = root.showSavedAddresses + } + + onShowAllAccountsChanged: { + walletAccountsListView.headerItem.highlighted = root.showAllAccounts + walletAccountsListView.footerItem.button.highlighted = root.showSavedAddresses + selectAllAccounts() } property var emojiPopup: null @@ -171,60 +181,6 @@ Rectangle { } } - Item { - height: childrenRect.height - Layout.fillWidth: true - Layout.leftMargin: Style.current.padding - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.RightButton - onClicked: { - mouse.accepted = true - } - } - - StyledTextEditWithLoadingState { - id: walletAmountValue - objectName: "walletLeftListAmountValue" - customColor: Style.current.textColor - text: { - LocaleUtils.currencyAmountToLocaleString(RootStore.totalCurrencyBalance) - } - selectByMouse: true - cursorVisible: true - readOnly: true - width: parent.width - font.weight: Font.Medium - font.pixelSize: 22 - loading: RootStore.assetsLoading - visible: !networkConnectionStore.accountBalanceNotAvailable - } - - StatusFlatRoundButton { - id: errorIcon - width: 14 - height: visible ? 14 : 0 - icon.width: 14 - icon.height: 14 - icon.name: "tiny/warning" - icon.color: Theme.palette.dangerColor1 - tooltip.text: networkConnectionStore.accountBalanceNotAvailableText - tooltip.maxWidth: 200 - visible: networkConnectionStore.accountBalanceNotAvailable - } - - StatusBaseText { - id: totalValue - color: Theme.palette.baseColor1 - text: qsTr("Total value") - width: parent.width - anchors.top: walletAmountValue.bottom - anchors.topMargin: 4 - font.pixelSize: 12 - } - } - StatusListView { id: walletAccountsListView @@ -267,8 +223,9 @@ Rectangle { accountContextMenu.item.popup(mouse.x, mouse.y) return } + root.showSavedAddresses = false + root.showAllAccounts = false changeSelectedAccount(model.address) - showSavedAddresses = false } components: [ StatusIcon { @@ -321,6 +278,83 @@ Rectangle { readonly property bool footerOverlayed: contentHeight > availableHeight + header: Button { + id: header + verticalPadding: Style.current.padding + horizontalPadding: Style.current.padding + highlighted: true + + leftInset: Style.current.padding + bottomInset: Style.current.padding + + background: Rectangle { + MouseArea { + id: mouseArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor + onClicked: { + root.showSavedAddresses = false + root.showAllAccounts = true + } + hoverEnabled: true + } + radius: Style.current.radius + color: header.highlighted || mouseArea.containsMouse ? Style.current.backgroundHover : root.color + implicitWidth: parent.ListView.view.width - Style.current.padding * 2 + implicitHeight: parent.ListView.view.firstItem.height + Style.current.padding + + layer.effect: DropShadow { + verticalOffset: -10 + radius: 20 + samples: 41 + fast: true + cached: true + color: Theme.palette.dropShadow2 + } + } + + contentItem: Item { + StatusBaseText { + id: allAccounts + leftPadding: Style.current.padding + color: Theme.palette.baseColor1 + text: qsTr("All accounts") + font.weight: Font.Medium + font.pixelSize: 15 + } + + StatusTextWithLoadingState { + id: walletAmountValue + objectName: "walletLeftListAmountValue" + customColor: Style.current.textColor + text: { + LocaleUtils.currencyAmountToLocaleString(RootStore.totalCurrencyBalance) + } + font.pixelSize: 22 + loading: RootStore.assetsLoading + visible: !networkConnectionStore.accountBalanceNotAvailable + anchors.top: allAccounts.bottom + anchors.topMargin: 4 + anchors.bottomMargin: Style.current.padding + leftPadding: Style.current.padding + } + + StatusFlatRoundButton { + id: errorIcon + width: 14 + height: visible ? 14 : 0 + icon.width: 14 + icon.height: 14 + icon.name: "tiny/warning" + icon.color: Theme.palette.dangerColor1 + tooltip.text: networkConnectionStore.accountBalanceNotAvailableText + tooltip.maxWidth: 200 + visible: networkConnectionStore.accountBalanceNotAvailable + } + } + } + footerPositioning: footerOverlayed ? ListView.OverlayFooter : ListView.InlineFooter footer: Control { id: footer @@ -374,12 +408,14 @@ Rectangle { textFillWidth: true spacing: parent.ListView.view.firstItem.statusListItemTitleArea.anchors.leftMargin onClicked: { - showSavedAddresses = true + root.showAllAccounts = false + root.showSavedAddresses = true } MouseArea { anchors.fill: parent acceptedButtons: Qt.RightButton + cursorShape: Qt.PointingHandCursor propagateComposedEvents: true onClicked: { mouse.accepted = true diff --git a/ui/app/AppLayouts/Wallet/views/RightTabView.qml b/ui/app/AppLayouts/Wallet/views/RightTabView.qml index 537bab8716..f8cc3c9b48 100644 --- a/ui/app/AppLayouts/Wallet/views/RightTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/RightTabView.qml @@ -60,6 +60,7 @@ Item { walletStore: RootStore networkConnectionStore: root.networkConnectionStore onLaunchShareAddressModal: root.launchShareAddressModal() + onSwitchHideWatchOnlyAccounts: RootStore.toggleWatchOnlyAccounts() } StatusTabBar { id: walletTabBar