feat(@wallet): add all account action

This commit is contained in:
Anthony Laibe 2023-05-12 09:11:44 +02:00 committed by Anthony Laibe
parent 420708c86f
commit 8e8f194eb7
16 changed files with 157 additions and 78 deletions

View File

@ -45,8 +45,8 @@ proc getSigningPhrase*(self: Controller): string =
proc isMnemonicBackedUp*(self: Controller): bool = proc isMnemonicBackedUp*(self: Controller): bool =
return self.settingsService.getMnemonic().len > 0 return self.settingsService.getMnemonic().len > 0
proc getCurrencyBalance*(self: Controller): CurrencyAmount = proc getCurrencyBalance*(self: Controller, addresses: seq[string]): CurrencyAmount =
return currencyAmountToItem(self.walletAccountService.getTotalCurrencyBalance(), self.currencyService.getCurrencyFormat(self.getCurrency())) return currencyAmountToItem(self.walletAccountService.getTotalCurrencyBalance(addresses), self.currencyService.getCurrencyFormat(self.getCurrency()))
proc getCurrencyAmount*(self: Controller, amount: float64, symbol: string): CurrencyAmount = proc getCurrencyAmount*(self: Controller, amount: float64, symbol: string): CurrencyAmount =
return currencyAmountToItem(amount, self.currencyService.getCurrencyFormat(symbol)) return currencyAmountToItem(amount, self.currencyService.getCurrencyFormat(symbol))

View File

