feat(@desktop/wallet): Watch only account toggle + persisted

fixes #11221
This commit is contained in:
Khushboo Mehta 2023-06-26 17:57:16 +02:00 committed by Khushboo-dev-cpp
parent 29d78a99be
commit a2dd87c18b
25 changed files with 126 additions and 54 deletions

View File

@ -48,3 +48,9 @@ proc getKeypairs*(self: Controller): seq[KeypairDto] =
proc getAllKnownKeycardsGroupedByKeyUid*(self: Controller): seq[KeycardDto] =
return self.walletAccountService.getAllKnownKeycardsGroupedByKeyUid()
proc toggleIncludeWatchOnlyAccount*(self: Controller) =
self.walletAccountService.toggleIncludeWatchOnlyAccount()
proc isIncludeWatchOnlyAccount*(self: Controller): bool =
return self.walletAccountService.isIncludeWatchOnlyAccount()

View File

@ -36,3 +36,6 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method toggleIncludeWatchOnlyAccount*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -10,6 +10,7 @@ import ../../../../../core/eventemitter
import ../../../../../../app_service/service/keycard/service as keycard_service
import ../../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../../app_service/service/network/service as network_service
import ../../../../../../app_service/service/settings/service
export io_interface
@ -107,8 +108,12 @@ method load*(self: Module) =
self.events.on(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED) do(e:Args):
self.refreshWalletAccounts()
self.events.on(SIGNAL_INCLUDE_WATCH_ONLY_ACCOUNTS_UPDATED) do(e: Args):
self.view.setIncludeWatchOnlyAccount(self.controller.isIncludeWatchOnlyAccount())
self.controller.init()
self.view.load()
self.view.setIncludeWatchOnlyAccount(self.controller.isIncludeWatchOnlyAccount())
method isLoaded*(self: Module): bool =
return self.moduleLoaded
@ -126,3 +131,6 @@ method updateAccountPosition*(self: Module, address: string, position: int) =
method deleteAccount*(self: Module, address: string) =
self.controller.deleteAccount(address)
method toggleIncludeWatchOnlyAccount*(self: Module) =
self.controller.toggleIncludeWatchOnlyAccount()

View File

@ -12,6 +12,7 @@ QtObject:
accounts: Model
accountsVariant: QVariant
keyPairModel: KeyPairModel
includeWatchOnlyAccount: bool
proc delete*(self: View) =
self.accounts.delete
@ -65,3 +66,17 @@ QtObject:
proc setKeyPairModelItems*(self: View, items: seq[KeyPairItem]) =
self.keyPairModel.setItems(items)
self.keyPairModelChanged()
proc includeWatchOnlyAccountChanged*(self: View) {.signal.}
proc getIncludeWatchOnlyAccount(self: View): bool {.slot.} =
return self.includeWatchOnlyAccount
QtProperty[bool] includeWatchOnlyAccount:
read = getIncludeWatchOnlyAccount
notify = includeWatchOnlyAccountChanged
proc toggleIncludeWatchOnlyAccount*(self: View) {.slot.} =
self.delegate.toggleIncludeWatchOnlyAccount()
proc setIncludeWatchOnlyAccount*(self: View, includeWatchOnlyAccount: bool) =
self.includeWatchOnlyAccount = includeWatchOnlyAccount
self.includeWatchOnlyAccountChanged()

View File

@ -19,7 +19,7 @@ method deleteAccount*(self: AccessInterface, address: string) {.base.} =
method refreshWalletAccounts*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method filterChanged*(self: AccessInterface, addresses: seq[string], chainIds: seq[int], excludeWatchOnly: bool) {.base.} =
method filterChanged*(self: AccessInterface, addresses: seq[string], chainIds: seq[int]) {.base.} =
raise newException(ValueError, "No implementation available")
method updateAccount*(self: AccessInterface, address: string, accountName: string, colorId: string, emoji: string) {.base.} =

View File

@ -42,11 +42,11 @@ method delete*(self: Module) =
self.view.delete
self.controller.delete
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int], excludeWatchOnly: bool) =
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) =
let walletAccounts = self.controller.getWalletAccounts()
let currency = self.controller.getCurrentCurrency()
let currencyFormat = self.controller.getCurrencyFormat(currency)
let items = walletAccounts.filter(w => not excludeWatchOnly or w.walletType != "watch").map(w => (block:
let items = walletAccounts.map(w => (block:
let keycardAccount = self.controller.isKeycardAccount(w)
walletAccountToWalletAccountsItem(
w,

View File

@ -64,4 +64,10 @@ proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAcco
return self.walletAccountService.getWalletAccounts()
proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
proc toggleIncludeWatchOnlyAccount*(self: Controller) =
self.walletAccountService.toggleIncludeWatchOnlyAccount()
proc isIncludeWatchOnlyAccount*(self: Controller): bool =
return self.walletAccountService.isIncludeWatchOnlyAccount()

View File

@ -8,7 +8,6 @@ type Filter* = ref object
activityController: activityc.Controller
addresses*: seq[string]
chainIds*: seq[int]
excludeWatchOnly*: bool
allAddresses*: bool
proc initFilter*(
@ -20,7 +19,6 @@ proc initFilter*(
result.activityController = activityController
result.addresses = @[]
result.chainIds = @[]
result.excludeWatchOnly = false
result.allAddresses = false
proc `$`*(self: Filter): string =
@ -29,7 +27,6 @@ proc `$`*(self: Filter): string =
chainIds: {self.chainIds},
)"""
proc setFillterAllAddresses*(self: Filter) =
self.allAddresses = true
self.addresses = self.controller.getWalletAccounts().map(a => a.address)
@ -37,16 +34,19 @@ proc setFillterAllAddresses*(self: Filter) =
self.activityController.updateFilter()
proc toggleWatchOnlyAccounts*(self: Filter) =
self.excludeWatchOnly = not self.excludeWatchOnly
if self.excludeWatchOnly:
self.controller.toggleIncludeWatchOnlyAccount()
proc includeWatchOnlyToggled*(self: Filter) =
let includeWatchOnly = self.controller.isIncludeWatchOnlyAccount()
if includeWatchOnly:
self.setFillterAllAddresses()
else:
self.addresses = self.controller.getWalletAccounts().filter(a => a.walletType != "watch").map(a => a.address)
self.activityController.setFilterAddresses(self.addresses)
self.activityController.updateFilter()
else:
self.setFillterAllAddresses()
proc load*(self: Filter) =
self.setFillterAllAddresses()
self.includeWatchOnlyToggled()
self.chainIds = self.controller.getEnabledChainIds()
self.activityController.setFilterChains(self.chainIds)
self.activityController.updateFilter()
@ -73,4 +73,4 @@ proc removeAddress*(self: Filter, address: string) =
proc updateNetworks*(self: Filter) =
self.chainIds = self.controller.getEnabledChainIds()
self.activityController.setFilterChains(self.chainIds)
self.activityController.updateFilter()
self.activityController.updateFilter()

View File

@ -132,29 +132,29 @@ method getCurrentCurrency*(self: Module): string =
method setTotalCurrencyBalance*(self: Module) =
var addresses: seq[string] = @[]
let walletAccounts = self.controller.getWalletAccounts()
if self.filter.excludeWatchOnly:
addresses = walletAccounts.filter(a => a.walletType != "watch").map(a => a.address)
else:
if self.controller.isIncludeWatchOnlyAccount():
addresses = walletAccounts.map(a => a.address)
else:
addresses = walletAccounts.filter(a => a.walletType != "watch").map(a => a.address)
self.view.setTotalCurrencyBalance(self.controller.getCurrencyBalance(addresses))
method notifyFilterChanged(self: Module) =
self.overviewModule.filterChanged(self.filter.addresses, self.filter.chainIds, self.filter.excludeWatchOnly, self.filter.allAddresses)
let includeWatchOnly = self.controller.isIncludeWatchOnlyAccount()
self.overviewModule.filterChanged(self.filter.addresses, self.filter.chainIds, includeWatchOnly, self.filter.allAddresses)
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)
self.accountsModule.filterChanged(self.filter.addresses, self.filter.chainIds, self.filter.excludeWatchOnly)
self.accountsModule.filterChanged(self.filter.addresses, self.filter.chainIds)
self.sendModule.filterChanged(self.filter.addresses, self.filter.chainIds)
self.view.filterChanged(self.filter.addresses[0], self.filter.excludeWatchOnly, self.filter.allAddresses)
if self.filter.addresses.len > 0:
self.view.filterChanged(self.filter.addresses[0], includeWatchOnly, self.filter.allAddresses)
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)
@ -202,6 +202,10 @@ method load*(self: Module) =
self.notifyFilterChanged()
self.events.on(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED) do(e:Args):
self.notifyFilterChanged()
self.events.on(SIGNAL_INCLUDE_WATCH_ONLY_ACCOUNTS_UPDATED) do(e: Args):
self.filter.includeWatchOnlyToggled()
self.notifyFilterChanged()
self.setTotalCurrencyBalance()
self.controller.init()
self.view.load()

View File

@ -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], excludeWatchOnly: bool, allAddresses: bool) {.base.} =
method filterChanged*(self: AccessInterface, addresses: seq[string], chainIds: seq[int], includeWatchOnly: bool, allAddresses: bool) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -10,7 +10,7 @@ type
emoji: string
isWatchOnlyAccount: bool
isAllAccounts: bool
hideWatchAccounts: bool
includeWatchOnly: bool
colorIds: seq[string]
proc initItem*(
@ -22,7 +22,7 @@ proc initItem*(
emoji: string,
isWatchOnlyAccount: bool=false,
isAllAccounts: bool = false,
hideWatchAccounts: bool = false,
includeWatchOnly: bool = true,
colorIds: seq[string] = @[]
): Item =
result.name = name
@ -32,7 +32,7 @@ proc initItem*(
result.colorId = colorId
result.emoji = emoji
result.isAllAccounts = isAllAccounts
result.hideWatchAccounts = hideWatchAccounts
result.includeWatchOnly = includeWatchOnly
result.colorIds = colorIds
result.isWatchOnlyAccount = isWatchOnlyAccount
@ -46,7 +46,7 @@ proc `$`*(self: Item): string =
emoji: {self.emoji},
isWatchOnlyAccount: {self.isWatchOnlyAccount},
isAllAccounts: {self.isAllAccounts},
hideWatchAccounts: {self.hideWatchAccounts},
includeWatchOnly: {self.includeWatchOnly},
colorIds: {self.colorIds}
]"""
@ -71,8 +71,8 @@ proc getEmoji*(self: Item): string =
proc getIsAllAccounts*(self: Item): bool =
return self.isAllAccounts
proc getHideWatchAccounts*(self: Item): bool =
return self.hideWatchAccounts
proc getIncludeWatchOnly*(self: Item): bool =
return self.includeWatchOnly
proc getColorIds*(self: Item): string =
return self.colorIds.join(";")

View File

@ -65,7 +65,7 @@ proc getWalletAccoutColors(self: Module, walletAccounts: seq[WalletAccountDto])
colors.add(account.colorId)
return colors
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int], excludeWatchOnly: bool, allAddresses: bool) =
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int], includeWatchOnly: bool, allAddresses: bool) =
let walletAccounts = self.controller.getWalletAccountsByAddresses(addresses)
if allAddresses:
let item = initItem(
@ -77,7 +77,7 @@ method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int],
"",
isWatchOnlyAccount=false,
isAllAccounts=true,
hideWatchAccounts=excludeWatchOnly,
includeWatchOnly=includeWatchOnly,
self.getWalletAccoutColors(walletAccounts)
)
self.view.setData(item)

View File

@ -17,7 +17,7 @@ QtObject:
colorId: string
emoji: string
isAllAccounts: bool
hideWatchAccounts: bool
includeWatchOnly: bool
colorIds: string
isWatchOnlyAccount: bool
@ -99,12 +99,12 @@ QtObject:
read = getIsAllAccounts
notify = isAllAccountsChanged
proc getHideWatchAccounts(self: View): QVariant {.slot.} =
return newQVariant(self.hideWatchAccounts)
proc hideWatchAccountsChanged(self: View) {.signal.}
QtProperty[QVariant] hideWatchAccounts:
read = getHideWatchAccounts
notify = hideWatchAccountsChanged
proc getIncludeWatchOnly(self: View): QVariant {.slot.} =
return newQVariant(self.includeWatchOnly)
proc includeWatchOnlyChanged(self: View) {.signal.}
QtProperty[QVariant] includeWatchOnly:
read = getIncludeWatchOnly
notify = includeWatchOnlyChanged
proc getColorIds(self: View): QVariant {.slot.} =
return newQVariant(self.colorIds)
@ -113,10 +113,10 @@ QtObject:
read = getColorIds
notify = colorIdsChanged
proc getIsWatchOnlyAccount(self: View): QVariant {.slot.} =
return newQVariant(self.isWatchOnlyAccount)
proc getIsWatchOnlyAccount(self: View): bool {.slot.} =
return self.isWatchOnlyAccount
proc isWatchOnlyAccountChanged(self: View) {.signal.}
QtProperty[QVariant] isWatchOnlyAccount:
QtProperty[bool] isWatchOnlyAccount:
read = getIsWatchOnlyAccount
notify = isWatchOnlyAccountChanged
@ -147,6 +147,6 @@ QtObject:
if(self.isAllAccounts != item.getIsAllAccounts()):
self.isAllAccounts = item.getIsAllAccounts()
self.isAllAccountsChanged()
if(self.hideWatchAccounts != item.getHideWatchAccounts()):
self.hideWatchAccounts = item.getHideWatchAccounts()
self.hideWatchAccountsChanged()
if(self.includeWatchOnly != item.getIncludeWatchOnly()):
self.includeWatchOnly = item.getIncludeWatchOnly()
self.includeWatchOnlyChanged()

View File

@ -39,7 +39,7 @@ QtObject:
QtProperty[string] currentCurrency:
read = getCurrentCurrency
proc filterChanged*(self: View, addresses: string, excludeWatchOnly: bool, allAddresses: bool) {.signal.}
proc filterChanged*(self: View, addresses: string, includeWatchOnly: bool, allAddresses: bool) {.signal.}
proc totalCurrencyBalanceChanged*(self: View) {.signal.}

View File

@ -44,6 +44,7 @@ const KEY_GIF_API_KEY* = "gifs/api-key"
const KEY_DISPLAY_NAME* = "display-name"
const KEY_BIO* = "bio"
const KEY_TEST_NETWORKS_ENABLED* = "test-networks-enabled?"
const INCLUDE_WATCH_ONLY_ACCOUNT* = "include-watch-only-account?"
# Notifications Settings Values
const VALUE_NOTIF_SEND_ALERTS* = "SendAlerts"
@ -136,6 +137,7 @@ type
notificationsSoundsEnabled*: bool
notificationsVolume*: int
notificationsMessagePreview*: int
includeWatchOnlyAccount*: bool
proc toPinnedMailserver*(jsonObj: JsonNode): PinnedMailserver =
# we maintain pinned mailserver per fleet
@ -192,6 +194,7 @@ proc toSettingsDto*(jsonObj: JsonNode): SettingsDto =
discard jsonObj.getProp(KEY_GIF_RECENTS, result.gifRecents)
discard jsonObj.getProp(KEY_GIF_FAVORITES, result.gifFavorites)
discard jsonObj.getProp(KEY_TEST_NETWORKS_ENABLED, result.testNetworksEnabled)
discard jsonObj.getProp(INCLUDE_WATCH_ONLY_ACCOUNT, result.includeWatchOnlyAccount)
var pinnedMailserverObj: JsonNode
if(jsonObj.getProp(KEY_PINNED_MAILSERVERS, pinnedMailserverObj)):

View File

@ -27,6 +27,7 @@ const SIGNAL_BIO_UPDATED* = "bioUpdated"
const SIGNAL_MNEMONIC_REMOVED* = "mnemonicRemoved"
const SIGNAL_SOCIAL_LINKS_UPDATED* = "socialLinksUpdated"
const SIGNAL_CURRENT_USER_STATUS_UPDATED* = "currentUserStatusUpdated"
const SIGNAL_INCLUDE_WATCH_ONLY_ACCOUNTS_UPDATED* = "includeWatchOnlyAccounts"
logScope:
topics = "settings-service"
@ -109,6 +110,9 @@ QtObject:
if settingsField.name == KEY_MNEMONIC:
self.settings.mnemonic = ""
self.events.emit(SIGNAL_MNEMONIC_REMOVED, Args())
if settingsField.name == INCLUDE_WATCH_ONLY_ACCOUNT:
self.settings.includeWatchOnlyAccount = parseBool(settingsField.value)
self.events.emit(SIGNAL_INCLUDE_WATCH_ONLY_ACCOUNTS_UPDATED, Args())
if receivedData.socialLinksInfo.links.len > 0 or
receivedData.socialLinksInfo.removed:
@ -966,3 +970,12 @@ QtObject:
data.error = e.msg
error "error saving social links", errDescription=data.error
self.storeSocialLinksAndNotify(data)
proc isIncludeWatchOnlyAccount*(self: Service): bool =
return self.settings.includeWatchOnlyAccount
proc toggleIncludeWatchOnlyAccount*(self: Service) =
let newValue = not self.settings.includeWatchOnlyAccount
if(self.saveSetting(INCLUDE_WATCH_ONLY_ACCOUNT, newValue)):
self.settings.includeWatchOnlyAccount = newValue
self.events.emit(SIGNAL_INCLUDE_WATCH_ONLY_ACCOUNTS_UPDATED, Args())

View File

@ -965,3 +965,9 @@ QtObject:
totalTokenBalance += token.getTotalBalanceOfSupportedChains()
return totalTokenBalance
proc isIncludeWatchOnlyAccount*(self: Service): bool =
return self.settingsService.isIncludeWatchOnlyAccount()
proc toggleIncludeWatchOnlyAccount*(self: Service) =
self.settingsService.toggleIncludeWatchOnlyAccount()

View File

@ -48,7 +48,7 @@ SplitView {
displayDecimals: 4,
stripTrailingZeroes: false}),
isAllAccounts: false,
hideWatchAccounts: false
includeWatchOnly: false
})

