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
|
@ -94,3 +94,12 @@ method communitiesModuleDidLoad*(self: AccessInterface) {.base.} =
|
|||
|
||||
method getKeycardModule*(self: AccessInterface): QVariant {.base.} =
|
||||
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 ./communities/module as communities_module
|
||||
import ./keycard/module as keycard_module
|
||||
import ./wallet/module as wallet_module
|
||||
|
||||
export io_interface
|
||||
|
||||
|
@ -61,6 +62,7 @@ type
|
|||
ensUsernamesModule: ens_usernames_module.AccessInterface
|
||||
communitiesModule: communities_module.AccessInterface
|
||||
keycardModule: keycard_module.AccessInterface
|
||||
walletModule: wallet_module.AccessInterface
|
||||
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
|
@ -109,6 +111,8 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
|
|||
result.keycardModule = keycard_module.newModule(result, events, keycardService, settingsService, networkService,
|
||||
privacyService, accountsService, walletAccountService, keychainService)
|
||||
|
||||
result.walletModule = wallet_module.newModule(result, events, walletAccountService, settingsService, networkService)
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
|
||||
|
||||
method delete*(self: Module) =
|
||||
|
@ -143,6 +147,7 @@ method load*(self: Module) =
|
|||
self.ensUsernamesModule.load()
|
||||
self.communitiesModule.load()
|
||||
self.keycardModule.load()
|
||||
self.walletModule.load()
|
||||
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
@ -187,6 +192,9 @@ proc checkIfModuleDidLoad(self: Module) =
|
|||
if(not self.keycardModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.walletModule.isLoaded()):
|
||||
return
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.profileSectionDidLoad()
|
||||
|
||||
|
@ -264,3 +272,12 @@ method communitiesModuleDidLoad*(self: Module) =
|
|||
|
||||
method getKeycardModule*(self: Module): QVariant =
|
||||
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()
|
||||
QtProperty[QVariant] keycardModule:
|
||||
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
|
||||
|
||||
property WalletStore walletStore
|
||||
property var currentAccount: walletStore.currentAccount
|
||||
property var account
|
||||
property var emojiPopup
|
||||
|
||||
header.title: qsTr("Rename %1").arg(currentAccount.name)
|
||||
header.title: qsTr("Rename %1").arg(popup.account.name)
|
||||
|
||||
property int marginBetweenInputs: 30
|
||||
|
||||
|
@ -53,10 +53,10 @@ StatusModal {
|
|||
input.edit.objectName: "renameAccountNameInput"
|
||||
input.isIconSelectable: true
|
||||
placeholderText: qsTr("Enter an account name...")
|
||||
input.text: currentAccount.name
|
||||
input.asset.emoji: currentAccount.emoji
|
||||
input.asset.color: currentAccount.color
|
||||
input.asset.name: !currentAccount.emoji ? "filled-account": ""
|
||||
input.text: popup.account.name
|
||||
input.asset.emoji: popup.account.emoji
|
||||
input.asset.color: popup.account.color
|
||||
input.asset.name: !popup.account.emoji ? "filled-account": ""
|
||||
|
||||
validationMode: StatusInput.ValidationMode.Always
|
||||
|
||||
|
@ -85,16 +85,16 @@ StatusModal {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
model: Constants.preDefinedWalletAccountColors
|
||||
titleText: qsTr("color").toUpperCase()
|
||||
selectedColor: currentAccount.color
|
||||
selectedColor: popup.account.color
|
||||
selectedColorIndex: {
|
||||
for (let i = 0; i < model.length; i++) {
|
||||
if(model[i] === currentAccount.color)
|
||||
if(model[i] === popup.account.color)
|
||||
return i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
onSelectedColorChanged: {
|
||||
if(selectedColor !== currentAccount.color) {
|
||||
if(selectedColor !== popup.account.color) {
|
||||
accountNameInput.input.asset.color = selectedColor
|
||||
}
|
||||
}
|
||||
|
@ -113,8 +113,8 @@ StatusModal {
|
|||
text: qsTr("Change Name")
|
||||
|
||||
enabled: accountNameInput.text !== "" && accountNameInput.valid
|
||||
&& (accountNameInput.text !== currentAccount.name
|
||||
|| (accountColorInput.selectedColorIndex >= 0 && accountColorInput.selectedColor !== currentAccount.color))
|
||||
&& (accountNameInput.text !== popup.account.name
|
||||
|| (accountColorInput.selectedColorIndex >= 0 && accountColorInput.selectedColor !== popup.account.color))
|
||||
|
||||
MessageDialog {
|
||||
id: changeError
|
||||
|
@ -128,7 +128,7 @@ StatusModal {
|
|||
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) {
|
||||
Global.playErrorSound();
|
||||
|
|
|
@ -56,6 +56,8 @@ QtObject {
|
|||
}
|
||||
|
||||
property WalletStore walletStore: WalletStore {
|
||||
accountsModule: profileSectionModuleInst.walletAccountsModule
|
||||
networksModule: profileSectionModuleInst.walletNetworksModule
|
||||
}
|
||||
|
||||
property KeycardStore keycardStore: KeycardStore {
|
||||
|
|
|
@ -1,41 +1,32 @@
|
|||
import QtQuick 2.13
|
||||
|
||||
import "../../Wallet/stores"
|
||||
import utils 1.0
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property var accountsModule
|
||||
property var networksModule
|
||||
|
||||
property var accountSensitiveSettings: Global.appIsReady? localAccountSensitiveSettings : null
|
||||
|
||||
property var areTestNetworksEnabled: networksModule.areTestNetworksEnabled
|
||||
property var layer1Networks: networksModule.layer1
|
||||
property var layer2Networks: networksModule.layer2
|
||||
property var testNetworks: networksModule.test
|
||||
property var networks: networksModule.networks
|
||||
|
||||
function toggleTestNetworksEnabled(){
|
||||
networksModule.toggleTestNetworksEnabled()
|
||||
}
|
||||
|
||||
property var accounts: Global.appIsReady? walletSectionAccounts.model : null
|
||||
property var importedAccounts: Global.appIsReady? walletSectionAccounts.imported : null
|
||||
property var generatedAccounts: Global.appIsReady? walletSectionAccounts.generated : null
|
||||
property var watchOnlyAccounts: Global.appIsReady? walletSectionAccounts.watchOnly : null
|
||||
|
||||
// TODO(alaibe): there should be no access to wallet section, create collectible in profile
|
||||
property var flatCollectibles: Global.appIsReady ? walletSectionCollectibles.model : null
|
||||
|
||||
property var currentAccount: Global.appIsReady? walletSectionCurrent : null
|
||||
|
||||
function switchAccountByAddress(address) {
|
||||
walletSection.switchAccountByAddress(address)
|
||||
}
|
||||
property var accounts: Global.appIsReady? accountsModule.accounts : null
|
||||
|
||||
function deleteAccount(keyUid, address) {
|
||||
return walletSectionAccounts.deleteAccount(keyUid, address)
|
||||
return accountsModule.deleteAccount(keyUid, address)
|
||||
}
|
||||
|
||||
function updateCurrentAccount(address, accountName, color, emoji) {
|
||||
return walletSectionCurrent.update(address, accountName, color, emoji)
|
||||
function updateAccount(address, accountName, color, emoji) {
|
||||
return accountsModule.updateAccount(address, accountName, color, emoji)
|
||||
}
|
||||
|
||||
property var dappList: Global.appIsReady? dappPermissionsModule.dapps : null
|
||||
|
|
|
@ -71,7 +71,7 @@ SettingsContentBase {
|
|||
}
|
||||
|
||||
onGoToAccountView: {
|
||||
root.walletStore.switchAccountByAddress(address)
|
||||
accountView.account = account
|
||||
stackContainer.currentIndex = accountViewIndex
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ SettingsContentBase {
|
|||
}
|
||||
|
||||
AccountView {
|
||||
id: accountView
|
||||
walletStore: root.walletStore
|
||||
emojiPopup: root.emojiPopup
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Item {
|
|||
|
||||
property WalletStore walletStore
|
||||
property var emojiPopup
|
||||
property var account
|
||||
|
||||
Column {
|
||||
id: column
|
||||
|
@ -42,11 +43,11 @@ Item {
|
|||
asset: StatusAssetSettings {
|
||||
width: isLetterIdenticon ? 40 : 20
|
||||
height: isLetterIdenticon ? 40 : 20
|
||||
color: walletStore.currentAccount.color
|
||||
emoji: walletStore.currentAccount.emoji
|
||||
name: !walletStore.currentAccount.emoji ? "filled-account": ""
|
||||
color: root.account ? root.account.color : "#ffffff"
|
||||
emoji: root.account ? root.account.emoji : ""
|
||||
name: root.account && !root.account.emoji ? "filled-account": ""
|
||||
letterSize: 14
|
||||
isLetterIdenticon: !!walletStore.currentAccount.emoji
|
||||
isLetterIdenticon: !!root.account && !!root.account.emoji
|
||||
bgWidth: 40
|
||||
bgHeight: 40
|
||||
bgColor: Theme.palette.primaryColor3
|
||||
|
@ -59,7 +60,7 @@ Item {
|
|||
StatusBaseText {
|
||||
objectName: "walletAccountViewAccountName"
|
||||
id: accountName
|
||||
text: walletStore.currentAccount.name
|
||||
text:root.account ? root.account.name : ""
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 28
|
||||
color: Theme.palette.directColor1
|
||||
|
@ -76,7 +77,7 @@ Item {
|
|||
}
|
||||
}
|
||||
StatusAddressPanel {
|
||||
value: walletStore.currentAccount.address
|
||||
value: root.account ? root.account.address : ""
|
||||
|
||||
font.weight: Font.Normal
|
||||
|
||||
|
@ -98,7 +99,10 @@ Item {
|
|||
maxWidth: parent.width
|
||||
primaryText: qsTr("Type")
|
||||
secondaryText: {
|
||||
const walletType = walletStore.currentAccount.walletType
|
||||
if (!root.account) {
|
||||
return ""
|
||||
}
|
||||
const walletType = root.account.walletType
|
||||
if (walletType === "watch") {
|
||||
return qsTr("Watch-Only Account")
|
||||
} else if (walletType === "generated" || walletType === "") {
|
||||
|
@ -118,15 +122,15 @@ Item {
|
|||
InformationTile {
|
||||
maxWidth: parent.width
|
||||
primaryText: qsTr("Derivation Path")
|
||||
secondaryText: walletStore.currentAccount.path
|
||||
visible: walletStore.currentAccount.path
|
||||
secondaryText: root.account ? root.account.path : ""
|
||||
visible: !!root.account && root.account.path
|
||||
}
|
||||
|
||||
InformationTile {
|
||||
maxWidth: parent.width
|
||||
visible: walletStore.currentAccount.relatedAccounts.count > 0
|
||||
visible:root.account ? root.account.relatedAccounts.count > 0 : false
|
||||
primaryText: qsTr("Related Accounts")
|
||||
tagsModel: walletStore.currentAccount.relatedAccounts
|
||||
tagsModel: root.account ? root.account.relatedAccounts : []
|
||||
tagsDelegate: StatusListItemTag {
|
||||
bgColor: model.color
|
||||
bgRadius: 6
|
||||
|
@ -144,20 +148,20 @@ Item {
|
|||
|
||||
StatusButton {
|
||||
objectName: "deleteAccountButton"
|
||||
visible: walletStore.currentAccount.walletType !== ""
|
||||
visible: !!root.account && root.account.walletType !== ""
|
||||
text: qsTr("Remove from your profile")
|
||||
type: StatusBaseButton.Type.Danger
|
||||
|
||||
ConfirmationDialog {
|
||||
id: confirmationPopup
|
||||
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.")
|
||||
confirmButtonLabel: qsTr("Remove Account")
|
||||
onConfirmButtonClicked: {
|
||||
confirmationPopup.close();
|
||||
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 {
|
||||
id: renameAccountModalComponent
|
||||
RenameAccontModal {
|
||||
account: root.account
|
||||
anchors.centerIn: parent
|
||||
onClosed: destroy()
|
||||
walletStore: root.walletStore
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import utils 1.0
|
||||
import shared.status 1.0
|
||||
|
@ -17,7 +18,7 @@ Column {
|
|||
property WalletStore walletStore
|
||||
|
||||
signal goToNetworksView()
|
||||
signal goToAccountView(address: string)
|
||||
signal goToAccountView(var account)
|
||||
signal goToDappPermissionsView()
|
||||
|
||||
Component.onCompleted: {
|
||||
|
@ -84,11 +85,28 @@ Column {
|
|||
width: parent.width
|
||||
height: childrenRect.height
|
||||
objectName: "generatedAccounts"
|
||||
model: walletStore.generatedAccounts
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: walletStore.accounts
|
||||
filters: ExpressionFilter {
|
||||
expression: {
|
||||
return model.walletType === "generated" || model.walletType === ""
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: WalletAccountDelegate {
|
||||
account: model
|
||||
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
|
||||
topPadding: Style.current.halfPadding
|
||||
bottomPadding: Style.current.halfPadding/2
|
||||
visible: walletStore.importedAccounts.count > 0
|
||||
visible: importedAccounts.count > 0
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: walletStore.importedAccounts
|
||||
model: importedAccounts
|
||||
delegate: WalletAccountDelegate {
|
||||
account: model
|
||||
onGoToAccountView: {
|
||||
root.goToAccountView(model.address)
|
||||
root.goToAccountView(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: watchOnlyAccounts
|
||||
sourceModel: walletStore.accounts
|
||||
filters: ValueFilter {
|
||||
roleName: "walletType"
|
||||
value: "watch"
|
||||
}
|
||||
}
|
||||
|
||||
StatusSectionHeadline {
|
||||
text: qsTr("Watch-Only")
|
||||
leftPadding: Style.current.padding
|
||||
topPadding: Style.current.halfPadding
|
||||
bottomPadding: Style.current.halfPadding/2
|
||||
visible: walletStore.watchOnlyAccounts.count > 0
|
||||
visible: watchOnlyAccounts.count > 0
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: walletStore.watchOnlyAccounts
|
||||
model: watchOnlyAccounts
|
||||
delegate: WalletAccountDelegate {
|
||||
account: model
|
||||
onGoToAccountView: {
|
||||
root.goToAccountView(model.address)
|
||||
root.goToAccountView(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import shared.status 1.0
|
||||
import StatusQ.Controls 0.1
|
||||
|
@ -23,7 +24,13 @@ Item {
|
|||
|
||||
Repeater {
|
||||
id: layer1List
|
||||
model: walletStore.layer1Networks
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: walletStore.networks
|
||||
filters: ValueFilter {
|
||||
roleName: "layer"
|
||||
value: 1
|
||||
}
|
||||
}
|
||||
delegate: WalletNetworkDelegate {
|
||||
network: model
|
||||
}
|
||||
|
@ -39,28 +46,16 @@ Item {
|
|||
|
||||
Repeater {
|
||||
id: layer2List
|
||||
model: walletStore.layer2Networks
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: walletStore.networks
|
||||
filters: ValueFilter {
|
||||
roleName: "layer"
|
||||
value: 2
|
||||
}
|
||||
}
|
||||
delegate: WalletNetworkDelegate {
|
||||
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