@ -1,4 +1,4 @@
import strformat import strformat, sequtils, sugar
import ./controller import ./controller
@ -7,6 +7,7 @@ type Filter* = ref object
controller: Controller controller: Controller
addresses*: seq[string] addresses*: seq[string]
chainIds*: seq[int] chainIds*: seq[int]
excludeWatchOnly*: bool
proc initFilter*( proc initFilter*(
controller: Controller, controller: Controller,
@ -15,7 +16,7 @@ proc initFilter*(
result.controller = controller result.controller = controller
result.addresses = @[] result.addresses = @[]
result.chainIds = @[] result.chainIds = @[]
result.excludeWatchOnly = false
proc `$`*(self: Filter): string = proc `$`*(self: Filter): string =
result = fmt"""WalletFilter( 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) = proc load*(self: Filter) =
let accounts = self.controller.getWalletAccounts() self.setFillterAllAddresses()
self.addresses = @[accounts[0].address]
self.chainIds = self.controller.getEnabledChainIds() self.chainIds = self.controller.getEnabledChainIds()
proc setAddress*(self: Filter, address: string) = proc setAddress*(self: Filter, address: string) =

View File

@ -18,6 +18,12 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
method setFilterAddress*(self: AccessInterface, address: string) {.base.} = method setFilterAddress*(self: AccessInterface, address: string) {.base.} =
raise newException(ValueError, "No implementation available") 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.} = method updateCurrency*(self: AccessInterface, currency: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -118,10 +118,10 @@ method updateCurrency*(self: Module, currency: string) =
self.controller.updateCurrency(currency) self.controller.updateCurrency(currency)
method setTotalCurrencyBalance*(self: Module) = method setTotalCurrencyBalance*(self: Module) =
self.view.setTotalCurrencyBalance(self.controller.getCurrencyBalance()) self.view.setTotalCurrencyBalance(self.controller.getCurrencyBalance(self.filter.addresses))
method notifyFilterChanged(self: Module) = 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.assetsModule.filterChanged(self.filter.addresses, self.filter.chainIds)
self.collectiblesModule.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) 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 = method getCurrencyAmount*(self: Module, amount: float64, symbol: string): CurrencyAmount =
return self.controller.getCurrencyAmount(amount, symbol) return self.controller.getCurrencyAmount(amount, symbol)
method toggleWatchOnlyAccounts*(self: Module) =
self.filter.toggleWatchOnlyAccounts()
self.notifyFilterChanged()
self.setTotalCurrencyBalance()
method setFilterAddress*(self: Module, address: string) = method setFilterAddress*(self: Module, address: string) =
self.filter.setAddress(address) self.filter.setAddress(address)
self.notifyFilterChanged() self.notifyFilterChanged()
method setFillterAllAddresses*(self: Module) =
self.filter.setFillterAllAddresses()
self.notifyFilterChanged()
method load*(self: Module) = method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("walletSection", newQVariant(self.view)) singletonInstance.engine.setRootContextProperty("walletSection", newQVariant(self.view))

View File

@ -40,11 +40,12 @@ method delete*(self: Module) =
method refreshNetworks*(self: Module) = method refreshNetworks*(self: Module) =
self.view.setAreTestNetworksEnabled(self.controller.areTestNetworksEnabled()) self.view.setAreTestNetworksEnabled(self.controller.areTestNetworksEnabled())
self.view.load(self.controller.getNetworks()) self.view.setItems(self.controller.getNetworks())
method load*(self: Module) = method load*(self: Module) =
self.controller.init() self.controller.init()
self.refreshNetworks() self.view.setAreTestNetworksEnabled(self.controller.areTestNetworksEnabled())
self.view.load(self.controller.getNetworks())
method isLoaded*(self: Module): bool = method isLoaded*(self: Module): bool =
return self.moduleLoaded return self.moduleLoaded

View File

@ -82,8 +82,8 @@ QtObject:
QtProperty[QVariant] enabled: QtProperty[QVariant] enabled:
read = getEnabled read = getEnabled
notify = enabledChanged notify = enabledChanged
proc load*(self: View, networks: seq[NetworkDto]) = proc setItems*(self: View, networks: seq[NetworkDto]) =
var items: seq[Item] = @[] var items: seq[Item] = @[]
let allEnabled = areAllEnabled(networks) let allEnabled = areAllEnabled(networks)
for n in networks: for n in networks:
@ -115,6 +115,8 @@ QtObject:
self.layer2Changed() self.layer2Changed()
self.enabledChanged() self.enabledChanged()
proc load*(self: View, networks: seq[NetworkDto]) =
self.setItems(networks)
self.delegate.viewDidLoad() self.delegate.viewDidLoad()
proc toggleNetwork*(self: View, chainId: int) {.slot.} = proc toggleNetwork*(self: View, chainId: int) {.slot.} =

View File

@ -17,5 +17,5 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
method viewDidLoad*(self: AccessInterface) {.base.} = method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") 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") raise newException(ValueError, "No implementation available")

View File

@ -65,7 +65,7 @@ proc getWalletAccoutColors(self: Module, walletAccounts: seq[WalletAccountDto])
colors.add(account.color) colors.add(account.color)
return colors 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) let walletAccounts = self.controller.getWalletAccountsByAddresses(addresses)
if addresses.len > 1: if addresses.len > 1:
let item = initItem( let item = initItem(
@ -76,7 +76,7 @@ method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int])
"", "",
"", "",
isAllAccounts=true, isAllAccounts=true,
hideWatchAccounts=false, # TODO(alaibe): need update when doing the action hideWatchAccounts=excludeWatchOnly,
self.getWalletAccoutColors(walletAccounts) self.getWalletAccoutColors(walletAccounts)
) )
self.view.setData(item) self.view.setData(item)
@ -90,7 +90,6 @@ method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int])
walletAccount.color, walletAccount.color,
walletAccount.emoji, walletAccount.emoji,
) )
self.view.setData(item) self.view.setData(item)
let walletTokens = self.controller.getWalletTokensByAddresses(addresses) let walletTokens = self.controller.getWalletTokensByAddresses(addresses)

View File

@ -66,6 +66,12 @@ QtObject:
proc setFilterAddress(self: View, address: string) {.slot.} = proc setFilterAddress(self: View, address: string) {.slot.} =
self.delegate.setFilterAddress(address) 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) = proc setTotalCurrencyBalance*(self: View, totalCurrencyBalance: CurrencyAmount) =
self.totalCurrencyBalance = totalCurrencyBalance self.totalCurrencyBalance = totalCurrencyBalance
self.totalCurrencyBalanceChanged() self.totalCurrencyBalanceChanged()

View File

@ -689,9 +689,9 @@ QtObject:
result.balance = 0.0 result.balance = 0.0
result.fetched = false 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 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) 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 = proc getTokenBalanceOnChain*(self: Service, address: string, chainId: int, symbol: string): float64 =

View File

@ -89,7 +89,9 @@ Item {
anchors.fill: parent anchors.fill: parent
changeSelectedAccount: function(address) { changeSelectedAccount: function(address) {
RootStore.setFilterAddress(address) RootStore.setFilterAddress(address)
}
selectAllAccounts: function() {
RootStore.setFillterAllAddresses()
} }
onShowSavedAddressesChanged: { onShowSavedAddressesChanged: {
if(showSavedAddresses) if(showSavedAddresses)

View File

@ -1,3 +1,3 @@
NetworkFilter 1.0 NetworkFilter.qml NetworkFilter 1.0 NetworkFilter.qml
NetworkSelectItemDelegate 1.0 NetworkSelectItemDelegate.qml NetworkSelectItemDelegate 1.0 NetworkSelectItemDelegate.qml
AccountHeaderGradient 1.0 AccountHeaderGradient.qml AccountHeaderGradient 1.0 AccountHeaderGradient.qml

View File

@ -104,7 +104,6 @@ Item {
icon.width: 16 icon.width: 16
icon.color: Theme.palette.baseColor1 icon.color: Theme.palette.baseColor1
// To-do once all accounts view is implemented, filter watch only accounts
onClicked: switchHideWatchOnlyAccounts() onClicked: switchHideWatchOnlyAccounts()
visible: overview.isAllAccounts visible: overview.isAllAccounts
} }

View File

@ -132,6 +132,10 @@ QtObject {
walletSection.setFilterAddress(address) walletSection.setFilterAddress(address)
} }
function setFillterAllAddresses() {
walletSection.setFillterAllAddresses()
}
function deleteAccount(address) { function deleteAccount(address) {
return walletSectionAccounts.deleteAccount(address) return walletSectionAccounts.deleteAccount(address)
} }
@ -208,4 +212,8 @@ QtObject {
function switchReceiveAccount(index) { function switchReceiveAccount(index) {
walletSectionSend.switchReceiveAccount(index) walletSectionSend.switchReceiveAccount(index)
} }
function toggleWatchOnlyAccounts() {
walletSection.toggleWatchOnlyAccounts()
}
} }

View File

@ -27,10 +27,20 @@ Rectangle {
objectName: "walletLeftTab" objectName: "walletLeftTab"
property var networkConnectionStore property var networkConnectionStore
property var selectAllAccounts: function(){}
property var changeSelectedAccount: function(){} property var changeSelectedAccount: function(){}
property bool showSavedAddresses: false property bool showSavedAddresses: false
property bool showAllAccounts: true
onShowSavedAddressesChanged: { 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 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 { StatusListView {
id: walletAccountsListView id: walletAccountsListView
@ -267,8 +223,9 @@ Rectangle {
accountContextMenu.item.popup(mouse.x, mouse.y) accountContextMenu.item.popup(mouse.x, mouse.y)
return return
} }
root.showSavedAddresses = false
root.showAllAccounts = false
changeSelectedAccount(model.address) changeSelectedAccount(model.address)
showSavedAddresses = false
} }
components: [ components: [
StatusIcon { StatusIcon {
@ -321,6 +278,83 @@ Rectangle {
readonly property bool footerOverlayed: contentHeight > availableHeight 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 footerPositioning: footerOverlayed ? ListView.OverlayFooter : ListView.InlineFooter
footer: Control { footer: Control {
id: footer id: footer
@ -374,12 +408,14 @@ Rectangle {
textFillWidth: true textFillWidth: true
spacing: parent.ListView.view.firstItem.statusListItemTitleArea.anchors.leftMargin spacing: parent.ListView.view.firstItem.statusListItemTitleArea.anchors.leftMargin
onClicked: { onClicked: {
showSavedAddresses = true root.showAllAccounts = false
root.showSavedAddresses = true
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
cursorShape: Qt.PointingHandCursor
propagateComposedEvents: true propagateComposedEvents: true
onClicked: { onClicked: {
mouse.accepted = true mouse.accepted = true

View File

@ -60,6 +60,7 @@ Item {
walletStore: RootStore walletStore: RootStore
networkConnectionStore: root.networkConnectionStore networkConnectionStore: root.networkConnectionStore
onLaunchShareAddressModal: root.launchShareAddressModal() onLaunchShareAddressModal: root.launchShareAddressModal()
onSwitchHideWatchOnlyAccounts: RootStore.toggleWatchOnlyAccounts()
} }
StatusTabBar { StatusTabBar {
id: walletTabBar id: walletTabBar