feat(@wallet): Sort account by position

This commit is contained in:
Anthony Laibe 2023-06-20 12:59:15 +01:00
parent a5ba253730
commit 31aca3ac35
19 changed files with 198 additions and 7 deletions

View File

@ -28,6 +28,9 @@ proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAcco
proc updateAccount*(self: Controller, address: string, accountName: string, colorId: string, emoji: string) =
discard self.walletAccountService.updateWalletAccount(address, accountName, colorId, emoji)
proc updateAccountPosition*(self: Controller, address: string, position: int) =
self.walletAccountService.updateWalletAccountPosition(address, position)
proc deleteAccount*(self: Controller, address: string) =
self.walletAccountService.deleteAccount(address)

View File

@ -25,6 +25,9 @@ method refreshWalletAccounts*(self: AccessInterface) {.base.} =
method updateAccount*(self: AccessInterface, address: string, accountName: string, colorId: string, emoji: string) {.base.} =
raise newException(ValueError, "No implementation available")
method updateAccountPosition*(self: AccessInterface, address: string, position: int) {.base.} =
raise newException(ValueError, "No implementation available")
# View Delegate Interface
# Delegate for the view must be declared here due to use of QtObject and multi
# inheritance, which is not well supported in Nim.

View File

@ -6,6 +6,7 @@ export wallet_account_item
type
Item* = ref object of WalletAccountItem
position: int
relatedAccounts: related_accounts_model.Model
proc initItem*(
@ -17,7 +18,8 @@ proc initItem*(
emoji: string = "",
relatedAccounts: related_accounts_model.Model = nil,
keyUid: string = "",
keycardAccount: bool = false
keycardAccount: bool = false,
position: int = 0,
): Item =
result = Item()
result.WalletAccountItem.setup(name,
@ -28,6 +30,7 @@ proc initItem*(
path,
keyUid,
keycardAccount)
result.position = position
result.relatedAccounts = relatedAccounts
proc `$`*(self: Item): string =
@ -38,3 +41,6 @@ proc `$`*(self: Item): string =
proc relatedAccounts*(self: Item): related_accounts_model.Model =
return self.relatedAccounts
proc position*(self: Item): int =
return self.position

View File

@ -11,6 +11,7 @@ type
Emoji,
RelatedAccounts,
KeyUid,
Position,
QtObject:
type
@ -54,6 +55,7 @@ QtObject:
ModelRole.Emoji.int: "emoji",
ModelRole.RelatedAccounts.int: "relatedAccounts",
ModelRole.KeyUid.int: "keyUid",
ModelRole.Position.int: "position",
}.toTable
@ -104,3 +106,5 @@ QtObject:
result = newQVariant(item.relatedAccounts())
of ModelRole.KeyUid:
result = newQVariant(item.keyUid())
of ModelRole.Position:
result = newQVariant(item.position())

View File

@ -104,6 +104,9 @@ method load*(self: Module) =
return
self.refreshWalletAccounts()
self.events.on(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.controller.init()
self.view.load()
@ -118,5 +121,8 @@ method viewDidLoad*(self: Module) =
method updateAccount*(self: Module, address: string, accountName: string, colorId: string, emoji: string) =
self.controller.updateAccount(address, accountName, colorId, emoji)
method updateAccountPosition*(self: Module, address: string, position: int) =
self.controller.updateAccountPosition(address, position)
method deleteAccount*(self: Module, address: string) =
self.controller.deleteAccount(address)

View File

@ -45,6 +45,9 @@ QtObject:
proc updateAccount(self: View, address: string, accountName: string, colorId: string, emoji: string) {.slot.} =
self.delegate.updateAccount(address, accountName, colorId, emoji)
proc updateAccountPosition(self: View, address: string, position: int) {.slot.} =
self.delegate.updateAccountPosition(address, position)
proc onUpdatedAccount*(self: View, account: Item) =
self.accounts.onUpdatedAccount(account)
self.keyPairModel.onUpdatedAccount(account.keyUid, account.address, account.name, account.colorId, account.emoji)

View File

@ -6,6 +6,7 @@ export wallet_account_item
type
Item* = ref object of WalletAccountItem
position: int
createdAt: int
assetsLoading: bool
currencyBalance: CurrencyAmount
@ -20,6 +21,7 @@ proc initItem*(
emoji: string = "",
keyUid: string = "",
createdAt: int = 0,
position: int = 0,
keycardAccount: bool = false,
assetsLoading: bool = true,
): Item =
@ -33,6 +35,7 @@ proc initItem*(
keyUid,
keycardAccount)
result.createdAt = createdAt
result.position = position
result.assetsLoading = assetsLoading
result.currencyBalance = currencyBalance
@ -51,3 +54,6 @@ proc assetsLoading*(self: Item): bool =
proc createdAt*(self: Item): int =
return self.createdAt
proc position*(self: Item): int =
return self.position

View File

@ -15,6 +15,7 @@ type
Emoji,
KeyUid,
CreatedAt,
Position,
KeycardAccount,
AssetsLoading,
@ -62,6 +63,7 @@ QtObject:
ModelRole.Emoji.int: "emoji",
ModelRole.KeyUid.int: "keyUid",
ModelRole.CreatedAt.int: "createdAt",
ModelRole.Position.int: "position",
ModelRole.KeycardAccount.int: "keycardAccount",
ModelRole.AssetsLoading.int: "assetsLoading",
}.toTable
@ -105,6 +107,8 @@ QtObject:
result = newQVariant(item.keyUid())
of ModelRole.CreatedAt:
result = newQVariant(item.createdAt())
of ModelRole.Position:
result = newQVariant(item.position())
of ModelRole.KeycardAccount:
result = newQVariant(item.keycardAccount())
of ModelRole.AssetsLoading:

View File

@ -200,6 +200,8 @@ method load*(self: Module) =
if not args.success:
return
self.notifyFilterChanged()
self.events.on(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED) do(e:Args):
self.notifyFilterChanged()
self.controller.init()
self.view.load()

View File

@ -50,7 +50,8 @@ proc walletAccountToWalletSettingsAccountsItem*(w: WalletAccountDto, keycardAcco
w.emoji,
relatedAccounts,
w.keyUid,
keycardAccount
keycardAccount,
w.position,
)
proc walletAccountToWalletAccountsItem*(w: WalletAccountDto, keycardAccount: bool, enabledChainIds: seq[int], currency: string,
@ -65,6 +66,7 @@ proc walletAccountToWalletAccountsItem*(w: WalletAccountDto, keycardAccount: boo
w.emoji,
w.keyUid,
w.createdAt,
w.position,
keycardAccount,
w.assetsLoading,
)

View File

@ -108,6 +108,7 @@ type
removed*: bool # needs for synchronization
operable*: string
createdAt*: int
position*: int
proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
result = WalletAccountDto()
@ -126,6 +127,7 @@ proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
discard jsonObj.getProp("removed", result.removed)
discard jsonObj.getProp("operable", result.operable)
discard jsonObj.getProp("createdAt", result.createdAt)
discard jsonObj.getProp("position", result.position)
result.assetsLoading = true
result.hasBalanceCache = false
result.hasMarketValuesCache = false

View File

@ -33,6 +33,7 @@ const SIGNAL_WALLET_ACCOUNT_TOKENS_BEING_FETCHED* = "walletAccount/tokenFetching
const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESSES_FETCHED* = "walletAccount/derivedAddressesFetched"
const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESSES_FROM_MNEMONIC_FETCHED* = "walletAccount/derivedAddressesFromMnemonicFetched"
const SIGNAL_WALLET_ACCOUNT_ADDRESS_DETAILS_FETCHED* = "walletAccount/addressDetailsFetched"
const SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED* = "walletAccount/positionUpdated"
const SIGNAL_KEYCARDS_SYNCHRONIZED* = "keycardsSynchronized"
const SIGNAL_NEW_KEYCARD_SET* = "newKeycardSet"
@ -549,7 +550,14 @@ QtObject:
error "error: ", procName="updateWalletAccount", errName=e.name, errDesription=e.msg
return false
proc fetchDerivedAddresses*(self: Service, password: string, derivedFrom: string, paths: seq[string], hashPassword: bool)=
proc updateWalletAccountPosition*(self: Service, address: string, position: int) =
discard backend.updateAccountPosition(address, position)
for account in self.getAccounts():
self.walletAccounts[account.address].position = account.position
self.events.emit(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED, Args())
proc fetchDerivedAddresses*(self: Service, password: string, derivedFrom: string, paths: seq[string], hashPassword: bool) =
let arg = FetchDerivedAddressesTaskArg(
password: if hashPassword: utils.hashPassword(password) else: password,
derivedFrom: derivedFrom,

View File

@ -258,6 +258,10 @@ rpc(updateKeycardUID, "accounts"):
rpc(deleteKeycard, "accounts"):
keycardUid: string
rpc(updateAccountPosition, "accounts"):
address: string
position: int
rpc(getHourlyMarketValues, "wallet"):
symbol: string
currency: string

View File

@ -34,6 +34,10 @@ QtObject {
return accountsModule.updateAccount(address, accountName, colorId, emoji)
}
function updateAccountPosition(address, position) {
return accountsModule.updateAccountPosition(address, position)
}
property var dappList: Global.appIsReady? dappPermissionsModule.dapps : null
function disconnect(dappName) {

View File

@ -25,8 +25,9 @@ SettingsContentBase {
readonly property int mainViewIndex: 0;
readonly property int networksViewIndex: 1;
readonly property int accountViewIndex: 2;
readonly property int dappPermissionViewIndex: 3;
readonly property int accountOrderViewIndex: 2;
readonly property int accountViewIndex: 3;
readonly property int dappPermissionViewIndex: 4;
function resetStack() {
stackContainer.currentIndex = mainViewIndex;
@ -57,6 +58,10 @@ SettingsContentBase {
root.rootStore.backButtonName = qsTr("Wallet")
root.sectionTitle = qsTr("DApp Permissions")
}
else if(currentIndex == root.accountOrderViewIndex) {
root.rootStore.backButtonName = qsTr("Wallet")
root.sectionTitle = qsTr("Edit account order")
}
}
MainView {
@ -75,6 +80,10 @@ SettingsContentBase {
stackContainer.currentIndex = accountViewIndex
}
onGoToAccountOrderView: {
stackContainer.currentIndex = accountOrderViewIndex
}
onGoToDappPermissionsView: {
stackContainer.currentIndex = dappPermissionViewIndex
}
@ -88,6 +97,13 @@ SettingsContentBase {
}
}
AccountOrderView {
walletStore: root.walletStore
onGoBack: {
stackContainer.currentIndex = mainViewIndex
}
}
AccountView {
id: accountView
walletStore: root.walletStore

View File

@ -0,0 +1,101 @@
import QtQuick 2.15
import SortFilterProxyModel 0.2
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import shared.status 1.0
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
import "../../stores"
import "../../controls"
StatusListView {
id: accountsView
signal goBack
property WalletStore walletStore
header: StatusBaseText {
text: qsTr("Move your most freqently used accounts to the top of your wallet list")
color: Theme.palette.baseColor1
font.pixelSize: Style.current.primaryTextFontSize
bottomPadding: Style.current.padding
}
anchors.top: parent.top
anchors.left: parent.left
width: parent.width
anchors.leftMargin: Style.current.padding
anchors.rightMargin: Style.current.padding
model: SortFilterProxyModel {
sourceModel: walletStore.accounts
sorters: [
RoleSorter {
roleName: "position"
priority: 2
}
]
}
displaced: Transition {
NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }
}
delegate: DropArea {
id: delegateRoot
property int visualIndex: index
width: ListView.view.width
height: draggableDelegate.height
keys: ["x-status-draggable-list-item-internal"]
onEntered: function(drag) {
const from = drag.source.visualIndex
const to = draggableDelegate.visualIndex
if (to === from)
return
drag.accept()
}
onDropped: function(drop) {
walletStore.updateAccountPosition(drop.source.address, draggableDelegate.position)
drop.accept()
}
StatusDraggableListItem {
id: draggableDelegate
property int position: model.position
property string address: model.address
width: parent.width
height: implicitHeight
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
dragParent: accountsView
visualIndex: delegateRoot.visualIndex
draggable: accountsView.count > 1
title: {
console.log(model.name, model.position)
return model.name
}
secondaryTitle: model.address
hasEmoji: true
icon.width: 40
icon.height: 40
icon.name: model.emoji
icon.color: Utils.getColorForId(model.colorId)
actions: []
}
}
}

View File

@ -18,6 +18,7 @@ Column {
property WalletStore walletStore
signal goToNetworksView()
signal goToAccountOrderView()
signal goToAccountView(var account)
signal goToDappPermissionsView()
@ -63,6 +64,22 @@ Column {
Separator {}
StatusListItem {
objectName: "accountOrderItem"
title: qsTr("Account order")
height: 64
width: parent.width
onClicked: goToAccountOrderView()
components: [
StatusIcon {
icon: "next"
color: Theme.palette.baseColor1
}
]
}
Separator {}
Item {
width: parent.width
height: 8

View File

@ -426,7 +426,7 @@ Rectangle {
model: SortFilterProxyModel {
sourceModel: RootStore.accounts
sorters: RoleSorter { roleName: "createdAt"; sortOrder: Qt.AscendingOrder }
sorters: RoleSorter { roleName: "position"; sortOrder: Qt.AscendingOrder }
}
}

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 3e7d1a5f34183ea9f2ebf3b3d6a8143c98674d62
Subproject commit da2f155f2df52d689d400bffc11e67b463ddcac9