View File

@ -56,7 +56,7 @@ SplitView {
displayDecimals: 4,
stripTrailingZeroes: false}),
isAllAccounts: false,
hideWatchAccounts: false
includeWatchOnly: false
})
}
@ -73,7 +73,7 @@ SplitView {
displayDecimals: 4,
stripTrailingZeroes: false}),
isAllAccounts: true,
hideWatchAccounts: true,
includeWatchOnly: true,
colorIds: "purple;pink;magenta"
})

View File

@ -13,8 +13,10 @@ Rectangle {
property string chainShortNames
property string userProfilePublicKey
property bool includeWatchOnlyAccount
signal goToAccountView(var account)
signal toggleIncludeWatchOnlyAccount()
QtObject {
id: d
@ -68,9 +70,8 @@ Rectangle {
},
StatusSwitch {
visible: d.isWatchOnly
// To-do connect in different task
// checked: false
// onCheckedChanged: {}
checked: root.includeWatchOnlyAccount
onClicked: root.toggleIncludeWatchOnlyAccount()
}
]
}

View File

@ -23,6 +23,11 @@ QtObject {
property var assets: walletSectionAssets.assets
property var accounts: Global.appIsReady? accountsModule.accounts : null
property var originModel: accountsModule.keyPairModel
property bool includeWatchOnlyAccount: accountsModule.includeWatchOnlyAccount
function toggleIncludeWatchOnlyAccount() {
accountsModule.toggleIncludeWatchOnlyAccount()
}
property string userProfilePublicKey: userProfile.pubKey

View File

@ -95,7 +95,9 @@ Column {
width: parent.width
chainShortNames: walletStore.getAllNetworksSupportedPrefix()
userProfilePublicKey: walletStore.userProfilePublicKey
includeWatchOnlyAccount: walletStore.includeWatchOnlyAccount
onGoToAccountView: root.goToAccountView(account)
onToggleIncludeWatchOnlyAccount: walletStore.toggleIncludeWatchOnlyAccount()
}
}
}

View File

@ -96,9 +96,9 @@ Item {
font.weight: Font.Normal
textColor: Theme.palette.baseColor1
text: overview.hideWatchAccounts ? qsTr("Show watch-only"): qsTr("Hide watch-only")
text: overview.includeWatchOnly ? qsTr("Hide watch-only"): qsTr("Show watch-only")
icon.name: overview.hideWatchAccounts ? "show" : "hide"
icon.name: overview.includeWatchOnly ? "hide" : "show"
icon.height: 16
icon.width: 16
icon.color: Theme.palette.baseColor1

View File

@ -125,7 +125,7 @@ Rectangle {
function onDestroyAddAccountPopup() {
addAccount.active = false
}
function onFilterChanged(address, excludeWatchOnly, allAddresses) {
function onFilterChanged(address, includeWatchOnly, allAddresses) {
root.currentAddress = allAddresses ? "" : address
root.showAllAccounts = allAddresses
}

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit f07a79cd189964e31f67ecb8b90036fb1ffeec5e
Subproject commit bada9fee11eee132f5bcf535d66b7c9311e1a8e6