feat:(@wallet): create wallet section in profile
Separate wallet module from profile wallet module 1 - they caused us many conflict regarding current 2 - better decoupling
This commit is contained in:
parent
fb8ea4a054
commit
4e5f7763db
|
@ -93,4 +93,13 @@ method communitiesModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getKeycardModule*(self: AccessInterface): QVariant {.base.} =
|
method getKeycardModule*(self: AccessInterface): QVariant {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method walletModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getWalletAccountsModule*(self: AccessInterface): QVariant {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getWalletNetworksModule*(self: AccessInterface): QVariant {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
|
@ -37,6 +37,7 @@ import ./notifications/module as notifications_module
|
||||||
import ./ens_usernames/module as ens_usernames_module
|
import ./ens_usernames/module as ens_usernames_module
|
||||||
import ./communities/module as communities_module
|
import ./communities/module as communities_module
|
||||||
import ./keycard/module as keycard_module
|
import ./keycard/module as keycard_module
|
||||||
|
import ./wallet/module as wallet_module
|
||||||
|
|
||||||
export io_interface
|
export io_interface
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ type
|
||||||
ensUsernamesModule: ens_usernames_module.AccessInterface
|
ensUsernamesModule: ens_usernames_module.AccessInterface
|
||||||
communitiesModule: communities_module.AccessInterface
|
communitiesModule: communities_module.AccessInterface
|
||||||
keycardModule: keycard_module.AccessInterface
|
keycardModule: keycard_module.AccessInterface
|
||||||
|
walletModule: wallet_module.AccessInterface
|
||||||
|
|
||||||
proc newModule*(delegate: delegate_interface.AccessInterface,
|
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||||
events: EventEmitter,
|
events: EventEmitter,
|
||||||
|
@ -109,6 +111,8 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||||
result.keycardModule = keycard_module.newModule(result, events, keycardService, settingsService, networkService,
|
result.keycardModule = keycard_module.newModule(result, events, keycardService, settingsService, networkService,
|
||||||
privacyService, accountsService, walletAccountService, keychainService)
|
privacyService, accountsService, walletAccountService, keychainService)
|
||||||
|
|
||||||
|
result.walletModule = wallet_module.newModule(result, events, walletAccountService, settingsService, networkService)
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
|
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
|
||||||
|
|
||||||
method delete*(self: Module) =
|
method delete*(self: Module) =
|
||||||
|
@ -143,6 +147,7 @@ method load*(self: Module) =
|
||||||
self.ensUsernamesModule.load()
|
self.ensUsernamesModule.load()
|
||||||
self.communitiesModule.load()
|
self.communitiesModule.load()
|
||||||
self.keycardModule.load()
|
self.keycardModule.load()
|
||||||
|
self.walletModule.load()
|
||||||
|
|
||||||
method isLoaded*(self: Module): bool =
|
method isLoaded*(self: Module): bool =
|
||||||
return self.moduleLoaded
|
return self.moduleLoaded
|
||||||
|
@ -187,6 +192,9 @@ proc checkIfModuleDidLoad(self: Module) =
|
||||||
if(not self.keycardModule.isLoaded()):
|
if(not self.keycardModule.isLoaded()):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(not self.walletModule.isLoaded()):
|
||||||
|
return
|
||||||
|
|
||||||
self.moduleLoaded = true
|
self.moduleLoaded = true
|
||||||
self.delegate.profileSectionDidLoad()
|
self.delegate.profileSectionDidLoad()
|
||||||
|
|
||||||
|
@ -263,4 +271,13 @@ method communitiesModuleDidLoad*(self: Module) =
|
||||||
self.checkIfModuleDidLoad()
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
method getKeycardModule*(self: Module): QVariant =
|
method getKeycardModule*(self: Module): QVariant =
|
||||||
self.keycardModule.getModuleAsVariant()
|
self.keycardModule.getModuleAsVariant()
|
||||||
|
|
||||||
|
method walletModuleDidLoad*(self: Module) =
|
||||||
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method getWalletAccountsModule*(self: Module): QVariant =
|
||||||
|
return self.walletModule.getAccountsModuleAsVariant()
|
||||||
|
|
||||||
|
method getWalletNetworksModule*(self: Module): QVariant =
|
||||||
|
return self.walletModule.getNetworksModuleAsVariant()
|
|
@ -80,3 +80,13 @@ QtObject:
|
||||||
return self.delegate.getKeycardModule()
|
return self.delegate.getKeycardModule()
|
||||||
QtProperty[QVariant] keycardModule:
|
QtProperty[QVariant] keycardModule:
|
||||||
read = getKeycardModule
|
read = getKeycardModule
|
||||||
|
|
||||||
|
proc getWalletAccountsModule(self: View): QVariant {.slot.} =
|
||||||
|
return self.delegate.getWalletAccountsModule()
|
||||||
|
QtProperty[QVariant] walletAccountsModule:
|
||||||
|
read = getWalletAccountsModule
|
||||||
|
|
||||||
|
proc getWalletNetworksModule(self: View): QVariant {.slot.} =
|
||||||
|
return self.delegate.getWalletNetworksModule()
|
||||||
|
QtProperty[QVariant] walletNetworksModule:
|
||||||
|
read = getWalletNetworksModule
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
import sugar, sequtils, tables
|
||||||
|
import io_interface
|
||||||
|
import ../../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||||
|
import ../../../../../../app_service/service/network/service as network_service
|
||||||
|
|
||||||
|
import ../../../../../global/global_singleton
|
||||||
|
import ../../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
|
||||||
|
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
|
||||||
|
const UNIQUE_PROFILE_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER* = "ProfileSection-AccountsModule-Authentication"
|
||||||
|
|
||||||
|
type
|
||||||
|
Controller* = ref object of RootObj
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
events: EventEmitter
|
||||||
|
walletAccountService: wallet_account_service.Service
|
||||||
|
|
||||||
|
proc newController*(
|
||||||
|
delegate: io_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
walletAccountService: wallet_account_service.Service,
|
||||||
|
): Controller =
|
||||||
|
result = Controller()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
|
result.walletAccountService = walletAccountService
|
||||||
|
|
||||||
|
proc delete*(self: Controller) =
|
||||||
|
discard
|
||||||
|
|
||||||
|
proc init*(self: Controller) =
|
||||||
|
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
||||||
|
let args = SharedKeycarModuleArgs(e)
|
||||||
|
if args.uniqueIdentifier != UNIQUE_PROFILE_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER:
|
||||||
|
return
|
||||||
|
self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid)
|
||||||
|
|
||||||
|
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
||||||
|
return self.walletAccountService.getWalletAccounts()
|
||||||
|
|
||||||
|
proc updateAccount*(self: Controller, address: string, accountName: string, color: string, emoji: string) =
|
||||||
|
discard self.walletAccountService.updateWalletAccount(address, accountName, color, emoji)
|
||||||
|
|
||||||
|
proc deleteAccount*(self: Controller, address: string, password = "", doPasswordHashing = false) =
|
||||||
|
self.walletAccountService.deleteAccount(address, password, doPasswordHashing)
|
||||||
|
|
||||||
|
proc authenticateKeyPair*(self: Controller, keyUid = "") =
|
||||||
|
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_PROFILE_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER,
|
||||||
|
keyUid: keyUid)
|
||||||
|
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
||||||
|
|
||||||
|
proc getMigratedKeyPairByKeyUid*(self: Controller, keyUid: string): seq[KeyPairDto] =
|
||||||
|
return self.walletAccountService.getMigratedKeyPairByKeyUid(keyUid)
|
||||||
|
|
||||||
|
proc getWalletAccount*(self: Controller, address: string): WalletAccountDto =
|
||||||
|
return self.walletAccountService.getAccountByAddress(address)
|
|
@ -0,0 +1,41 @@
|
||||||
|
import NimQml
|
||||||
|
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
## Abstract class for any input/interaction with this module.
|
||||||
|
|
||||||
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method load*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method syncKeycard*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method deleteAccount*(self: AccessInterface, keyUid: string, address: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method refreshWalletAccounts*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method updateAccount*(self: AccessInterface, address: string, accountName: string, color: string, emoji: string) {.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.
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method authenticateUser*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,68 @@
|
||||||
|
import strformat
|
||||||
|
import ./related_accounts_model as related_accounts_model
|
||||||
|
|
||||||
|
type
|
||||||
|
Item* = object
|
||||||
|
name*: string
|
||||||
|
address: string
|
||||||
|
color*: string
|
||||||
|
emoji*: string
|
||||||
|
walletType: string
|
||||||
|
path: string
|
||||||
|
relatedAccounts: related_accounts_model.Model
|
||||||
|
keyUid: string
|
||||||
|
|
||||||
|
proc initItem*(
|
||||||
|
name: string = "",
|
||||||
|
address: string = "",
|
||||||
|
path: string = "",
|
||||||
|
color: string = "",
|
||||||
|
walletType: string = "",
|
||||||
|
emoji: string = "",
|
||||||
|
relatedAccounts: related_accounts_model.Model = nil,
|
||||||
|
keyUid: string = "",
|
||||||
|
): Item =
|
||||||
|
result.name = name
|
||||||
|
result.address = address
|
||||||
|
result.path = path
|
||||||
|
result.color = color
|
||||||
|
result.walletType = walletType
|
||||||
|
result.emoji = emoji
|
||||||
|
result.relatedAccounts = relatedAccounts
|
||||||
|
result.keyUid = keyUid
|
||||||
|
|
||||||
|
proc `$`*(self: Item): string =
|
||||||
|
result = fmt"""WalletAccountItem(
|
||||||
|
name: {self.name},
|
||||||
|
address: {self.address},
|
||||||
|
path: {self.path},
|
||||||
|
color: {self.color},
|
||||||
|
walletType: {self.walletType},
|
||||||
|
emoji: {self.emoji},
|
||||||
|
relatedAccounts: {self.relatedAccounts}
|
||||||
|
keyUid: {self.keyUid},
|
||||||
|
]"""
|
||||||
|
|
||||||
|
proc getName*(self: Item): string =
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
proc getAddress*(self: Item): string =
|
||||||
|
return self.address
|
||||||
|
|
||||||
|
proc getPath*(self: Item): string =
|
||||||
|
return self.path
|
||||||
|
|
||||||
|
proc getEmoji*(self: Item): string =
|
||||||
|
return self.emoji
|
||||||
|
|
||||||
|
proc getColor*(self: Item): string =
|
||||||
|
return self.color
|
||||||
|
|
||||||
|
proc getWalletType*(self: Item): string =
|
||||||
|
return self.walletType
|
||||||
|
|
||||||
|
proc getRelatedAccounts*(self: Item): related_accounts_model.Model =
|
||||||
|
return self.relatedAccounts
|
||||||
|
|
||||||
|
proc getKeyUid*(self: Item): string =
|
||||||
|
return self.keyUid
|
|
@ -0,0 +1,106 @@
|
||||||
|
import NimQml, Tables, strutils, strformat
|
||||||
|
import ./item
|
||||||
|
|
||||||
|
type
|
||||||
|
ModelRole {.pure.} = enum
|
||||||
|
Name = UserRole + 1,
|
||||||
|
Address,
|
||||||
|
Path,
|
||||||
|
Color,
|
||||||
|
WalletType,
|
||||||
|
Emoji,
|
||||||
|
RelatedAccounts,
|
||||||
|
KeyUid,
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
Model* = ref object of QAbstractListModel
|
||||||
|
items: seq[Item]
|
||||||
|
|
||||||
|
proc delete(self: Model) =
|
||||||
|
self.items = @[]
|
||||||
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc setup(self: Model) =
|
||||||
|
self.QAbstractListModel.setup
|
||||||
|
|
||||||
|
proc newModel*(): Model =
|
||||||
|
new(result, delete)
|
||||||
|
result.setup
|
||||||
|
|
||||||
|
proc `$`*(self: Model): string =
|
||||||
|
for i in 0 ..< self.items.len:
|
||||||
|
result &= fmt"""[{i}]:({$self.items[i]})"""
|
||||||
|
|
||||||
|
proc countChanged(self: Model) {.signal.}
|
||||||
|
|
||||||
|
proc getCount*(self: Model): int {.slot.} =
|
||||||
|
self.items.len
|
||||||
|
|
||||||
|
QtProperty[int] count:
|
||||||
|
read = getCount
|
||||||
|
notify = countChanged
|
||||||
|
|
||||||
|
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||||
|
return self.items.len
|
||||||
|
|
||||||
|
method roleNames(self: Model): Table[int, string] =
|
||||||
|
{
|
||||||
|
ModelRole.Name.int:"name",
|
||||||
|
ModelRole.Address.int:"address",
|
||||||
|
ModelRole.Path.int:"path",
|
||||||
|
ModelRole.Color.int:"color",
|
||||||
|
ModelRole.WalletType.int:"walletType",
|
||||||
|
ModelRole.Emoji.int: "emoji",
|
||||||
|
ModelRole.RelatedAccounts.int: "relatedAccounts",
|
||||||
|
ModelRole.KeyUid.int: "keyUid",
|
||||||
|
}.toTable
|
||||||
|
|
||||||
|
|
||||||
|
proc setItems*(self: Model, items: seq[Item]) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.items = items
|
||||||
|
self.endResetModel()
|
||||||
|
self.countChanged()
|
||||||
|
|
||||||
|
proc onUpdatedAccount*(self: Model, account: Item) =
|
||||||
|
var i = 0
|
||||||
|
for item in self.items.mitems:
|
||||||
|
if account.getAddress() == item.getAddress():
|
||||||
|
item.name = account.name
|
||||||
|
item.color = account.color
|
||||||
|
item.emoji = account.emoji
|
||||||
|
let index = self.createIndex(i, 0, nil)
|
||||||
|
self.dataChanged(index, index, @[ModelRole.Name.int])
|
||||||
|
self.dataChanged(index, index, @[ModelRole.Color.int])
|
||||||
|
self.dataChanged(index, index, @[ModelRole.Emoji.int])
|
||||||
|
break
|
||||||
|
i.inc
|
||||||
|
|
||||||
|
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||||
|
if (not index.isValid):
|
||||||
|
return
|
||||||
|
|
||||||
|
if (index.row < 0 or index.row >= self.items.len):
|
||||||
|
return
|
||||||
|
|
||||||
|
let item = self.items[index.row]
|
||||||
|
let enumRole = role.ModelRole
|
||||||
|
|
||||||
|
case enumRole:
|
||||||
|
of ModelRole.Name:
|
||||||
|
result = newQVariant(item.getName())
|
||||||
|
of ModelRole.Address:
|
||||||
|
result = newQVariant(item.getAddress())
|
||||||
|
of ModelRole.Path:
|
||||||
|
result = newQVariant(item.getPath())
|
||||||
|
of ModelRole.Color:
|
||||||
|
result = newQVariant(item.getColor())
|
||||||
|
of ModelRole.WalletType:
|
||||||
|
result = newQVariant(item.getWalletType())
|
||||||
|
of ModelRole.Emoji:
|
||||||
|
result = newQVariant(item.getEmoji())
|
||||||
|
of ModelRole.RelatedAccounts:
|
||||||
|
result = newQVariant(item.getRelatedAccounts())
|
||||||
|
of ModelRole.KeyUid:
|
||||||
|
result = newQVariant(item.getKeyUid())
|
|
@ -0,0 +1,136 @@
|
||||||
|
import tables, NimQml, sequtils, sugar, chronicles
|
||||||
|
|
||||||
|
import ./io_interface, ./view, ./item, ./controller, ./utils
|
||||||
|
import ../io_interface as delegate_interface
|
||||||
|
import ../../../../../global/global_singleton
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
import ../../../../../../app_service/common/account_constants
|
||||||
|
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 ../../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
|
||||||
|
|
||||||
|
export io_interface
|
||||||
|
|
||||||
|
# TODO: remove it completely if after wallet settings part refactore this is not needed.
|
||||||
|
type
|
||||||
|
AuthenticationReason {.pure.} = enum
|
||||||
|
DeleteAccountAuthentication = 0
|
||||||
|
|
||||||
|
# TODO: remove it completely if after wallet settings part refactore this is not needed.
|
||||||
|
type WalletAccountDetails = object
|
||||||
|
address: string
|
||||||
|
path: string
|
||||||
|
addressAccountIsDerivedFrom: string
|
||||||
|
publicKey: string
|
||||||
|
keyUid: string
|
||||||
|
|
||||||
|
type
|
||||||
|
Module* = ref object of io_interface.AccessInterface
|
||||||
|
delegate: delegate_interface.AccessInterface
|
||||||
|
events: EventEmitter
|
||||||
|
view: View
|
||||||
|
viewVariant: QVariant
|
||||||
|
controller: Controller
|
||||||
|
moduleLoaded: bool
|
||||||
|
walletAccountService: wallet_account_service.Service
|
||||||
|
processingWalletAccount: WalletAccountDetails
|
||||||
|
authentiactionReason: AuthenticationReason
|
||||||
|
|
||||||
|
proc newModule*(
|
||||||
|
delegate: delegate_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
walletAccountService: wallet_account_service.Service,
|
||||||
|
networkService: network_service.Service,
|
||||||
|
): Module =
|
||||||
|
result = Module()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
|
result.walletAccountService = walletAccountService
|
||||||
|
result.view = newView(result)
|
||||||
|
result.viewVariant = newQVariant(result.view)
|
||||||
|
result.controller = controller.newController(result, events, walletAccountService)
|
||||||
|
result.moduleLoaded = false
|
||||||
|
result.authentiactionReason = AuthenticationReason.DeleteAccountAuthentication
|
||||||
|
|
||||||
|
method delete*(self: Module) =
|
||||||
|
self.view.delete
|
||||||
|
self.viewVariant.delete
|
||||||
|
self.controller.delete
|
||||||
|
|
||||||
|
method getModuleAsVariant*(self: Module): QVariant =
|
||||||
|
return self.viewVariant
|
||||||
|
|
||||||
|
method refreshWalletAccounts*(self: Module) =
|
||||||
|
let walletAccounts = self.controller.getWalletAccounts()
|
||||||
|
|
||||||
|
let items = walletAccounts.map(w => (block:
|
||||||
|
walletAccountToItem(w)
|
||||||
|
))
|
||||||
|
|
||||||
|
self.view.setItems(items)
|
||||||
|
|
||||||
|
method load*(self: Module) =
|
||||||
|
self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e:Args):
|
||||||
|
self.refreshWalletAccounts()
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||||
|
self.refreshWalletAccounts()
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_WALLET_ACCOUNT_UPDATED) do(e:Args):
|
||||||
|
let args = WalletAccountUpdated(e)
|
||||||
|
self.view.onUpdatedAccount(walletAccountToItem(args.account))
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
||||||
|
let args = KeycardActivityArgs(e)
|
||||||
|
if not args.success:
|
||||||
|
return
|
||||||
|
self.refreshWalletAccounts()
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_KEYCARDS_SYNCHRONIZED) do(e: Args):
|
||||||
|
let args = KeycardActivityArgs(e)
|
||||||
|
if not args.success:
|
||||||
|
return
|
||||||
|
self.refreshWalletAccounts()
|
||||||
|
|
||||||
|
self.controller.init()
|
||||||
|
self.view.load()
|
||||||
|
|
||||||
|
method isLoaded*(self: Module): bool =
|
||||||
|
return self.moduleLoaded
|
||||||
|
|
||||||
|
method viewDidLoad*(self: Module) =
|
||||||
|
self.refreshWalletAccounts()
|
||||||
|
self.moduleLoaded = true
|
||||||
|
self.delegate.accountsModuleDidLoad()
|
||||||
|
|
||||||
|
method updateAccount*(self: Module, address: string, accountName: string, color: string, emoji: string) =
|
||||||
|
self.controller.updateAccount(address, accountName, color, emoji)
|
||||||
|
|
||||||
|
method authenticateActivityForKeyUid(self: Module, keyUid: string, reason: AuthenticationReason) =
|
||||||
|
self.authentiactionReason = reason
|
||||||
|
let keyPair = self.controller.getMigratedKeyPairByKeyUid(keyUid)
|
||||||
|
let keyPairMigratedToKeycard = keyPair.len > 0
|
||||||
|
if keyPairMigratedToKeycard:
|
||||||
|
self.controller.authenticateKeyPair(keyUid)
|
||||||
|
else:
|
||||||
|
self.processingWalletAccount.keyUid = singletonInstance.userProfile.getKeyUid()
|
||||||
|
self.controller.authenticateKeyPair()
|
||||||
|
|
||||||
|
method deleteAccount*(self: Module, keyUid: string, address: string) =
|
||||||
|
let accountDto = self.controller.getWalletAccount(address)
|
||||||
|
if accountDto.walletType == WalletTypeWatch:
|
||||||
|
self.controller.deleteAccount(address)
|
||||||
|
return
|
||||||
|
self.processingWalletAccount = WalletAccountDetails(keyUid: keyUid, address: address)
|
||||||
|
self.authenticateActivityForKeyUid(keyUid, AuthenticationReason.DeleteAccountAuthentication)
|
||||||
|
|
||||||
|
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string) =
|
||||||
|
if self.authentiactionReason == AuthenticationReason.DeleteAccountAuthentication:
|
||||||
|
if self.processingWalletAccount.keyUid != keyUid:
|
||||||
|
error "cannot resolve key uid of an account being deleted", keyUid=keyUid
|
||||||
|
return
|
||||||
|
if password.len == 0:
|
||||||
|
return
|
||||||
|
let doPasswordHashing = pin.len != PINLengthForStatusApp
|
||||||
|
self.controller.deleteAccount(self.processingWalletAccount.address, password, doPasswordHashing)
|
|
@ -0,0 +1,32 @@
|
||||||
|
import strformat
|
||||||
|
|
||||||
|
type
|
||||||
|
Item* = object
|
||||||
|
name: string
|
||||||
|
color: string
|
||||||
|
emoji: string
|
||||||
|
|
||||||
|
proc initItem*(
|
||||||
|
name: string = "",
|
||||||
|
color: string = "",
|
||||||
|
emoji: string = "",
|
||||||
|
): Item =
|
||||||
|
result.name = name
|
||||||
|
result.color = color
|
||||||
|
result.emoji = emoji
|
||||||
|
|
||||||
|
proc `$`*(self: Item): string =
|
||||||
|
result = fmt"""WalletAccountItem(
|
||||||
|
name: {self.name},
|
||||||
|
color: {self.color},
|
||||||
|
emoji: {self.emoji},
|
||||||
|
]"""
|
||||||
|
|
||||||
|
proc getName*(self: Item): string =
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
proc getEmoji*(self: Item): string =
|
||||||
|
return self.emoji
|
||||||
|
|
||||||
|
proc getColor*(self: Item): string =
|
||||||
|
return self.color
|
|
@ -0,0 +1,73 @@
|
||||||
|
import NimQml, Tables, strutils, strformat
|
||||||
|
|
||||||
|
import ./related_account_item
|
||||||
|
|
||||||
|
type
|
||||||
|
ModelRole {.pure.} = enum
|
||||||
|
Name = UserRole + 1,
|
||||||
|
Color,
|
||||||
|
Emoji,
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
Model* = ref object of QAbstractListModel
|
||||||
|
items: seq[Item]
|
||||||
|
|
||||||
|
proc delete(self: Model) =
|
||||||
|
self.items = @[]
|
||||||
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc setup(self: Model) =
|
||||||
|
self.QAbstractListModel.setup
|
||||||
|
|
||||||
|
proc newModel*(): Model =
|
||||||
|
new(result, delete)
|
||||||
|
result.setup
|
||||||
|
|
||||||
|
proc `$`*(self: Model): string =
|
||||||
|
for i in 0 ..< self.items.len:
|
||||||
|
result &= fmt"""[{i}]:({$self.items[i]})"""
|
||||||
|
|
||||||
|
proc countChanged(self: Model) {.signal.}
|
||||||
|
|
||||||
|
proc getCount*(self: Model): int {.slot.} =
|
||||||
|
self.items.len
|
||||||
|
|
||||||
|
QtProperty[int] count:
|
||||||
|
read = getCount
|
||||||
|
notify = countChanged
|
||||||
|
|
||||||
|
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||||
|
return self.items.len
|
||||||
|
|
||||||
|
method roleNames(self: Model): Table[int, string] =
|
||||||
|
{
|
||||||
|
ModelRole.Name.int:"name",
|
||||||
|
ModelRole.Color.int:"color",
|
||||||
|
ModelRole.Emoji.int: "emoji",
|
||||||
|
}.toTable
|
||||||
|
|
||||||
|
|
||||||
|
proc setItems*(self: Model, items: seq[Item]) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.items = items
|
||||||
|
self.endResetModel()
|
||||||
|
self.countChanged()
|
||||||
|
|
||||||
|
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||||
|
if (not index.isValid):
|
||||||
|
return
|
||||||
|
|
||||||
|
if (index.row < 0 or index.row >= self.items.len):
|
||||||
|
return
|
||||||
|
|
||||||
|
let item = self.items[index.row]
|
||||||
|
let enumRole = role.ModelRole
|
||||||
|
|
||||||
|
case enumRole:
|
||||||
|
of ModelRole.Name:
|
||||||
|
result = newQVariant(item.getName())
|
||||||
|
of ModelRole.Color:
|
||||||
|
result = newQVariant(item.getColor())
|
||||||
|
of ModelRole.Emoji:
|
||||||
|
result = newQVariant(item.getEmoji())
|
|
@ -0,0 +1,34 @@
|
||||||
|
import tables, sequtils, sugar
|
||||||
|
import ../../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||||
|
import ./item
|
||||||
|
import ./related_account_item as related_account_item
|
||||||
|
import ./related_accounts_model as related_accounts_model
|
||||||
|
|
||||||
|
proc walletAccountToRelatedAccountItem*(w: WalletAccountDto) : related_account_item.Item =
|
||||||
|
return related_account_item.initItem(
|
||||||
|
w.name,
|
||||||
|
w.color,
|
||||||
|
w.emoji,
|
||||||
|
)
|
||||||
|
|
||||||
|
proc walletAccountToItem*(
|
||||||
|
w: WalletAccountDto,
|
||||||
|
) : item.Item =
|
||||||
|
let relatedAccounts = related_accounts_model.newModel()
|
||||||
|
if w.isNil:
|
||||||
|
return item.initItem()
|
||||||
|
|
||||||
|
relatedAccounts.setItems(
|
||||||
|
w.relatedAccounts.map(x => walletAccountToRelatedAccountItem(x))
|
||||||
|
)
|
||||||
|
|
||||||
|
return item.initItem(
|
||||||
|
w.name,
|
||||||
|
w.address,
|
||||||
|
w.path,
|
||||||
|
w.color,
|
||||||
|
w.walletType,
|
||||||
|
w.emoji,
|
||||||
|
relatedAccounts,
|
||||||
|
w.keyUid,
|
||||||
|
)
|
|
@ -0,0 +1,48 @@
|
||||||
|
import NimQml, sequtils, strutils, sugar
|
||||||
|
|
||||||
|
import ./model
|
||||||
|
import ./item
|
||||||
|
import ./io_interface
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
View* = ref object of QObject
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
accounts: Model
|
||||||
|
accountsVariant: QVariant
|
||||||
|
|
||||||
|
proc delete*(self: View) =
|
||||||
|
self.accounts.delete
|
||||||
|
self.accountsVariant.delete
|
||||||
|
self.QObject.delete
|
||||||
|
|
||||||
|
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||||
|
new(result, delete)
|
||||||
|
result.QObject.setup
|
||||||
|
result.delegate = delegate
|
||||||
|
result.accounts = newModel()
|
||||||
|
result.accountsVariant = newQVariant(result.accounts)
|
||||||
|
|
||||||
|
proc load*(self: View) =
|
||||||
|
self.delegate.viewDidLoad()
|
||||||
|
|
||||||
|
proc accountsChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc getAccounts(self: View): QVariant {.slot.} =
|
||||||
|
return self.accountsVariant
|
||||||
|
|
||||||
|
QtProperty[QVariant] accounts:
|
||||||
|
read = getAccounts
|
||||||
|
notify = accountsChanged
|
||||||
|
|
||||||
|
proc setItems*(self: View, items: seq[Item]) =
|
||||||
|
self.accounts.setItems(items)
|
||||||
|
|
||||||
|
proc updateAccount(self: View, address: string, accountName: string, color: string, emoji: string) {.slot.} =
|
||||||
|
self.delegate.updateAccount(address, accountName, color, emoji)
|
||||||
|
|
||||||
|
proc onUpdatedAccount*(self: View, account: Item) =
|
||||||
|
self.accounts.onUpdatedAccount(account)
|
||||||
|
|
||||||
|
proc deleteAccount*(self: View, keyUid: string, address: string) {.slot.} =
|
||||||
|
self.delegate.deleteAccount(keyUid, address)
|
|
@ -0,0 +1,33 @@
|
||||||
|
import NimQml
|
||||||
|
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
## Abstract class for any input/interaction with this module.
|
||||||
|
|
||||||
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method load*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method isLoaded*(self: AccessInterface): bool {.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.
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
# Methods called by submodules of this module
|
||||||
|
method accountsModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method networksModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getAccountsModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getNetworksModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,79 @@
|
||||||
|
import NimQml, chronicles
|
||||||
|
|
||||||
|
import ./io_interface as io_interface
|
||||||
|
import ../io_interface as delegate_interface
|
||||||
|
|
||||||
|
import ./accounts/module as accounts_module
|
||||||
|
import ./networks/module as networks_module
|
||||||
|
|
||||||
|
import ../../../../global/global_singleton
|
||||||
|
import ../../../../core/eventemitter
|
||||||
|
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 as settings_service
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "profile-section-wallet-module"
|
||||||
|
|
||||||
|
import io_interface
|
||||||
|
export io_interface
|
||||||
|
|
||||||
|
type
|
||||||
|
Module* = ref object of io_interface.AccessInterface
|
||||||
|
delegate: delegate_interface.AccessInterface
|
||||||
|
events: EventEmitter
|
||||||
|
moduleLoaded: bool
|
||||||
|
|
||||||
|
accountsModule: accounts_module.AccessInterface
|
||||||
|
networksModule: networks_module.AccessInterface
|
||||||
|
|
||||||
|
proc newModule*(
|
||||||
|
delegate: delegate_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
walletAccountService: wallet_account_service.Service,
|
||||||
|
settingsService: settings_service.Service,
|
||||||
|
networkService: network_service.Service,
|
||||||
|
): Module =
|
||||||
|
result = Module()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
|
result.moduleLoaded = false
|
||||||
|
|
||||||
|
result.accountsModule = accounts_module.newModule(result, events, walletAccountService, networkService)
|
||||||
|
result.networksModule = networks_module.newModule(result, events, networkService, walletAccountService, settingsService)
|
||||||
|
|
||||||
|
method delete*(self: Module) =
|
||||||
|
self.accountsModule.delete
|
||||||
|
self.networksModule.delete
|
||||||
|
|
||||||
|
method load*(self: Module) =
|
||||||
|
self.accountsModule.load()
|
||||||
|
self.networksModule.load()
|
||||||
|
|
||||||
|
method isLoaded*(self: Module): bool =
|
||||||
|
return self.moduleLoaded
|
||||||
|
|
||||||
|
method getAccountsModuleAsVariant*(self: Module): QVariant =
|
||||||
|
return self.accountsModule.getModuleAsVariant()
|
||||||
|
|
||||||
|
method getNetworksModuleAsVariant*(self: Module): QVariant =
|
||||||
|
return self.networksModule.getModuleAsVariant()
|
||||||
|
|
||||||
|
proc checkIfModuleDidLoad(self: Module) =
|
||||||
|
if(not self.accountsModule.isLoaded()):
|
||||||
|
return
|
||||||
|
|
||||||
|
if(not self.networksModule.isLoaded()):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.moduleLoaded = true
|
||||||
|
self.delegate.walletModuleDidLoad()
|
||||||
|
|
||||||
|
method viewDidLoad*(self: Module) =
|
||||||
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method accountsModuleDidLoad*(self: Module) =
|
||||||
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method networksModuleDidLoad*(self: Module) =
|
||||||
|
self.checkIfModuleDidLoad()
|
|
@ -0,0 +1,44 @@
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
import ../../../../../../app_service/service/network/service as network_service
|
||||||
|
import ../../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||||
|
import ../../../../../../app_service/service/settings/service as settings_service
|
||||||
|
import ./io_interface
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
Controller* = ref object of RootObj
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
events: EventEmitter
|
||||||
|
networkService: network_service.Service
|
||||||
|
walletAccountService: wallet_account_service.Service
|
||||||
|
settingsService: settings_service.Service
|
||||||
|
|
||||||
|
proc newController*(
|
||||||
|
delegate: io_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
networkService: network_service.Service,
|
||||||
|
walletAccountService: wallet_account_service.Service,
|
||||||
|
settingsService: settings_service.Service,
|
||||||
|
): Controller =
|
||||||
|
result = Controller()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
|
result.networkService = networkService
|
||||||
|
result.walletAccountService = walletAccountService
|
||||||
|
result.settingsService = settingsService
|
||||||
|
|
||||||
|
proc delete*(self: Controller) =
|
||||||
|
discard
|
||||||
|
|
||||||
|
proc init*(self: Controller) =
|
||||||
|
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e: Args):
|
||||||
|
self.delegate.refreshNetworks()
|
||||||
|
|
||||||
|
proc getNetworks*(self: Controller): seq[NetworkDto] =
|
||||||
|
return self.networkService.getNetworks()
|
||||||
|
|
||||||
|
proc areTestNetworksEnabled*(self: Controller): bool =
|
||||||
|
return self.settingsService.areTestNetworksEnabled()
|
||||||
|
|
||||||
|
proc toggleTestNetworksEnabled*(self: Controller) =
|
||||||
|
self.walletAccountService.toggleTestNetworksEnabled()
|
|
@ -0,0 +1,29 @@
|
||||||
|
import NimQml
|
||||||
|
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
## Abstract class for any input/interaction with this module.
|
||||||
|
|
||||||
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method load*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method isLoaded*(self: AccessInterface): bool {.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.
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method refreshNetworks*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method toggleTestNetworksEnabled*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,39 @@
|
||||||
|
import strformat
|
||||||
|
|
||||||
|
type
|
||||||
|
Item* = object
|
||||||
|
chainId: int
|
||||||
|
layer: int
|
||||||
|
chainName: string
|
||||||
|
iconUrl: string
|
||||||
|
|
||||||
|
proc initItem*(
|
||||||
|
chainId: int,
|
||||||
|
layer: int,
|
||||||
|
chainName: string,
|
||||||
|
iconUrl: string,
|
||||||
|
): Item =
|
||||||
|
result.chainId = chainId
|
||||||
|
result.layer = layer
|
||||||
|
result.chainName = chainName
|
||||||
|
result.iconUrl = iconUrl
|
||||||
|
|
||||||
|
proc `$`*(self: Item): string =
|
||||||
|
result = fmt"""NetworkItem(
|
||||||
|
chainId: {self.chainId},
|
||||||
|
chainName: {self.chainName},
|
||||||
|
layer: {self.layer},
|
||||||
|
iconUrl:{self.iconUrl},
|
||||||
|
]"""
|
||||||
|
|
||||||
|
proc getChainId*(self: Item): int =
|
||||||
|
return self.chainId
|
||||||
|
|
||||||
|
proc getLayer*(self: Item): int =
|
||||||
|
return self.layer
|
||||||
|
|
||||||
|
proc getChainName*(self: Item): string =
|
||||||
|
return self.chainName
|
||||||
|
|
||||||
|
proc getIconURL*(self: Item): string =
|
||||||
|
return self.iconUrl
|
|
@ -0,0 +1,88 @@
|
||||||
|
import NimQml, Tables, strutils, strformat
|
||||||
|
|
||||||
|
import ./item
|
||||||
|
|
||||||
|
const EXPLORER_TX_PREFIX* = "/tx/"
|
||||||
|
|
||||||
|
type
|
||||||
|
ModelRole* {.pure.} = enum
|
||||||
|
ChainId = UserRole + 1,
|
||||||
|
Layer
|
||||||
|
ChainName
|
||||||
|
IconUrl
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
Model* = ref object of QAbstractListModel
|
||||||
|
items: seq[Item]
|
||||||
|
|
||||||
|
proc delete(self: Model) =
|
||||||
|
self.items = @[]
|
||||||
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc setup(self: Model) =
|
||||||
|
self.QAbstractListModel.setup
|
||||||
|
|
||||||
|
proc newModel*(): Model =
|
||||||
|
new(result, delete)
|
||||||
|
result.setup
|
||||||
|
|
||||||
|
proc `$`*(self: Model): string =
|
||||||
|
for i in 0 ..< self.items.len:
|
||||||
|
result &= fmt"""[{i}]:({$self.items[i]})"""
|
||||||
|
|
||||||
|
proc countChanged(self: Model) {.signal.}
|
||||||
|
|
||||||
|
proc getCount(self: Model): int {.slot.} =
|
||||||
|
self.items.len
|
||||||
|
|
||||||
|
QtProperty[int] count:
|
||||||
|
read = getCount
|
||||||
|
notify = countChanged
|
||||||
|
|
||||||
|
method rowCount*(self: Model, index: QModelIndex = nil): int =
|
||||||
|
return self.items.len
|
||||||
|
|
||||||
|
method roleNames(self: Model): Table[int, string] =
|
||||||
|
{
|
||||||
|
ModelRole.ChainId.int:"chainId",
|
||||||
|
ModelRole.Layer.int:"layer",
|
||||||
|
ModelRole.ChainName.int:"chainName",
|
||||||
|
ModelRole.IconUrl.int:"iconUrl",
|
||||||
|
}.toTable
|
||||||
|
|
||||||
|
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||||
|
if (not index.isValid):
|
||||||
|
return
|
||||||
|
|
||||||
|
if (index.row < 0 or index.row >= self.items.len):
|
||||||
|
return
|
||||||
|
|
||||||
|
let item = self.items[index.row]
|
||||||
|
let enumRole = role.ModelRole
|
||||||
|
|
||||||
|
case enumRole:
|
||||||
|
of ModelRole.ChainId:
|
||||||
|
result = newQVariant(item.getChainId())
|
||||||
|
of ModelRole.Layer:
|
||||||
|
result = newQVariant(item.getLayer())
|
||||||
|
of ModelRole.ChainName:
|
||||||
|
result = newQVariant(item.getChainName())
|
||||||
|
of ModelRole.IconUrl:
|
||||||
|
result = newQVariant(item.getIconURL())
|
||||||
|
|
||||||
|
proc rowData*(self: Model, index: int, column: string): string {.slot.} =
|
||||||
|
if (index >= self.items.len):
|
||||||
|
return
|
||||||
|
let item = self.items[index]
|
||||||
|
case column:
|
||||||
|
of "chainId": result = $item.getChainId()
|
||||||
|
of "layer": result = $item.getLayer()
|
||||||
|
of "chainName": result = $item.getChainName()
|
||||||
|
of "iconUrl": result = $item.getIconURL()
|
||||||
|
|
||||||
|
proc setItems*(self: Model, items: seq[Item]) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.items = items
|
||||||
|
self.endResetModel()
|
||||||
|
self.countChanged()
|
|
@ -0,0 +1,64 @@
|
||||||
|
import Tables, NimQml
|
||||||
|
import ../io_interface as delegate_interface
|
||||||
|
import io_interface, view, controller
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
import ../../../../../../app_service/service/network/service as network_service
|
||||||
|
import ../../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||||
|
import ../../../../../../app_service/service/settings/service as settings_service
|
||||||
|
|
||||||
|
export io_interface
|
||||||
|
|
||||||
|
type
|
||||||
|
Module* = ref object of io_interface.AccessInterface
|
||||||
|
delegate: delegate_interface.AccessInterface
|
||||||
|
view: View
|
||||||
|
viewVariant: QVariant
|
||||||
|
controller: Controller
|
||||||
|
moduleLoaded: bool
|
||||||
|
|
||||||
|
proc newModule*(
|
||||||
|
delegate: delegate_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
networkService: networkService.Service,
|
||||||
|
walletAccountService: wallet_account_service.Service,
|
||||||
|
settingsService: settings_service.Service,
|
||||||
|
): Module =
|
||||||
|
result = Module()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.view = view.newView(result)
|
||||||
|
result.viewVariant = newQVariant(result.view)
|
||||||
|
result.controller = controller.newController(result, events, networkService, walletAccountService, settingsService)
|
||||||
|
result.moduleLoaded = false
|
||||||
|
|
||||||
|
method delete*(self: Module) =
|
||||||
|
self.view.delete
|
||||||
|
self.viewVariant.delete
|
||||||
|
self.controller.delete
|
||||||
|
|
||||||
|
method getModuleAsVariant*(self: Module): QVariant =
|
||||||
|
return self.viewVariant
|
||||||
|
|
||||||
|
method refreshNetworks*(self: Module) =
|
||||||
|
self.view.load(self.controller.getNetworks())
|
||||||
|
|
||||||
|
method load*(self: Module) =
|
||||||
|
self.controller.init()
|
||||||
|
self.view.setAreTestNetworksEnabled(self.controller.areTestNetworksEnabled())
|
||||||
|
self.refreshNetworks()
|
||||||
|
|
||||||
|
method isLoaded*(self: Module): bool =
|
||||||
|
return self.moduleLoaded
|
||||||
|
|
||||||
|
proc checkIfModuleDidLoad(self: Module) =
|
||||||
|
self.moduleLoaded = true
|
||||||
|
self.delegate.networksModuleDidLoad()
|
||||||
|
|
||||||
|
method viewDidLoad*(self: Module) =
|
||||||
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method areTestNetworksEnabled*(self: Module): bool =
|
||||||
|
return self.controller.areTestNetworksEnabled()
|
||||||
|
|
||||||
|
method toggleTestNetworksEnabled*(self: Module) =
|
||||||
|
self.controller.toggleTestNetworksEnabled()
|
||||||
|
self.refreshNetworks()
|
|
@ -0,0 +1,65 @@
|
||||||
|
import Tables, NimQml, sequtils, sugar
|
||||||
|
|
||||||
|
import ../../../../../../app_service/service/network/dto
|
||||||
|
import ./io_interface
|
||||||
|
import ./model
|
||||||
|
import ./item
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
View* = ref object of QObject
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
networks: Model
|
||||||
|
areTestNetworksEnabled: bool
|
||||||
|
|
||||||
|
proc setup(self: View) =
|
||||||
|
self.QObject.setup
|
||||||
|
|
||||||
|
proc delete*(self: View) =
|
||||||
|
self.QObject.delete
|
||||||
|
|
||||||
|
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||||
|
new(result, delete)
|
||||||
|
result.delegate = delegate
|
||||||
|
result.networks = newModel()
|
||||||
|
result.setup()
|
||||||
|
|
||||||
|
proc areTestNetworksEnabledChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc getAreTestNetworksEnabled(self: View): bool {.slot.} =
|
||||||
|
return self.areTestNetworksEnabled
|
||||||
|
|
||||||
|
QtProperty[bool] areTestNetworksEnabled:
|
||||||
|
read = getAreTestNetworksEnabled
|
||||||
|
notify = areTestNetworksEnabledChanged
|
||||||
|
|
||||||
|
proc setAreTestNetworksEnabled*(self: View, areTestNetworksEnabled: bool) =
|
||||||
|
self.areTestNetworksEnabled = areTestNetworksEnabled
|
||||||
|
self.areTestNetworksEnabledChanged()
|
||||||
|
|
||||||
|
proc toggleTestNetworksEnabled*(self: View) {.slot.} =
|
||||||
|
self.delegate.toggleTestNetworksEnabled()
|
||||||
|
self.areTestNetworksEnabled = not self.areTestNetworksEnabled
|
||||||
|
self.areTestNetworksEnabledChanged()
|
||||||
|
|
||||||
|
proc networksChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc getNetworks(self: View): QVariant {.slot.} =
|
||||||
|
return newQVariant(self.networks)
|
||||||
|
|
||||||
|
QtProperty[QVariant] networks:
|
||||||
|
read = getNetworks
|
||||||
|
notify = networksChanged
|
||||||
|
|
||||||
|
proc load*(self: View, networks: seq[NetworkDto]) =
|
||||||
|
var items: seq[Item] = @[]
|
||||||
|
for n in networks:
|
||||||
|
items.add(initItem(
|
||||||
|
n.chainId,
|
||||||
|
n.layer,
|
||||||
|
n.chainName,
|
||||||
|
n.iconUrl,
|
||||||
|
))
|
||||||
|
|
||||||
|
self.networks.setItems(items)
|
||||||
|
self.delegate.viewDidLoad()
|
|
@ -20,10 +20,10 @@ StatusModal {
|
||||||
id: popup
|
id: popup
|
||||||
|
|
||||||
property WalletStore walletStore
|
property WalletStore walletStore
|
||||||
property var currentAccount: walletStore.currentAccount
|
property var account
|
||||||
property var emojiPopup
|
property var emojiPopup
|
||||||
|
|
||||||
header.title: qsTr("Rename %1").arg(currentAccount.name)
|
header.title: qsTr("Rename %1").arg(popup.account.name)
|
||||||
|
|
||||||
property int marginBetweenInputs: 30
|
property int marginBetweenInputs: 30
|
||||||
|
|
||||||
|
@ -53,10 +53,10 @@ StatusModal {
|
||||||
input.edit.objectName: "renameAccountNameInput"
|
input.edit.objectName: "renameAccountNameInput"
|
||||||
input.isIconSelectable: true
|
input.isIconSelectable: true
|
||||||
placeholderText: qsTr("Enter an account name...")
|
placeholderText: qsTr("Enter an account name...")
|
||||||
input.text: currentAccount.name
|
input.text: popup.account.name
|
||||||
input.asset.emoji: currentAccount.emoji
|
input.asset.emoji: popup.account.emoji
|
||||||
input.asset.color: currentAccount.color
|
input.asset.color: popup.account.color
|
||||||
input.asset.name: !currentAccount.emoji ? "filled-account": ""
|
input.asset.name: !popup.account.emoji ? "filled-account": ""
|
||||||
|
|
||||||
validationMode: StatusInput.ValidationMode.Always
|
validationMode: StatusInput.ValidationMode.Always
|
||||||
|
|
||||||
|
@ -85,16 +85,16 @@ StatusModal {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
model: Constants.preDefinedWalletAccountColors
|
model: Constants.preDefinedWalletAccountColors
|
||||||
titleText: qsTr("color").toUpperCase()
|
titleText: qsTr("color").toUpperCase()
|
||||||
selectedColor: currentAccount.color
|
selectedColor: popup.account.color
|
||||||
selectedColorIndex: {
|
selectedColorIndex: {
|
||||||
for (let i = 0; i < model.length; i++) {
|
for (let i = 0; i < model.length; i++) {
|
||||||
if(model[i] === currentAccount.color)
|
if(model[i] === popup.account.color)
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
onSelectedColorChanged: {
|
onSelectedColorChanged: {
|
||||||
if(selectedColor !== currentAccount.color) {
|
if(selectedColor !== popup.account.color) {
|
||||||
accountNameInput.input.asset.color = selectedColor
|
accountNameInput.input.asset.color = selectedColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,8 +113,8 @@ StatusModal {
|
||||||
text: qsTr("Change Name")
|
text: qsTr("Change Name")
|
||||||
|
|
||||||
enabled: accountNameInput.text !== "" && accountNameInput.valid
|
enabled: accountNameInput.text !== "" && accountNameInput.valid
|
||||||
&& (accountNameInput.text !== currentAccount.name
|
&& (accountNameInput.text !== popup.account.name
|
||||||
|| (accountColorInput.selectedColorIndex >= 0 && accountColorInput.selectedColor !== currentAccount.color))
|
|| (accountColorInput.selectedColorIndex >= 0 && accountColorInput.selectedColor !== popup.account.color))
|
||||||
|
|
||||||
MessageDialog {
|
MessageDialog {
|
||||||
id: changeError
|
id: changeError
|
||||||
|
@ -128,7 +128,7 @@ StatusModal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const error = walletStore.updateCurrentAccount(currentAccount.address, accountNameInput.text, accountColorInput.selectedColor, accountNameInput.input.asset.emoji);
|
const error = walletStore.updateAccount(popup.account.address, accountNameInput.text, accountColorInput.selectedColor, accountNameInput.input.asset.emoji);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Global.playErrorSound();
|
Global.playErrorSound();
|
||||||
|
|
|
@ -56,6 +56,8 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
property WalletStore walletStore: WalletStore {
|
property WalletStore walletStore: WalletStore {
|
||||||
|
accountsModule: profileSectionModuleInst.walletAccountsModule
|
||||||
|
networksModule: profileSectionModuleInst.walletNetworksModule
|
||||||
}
|
}
|
||||||
|
|
||||||
property KeycardStore keycardStore: KeycardStore {
|
property KeycardStore keycardStore: KeycardStore {
|
||||||
|
|
|
@ -1,41 +1,32 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
|
||||||
import "../../Wallet/stores"
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property var accountsModule
|
||||||
|
property var networksModule
|
||||||
|
|
||||||
property var accountSensitiveSettings: Global.appIsReady? localAccountSensitiveSettings : null
|
property var accountSensitiveSettings: Global.appIsReady? localAccountSensitiveSettings : null
|
||||||
|
|
||||||
property var areTestNetworksEnabled: networksModule.areTestNetworksEnabled
|
property var areTestNetworksEnabled: networksModule.areTestNetworksEnabled
|
||||||
property var layer1Networks: networksModule.layer1
|
property var networks: networksModule.networks
|
||||||
property var layer2Networks: networksModule.layer2
|
|
||||||
property var testNetworks: networksModule.test
|
|
||||||
|
|
||||||
function toggleTestNetworksEnabled(){
|
function toggleTestNetworksEnabled(){
|
||||||
networksModule.toggleTestNetworksEnabled()
|
networksModule.toggleTestNetworksEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
property var accounts: Global.appIsReady? walletSectionAccounts.model : null
|
// TODO(alaibe): there should be no access to wallet section, create collectible in profile
|
||||||
property var importedAccounts: Global.appIsReady? walletSectionAccounts.imported : null
|
|
||||||
property var generatedAccounts: Global.appIsReady? walletSectionAccounts.generated : null
|
|
||||||
property var watchOnlyAccounts: Global.appIsReady? walletSectionAccounts.watchOnly : null
|
|
||||||
|
|
||||||
property var flatCollectibles: Global.appIsReady ? walletSectionCollectibles.model : null
|
property var flatCollectibles: Global.appIsReady ? walletSectionCollectibles.model : null
|
||||||
|
property var accounts: Global.appIsReady? accountsModule.accounts : null
|
||||||
|
|
||||||
property var currentAccount: Global.appIsReady? walletSectionCurrent : null
|
|
||||||
|
|
||||||
function switchAccountByAddress(address) {
|
|
||||||
walletSection.switchAccountByAddress(address)
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteAccount(keyUid, address) {
|
function deleteAccount(keyUid, address) {
|
||||||
return walletSectionAccounts.deleteAccount(keyUid, address)
|
return accountsModule.deleteAccount(keyUid, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCurrentAccount(address, accountName, color, emoji) {
|
function updateAccount(address, accountName, color, emoji) {
|
||||||
return walletSectionCurrent.update(address, accountName, color, emoji)
|
return accountsModule.updateAccount(address, accountName, color, emoji)
|
||||||
}
|
}
|
||||||
|
|
||||||
property var dappList: Global.appIsReady? dappPermissionsModule.dapps : null
|
property var dappList: Global.appIsReady? dappPermissionsModule.dapps : null
|
||||||
|
|
|
@ -71,7 +71,7 @@ SettingsContentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
onGoToAccountView: {
|
onGoToAccountView: {
|
||||||
root.walletStore.switchAccountByAddress(address)
|
accountView.account = account
|
||||||
stackContainer.currentIndex = accountViewIndex
|
stackContainer.currentIndex = accountViewIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ SettingsContentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountView {
|
AccountView {
|
||||||
|
id: accountView
|
||||||
walletStore: root.walletStore
|
walletStore: root.walletStore
|
||||||
emojiPopup: root.emojiPopup
|
emojiPopup: root.emojiPopup
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ Item {
|
||||||
|
|
||||||
property WalletStore walletStore
|
property WalletStore walletStore
|
||||||
property var emojiPopup
|
property var emojiPopup
|
||||||
|
property var account
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: column
|
id: column
|
||||||
|
@ -42,11 +43,11 @@ Item {
|
||||||
asset: StatusAssetSettings {
|
asset: StatusAssetSettings {
|
||||||
width: isLetterIdenticon ? 40 : 20
|
width: isLetterIdenticon ? 40 : 20
|
||||||
height: isLetterIdenticon ? 40 : 20
|
height: isLetterIdenticon ? 40 : 20
|
||||||
color: walletStore.currentAccount.color
|
color: root.account ? root.account.color : "#ffffff"
|
||||||
emoji: walletStore.currentAccount.emoji
|
emoji: root.account ? root.account.emoji : ""
|
||||||
name: !walletStore.currentAccount.emoji ? "filled-account": ""
|
name: root.account && !root.account.emoji ? "filled-account": ""
|
||||||
letterSize: 14
|
letterSize: 14
|
||||||
isLetterIdenticon: !!walletStore.currentAccount.emoji
|
isLetterIdenticon: !!root.account && !!root.account.emoji
|
||||||
bgWidth: 40
|
bgWidth: 40
|
||||||
bgHeight: 40
|
bgHeight: 40
|
||||||
bgColor: Theme.palette.primaryColor3
|
bgColor: Theme.palette.primaryColor3
|
||||||
|
@ -59,7 +60,7 @@ Item {
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
objectName: "walletAccountViewAccountName"
|
objectName: "walletAccountViewAccountName"
|
||||||
id: accountName
|
id: accountName
|
||||||
text: walletStore.currentAccount.name
|
text:root.account ? root.account.name : ""
|
||||||
font.weight: Font.Bold
|
font.weight: Font.Bold
|
||||||
font.pixelSize: 28
|
font.pixelSize: 28
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
|
@ -76,7 +77,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatusAddressPanel {
|
StatusAddressPanel {
|
||||||
value: walletStore.currentAccount.address
|
value: root.account ? root.account.address : ""
|
||||||
|
|
||||||
font.weight: Font.Normal
|
font.weight: Font.Normal
|
||||||
|
|
||||||
|
@ -98,7 +99,10 @@ Item {
|
||||||
maxWidth: parent.width
|
maxWidth: parent.width
|
||||||
primaryText: qsTr("Type")
|
primaryText: qsTr("Type")
|
||||||
secondaryText: {
|
secondaryText: {
|
||||||
const walletType = walletStore.currentAccount.walletType
|
if (!root.account) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
const walletType = root.account.walletType
|
||||||
if (walletType === "watch") {
|
if (walletType === "watch") {
|
||||||
return qsTr("Watch-Only Account")
|
return qsTr("Watch-Only Account")
|
||||||
} else if (walletType === "generated" || walletType === "") {
|
} else if (walletType === "generated" || walletType === "") {
|
||||||
|
@ -118,15 +122,15 @@ Item {
|
||||||
InformationTile {
|
InformationTile {
|
||||||
maxWidth: parent.width
|
maxWidth: parent.width
|
||||||
primaryText: qsTr("Derivation Path")
|
primaryText: qsTr("Derivation Path")
|
||||||
secondaryText: walletStore.currentAccount.path
|
secondaryText: root.account ? root.account.path : ""
|
||||||
visible: walletStore.currentAccount.path
|
visible: !!root.account && root.account.path
|
||||||
}
|
}
|
||||||
|
|
||||||
InformationTile {
|
InformationTile {
|
||||||
maxWidth: parent.width
|
maxWidth: parent.width
|
||||||
visible: walletStore.currentAccount.relatedAccounts.count > 0
|
visible:root.account ? root.account.relatedAccounts.count > 0 : false
|
||||||
primaryText: qsTr("Related Accounts")
|
primaryText: qsTr("Related Accounts")
|
||||||
tagsModel: walletStore.currentAccount.relatedAccounts
|
tagsModel: root.account ? root.account.relatedAccounts : []
|
||||||
tagsDelegate: StatusListItemTag {
|
tagsDelegate: StatusListItemTag {
|
||||||
bgColor: model.color
|
bgColor: model.color
|
||||||
bgRadius: 6
|
bgRadius: 6
|
||||||
|
@ -144,20 +148,20 @@ Item {
|
||||||
|
|
||||||
StatusButton {
|
StatusButton {
|
||||||
objectName: "deleteAccountButton"
|
objectName: "deleteAccountButton"
|
||||||
visible: walletStore.currentAccount.walletType !== ""
|
visible: !!root.account && root.account.walletType !== ""
|
||||||
text: qsTr("Remove from your profile")
|
text: qsTr("Remove from your profile")
|
||||||
type: StatusBaseButton.Type.Danger
|
type: StatusBaseButton.Type.Danger
|
||||||
|
|
||||||
ConfirmationDialog {
|
ConfirmationDialog {
|
||||||
id: confirmationPopup
|
id: confirmationPopup
|
||||||
confirmButtonObjectName: "confirmDeleteAccountButton"
|
confirmButtonObjectName: "confirmDeleteAccountButton"
|
||||||
header.title: qsTr("Confirm %1 Removal").arg(walletStore.currentAccount.name)
|
header.title: qsTr("Confirm %1 Removal").arg(root.account ? root.account.name : "")
|
||||||
confirmationText: qsTr("You will not be able to restore viewing access to this account in the future unless you enter this account’s address again.")
|
confirmationText: qsTr("You will not be able to restore viewing access to this account in the future unless you enter this account’s address again.")
|
||||||
confirmButtonLabel: qsTr("Remove Account")
|
confirmButtonLabel: qsTr("Remove Account")
|
||||||
onConfirmButtonClicked: {
|
onConfirmButtonClicked: {
|
||||||
confirmationPopup.close();
|
confirmationPopup.close();
|
||||||
root.goBack();
|
root.goBack();
|
||||||
root.walletStore.deleteAccount(walletStore.currentAccount.keyUid, walletStore.currentAccount.address);
|
root.walletStore.deleteAccount(root.account.keyUid, root.account.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -171,6 +175,7 @@ Item {
|
||||||
Component {
|
Component {
|
||||||
id: renameAccountModalComponent
|
id: renameAccountModalComponent
|
||||||
RenameAccontModal {
|
RenameAccontModal {
|
||||||
|
account: root.account
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
walletStore: root.walletStore
|
walletStore: root.walletStore
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.status 1.0
|
import shared.status 1.0
|
||||||
|
@ -17,7 +18,7 @@ Column {
|
||||||
property WalletStore walletStore
|
property WalletStore walletStore
|
||||||
|
|
||||||
signal goToNetworksView()
|
signal goToNetworksView()
|
||||||
signal goToAccountView(address: string)
|
signal goToAccountView(var account)
|
||||||
signal goToDappPermissionsView()
|
signal goToDappPermissionsView()
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
@ -84,11 +85,28 @@ Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
objectName: "generatedAccounts"
|
objectName: "generatedAccounts"
|
||||||
model: walletStore.generatedAccounts
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: walletStore.accounts
|
||||||
|
filters: ExpressionFilter {
|
||||||
|
expression: {
|
||||||
|
return model.walletType === "generated" || model.walletType === ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
delegate: WalletAccountDelegate {
|
delegate: WalletAccountDelegate {
|
||||||
account: model
|
account: model
|
||||||
onGoToAccountView: {
|
onGoToAccountView: {
|
||||||
root.goToAccountView(model.address)
|
root.goToAccountView(model)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SortFilterProxyModel {
|
||||||
|
id: importedAccounts
|
||||||
|
sourceModel: walletStore.accounts
|
||||||
|
filters: ExpressionFilter {
|
||||||
|
expression: {
|
||||||
|
return model.walletType !== "generated" && model.walletType !== "watch" && model.walletType !== ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,33 +116,42 @@ Column {
|
||||||
leftPadding: Style.current.padding
|
leftPadding: Style.current.padding
|
||||||
topPadding: Style.current.halfPadding
|
topPadding: Style.current.halfPadding
|
||||||
bottomPadding: Style.current.halfPadding/2
|
bottomPadding: Style.current.halfPadding/2
|
||||||
visible: walletStore.importedAccounts.count > 0
|
visible: importedAccounts.count > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: walletStore.importedAccounts
|
model: importedAccounts
|
||||||
delegate: WalletAccountDelegate {
|
delegate: WalletAccountDelegate {
|
||||||
account: model
|
account: model
|
||||||
onGoToAccountView: {
|
onGoToAccountView: {
|
||||||
root.goToAccountView(model.address)
|
root.goToAccountView(model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SortFilterProxyModel {
|
||||||
|
id: watchOnlyAccounts
|
||||||
|
sourceModel: walletStore.accounts
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "walletType"
|
||||||
|
value: "watch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StatusSectionHeadline {
|
StatusSectionHeadline {
|
||||||
text: qsTr("Watch-Only")
|
text: qsTr("Watch-Only")
|
||||||
leftPadding: Style.current.padding
|
leftPadding: Style.current.padding
|
||||||
topPadding: Style.current.halfPadding
|
topPadding: Style.current.halfPadding
|
||||||
bottomPadding: Style.current.halfPadding/2
|
bottomPadding: Style.current.halfPadding/2
|
||||||
visible: walletStore.watchOnlyAccounts.count > 0
|
visible: watchOnlyAccounts.count > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: walletStore.watchOnlyAccounts
|
model: watchOnlyAccounts
|
||||||
delegate: WalletAccountDelegate {
|
delegate: WalletAccountDelegate {
|
||||||
account: model
|
account: model
|
||||||
onGoToAccountView: {
|
onGoToAccountView: {
|
||||||
root.goToAccountView(model.address)
|
root.goToAccountView(model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import shared.status 1.0
|
import shared.status 1.0
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
|
@ -23,7 +24,13 @@ Item {
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: layer1List
|
id: layer1List
|
||||||
model: walletStore.layer1Networks
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: walletStore.networks
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "layer"
|
||||||
|
value: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
delegate: WalletNetworkDelegate {
|
delegate: WalletNetworkDelegate {
|
||||||
network: model
|
network: model
|
||||||
}
|
}
|
||||||
|
@ -39,28 +46,16 @@ Item {
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: layer2List
|
id: layer2List
|
||||||
model: walletStore.layer2Networks
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: walletStore.networks
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "layer"
|
||||||
|
value: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
delegate: WalletNetworkDelegate {
|
delegate: WalletNetworkDelegate {
|
||||||
network: model
|
network: model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
height: Style.current.bigPadding
|
|
||||||
width: parent.width
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
// Disable for now
|
|
||||||
visible: false
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Style.current.bigPadding
|
|
||||||
id: addCustomNetworkButton
|
|
||||||
type: StatusFlatRoundButton.Type.Primary
|
|
||||||
text: qsTr("Add Custom Network")
|
|
||||||
onClicked: {
|
|
||||||
root.goBack()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue