onboarding process updated, import account feature handled
This commit is contained in:
parent
e9bb9b256e
commit
30f11c06d4
|
@ -42,6 +42,7 @@ proc load*(self: AppController)
|
||||||
|
|
||||||
# Startup Module Delegate Interface
|
# Startup Module Delegate Interface
|
||||||
proc startupDidLoad*(self: AppController)
|
proc startupDidLoad*(self: AppController)
|
||||||
|
proc accountCreated*(self: AppController)
|
||||||
|
|
||||||
# Main Module Delegate Interface
|
# Main Module Delegate Interface
|
||||||
proc mainDidLoad*(self: AppController)
|
proc mainDidLoad*(self: AppController)
|
||||||
|
@ -95,12 +96,14 @@ proc delete*(self: AppController) =
|
||||||
|
|
||||||
proc startupDidLoad*(self: AppController) =
|
proc startupDidLoad*(self: AppController) =
|
||||||
echo "StartupDidLoad"
|
echo "StartupDidLoad"
|
||||||
|
singletonInstance.engine.load(newQUrl("qrc:///main.qml"))
|
||||||
# self.login.init()
|
# self.login.init()
|
||||||
# self.onboarding.init()
|
# self.onboarding.init()
|
||||||
|
|
||||||
proc mainDidLoad*(self: AppController) =
|
proc mainDidLoad*(self: AppController) =
|
||||||
# This to will be adapted to appropriate modules later:
|
# This to will be adapted to appropriate modules later:
|
||||||
self.appService.onLoggedIn()
|
self.appService.onLoggedIn()
|
||||||
|
self.startupModule.moveToAppState()
|
||||||
|
|
||||||
# Reset login and onboarding to remove any mnemonic that would have been saved in the accounts list
|
# Reset login and onboarding to remove any mnemonic that would have been saved in the accounts list
|
||||||
# self.login.reset()
|
# self.login.reset()
|
||||||
|
@ -121,4 +124,8 @@ proc load*(self: AppController) =
|
||||||
self.chatService.init()
|
self.chatService.init()
|
||||||
self.communityService.init()
|
self.communityService.init()
|
||||||
|
|
||||||
self.mainModule.load()
|
self.mainModule.load()
|
||||||
|
|
||||||
|
proc accountCreated*(self: AppController) =
|
||||||
|
echo "AppController account created"
|
||||||
|
self.load()
|
|
@ -1,29 +1,29 @@
|
||||||
import Tables
|
import Tables
|
||||||
|
|
||||||
import controller_interface
|
import controller_interface
|
||||||
|
import io_interface
|
||||||
|
|
||||||
import ../../../app_service/service/accounts/service_interface as accounts_service
|
import ../../../app_service/service/accounts/service_interface as accounts_service
|
||||||
|
|
||||||
export controller_interface
|
export controller_interface
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller*[T: controller_interface.DelegateInterface] =
|
Controller* = ref object of controller_interface.AccessInterface
|
||||||
ref object of controller_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
delegate: T
|
|
||||||
accountsService: accounts_service.ServiceInterface
|
accountsService: accounts_service.ServiceInterface
|
||||||
|
|
||||||
proc newController*[T](delegate: T,
|
proc newController*(delegate: io_interface.AccessInterface,
|
||||||
accountsService: accounts_service.ServiceInterface):
|
accountsService: accounts_service.ServiceInterface):
|
||||||
Controller[T] =
|
Controller =
|
||||||
result = Controller[T]()
|
result = Controller()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.accountsService = accountsService
|
result.accountsService = accountsService
|
||||||
|
|
||||||
method delete*[T](self: Controller[T]) =
|
method delete*(self: Controller) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method init*[T](self: Controller[T]) =
|
method init*(self: Controller) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method shouldStartWithOnboardingScreen*[T](self: Controller[T]): bool =
|
method shouldStartWithOnboardingScreen*(self: Controller): bool =
|
||||||
return self.accountsService.openedAccounts().len > 0
|
return self.accountsService.openedAccounts().len == 0
|
|
@ -10,9 +10,4 @@ method init*(self: AccessInterface) {.base.} =
|
||||||
|
|
||||||
method shouldStartWithOnboardingScreen*(self: AccessInterface): bool {.base.} =
|
method shouldStartWithOnboardingScreen*(self: AccessInterface): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
type
|
|
||||||
## Abstract class (concept) which must be implemented by object/s used in this
|
|
||||||
## module.
|
|
||||||
DelegateInterface* = concept c
|
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
type
|
# Defines how parent module accesses this module
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
include ./private_interfaces/module_base_interface
|
||||||
## Abstract class for any input/interaction with this module.
|
include ./private_interfaces/module_access_interface
|
||||||
|
|
||||||
method delete*(self: AccessInterface) {.base.} =
|
# Defines how this module view communicates with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
include ./private_interfaces/module_view_delegate_interface
|
||||||
|
|
||||||
method load*(self: AccessInterface) {.base.} =
|
# Defines how this controller communicates with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
include ./private_interfaces/module_controller_delegate_interface
|
||||||
|
|
||||||
# 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")
|
|
||||||
|
|
||||||
|
# Defines how submodules of this module communicate with this module
|
||||||
|
include ./private_interfaces/module_onboarding_delegate_interface
|
||||||
|
include ./private_interfaces/module_login_delegate_interface
|
||||||
|
|
||||||
|
# This way (using concepts) is used only for the modules managed by AppController
|
||||||
type
|
type
|
||||||
## Abstract class (concept) which must be implemented by object/s used in this
|
|
||||||
## module.
|
|
||||||
DelegateInterface* = concept c
|
DelegateInterface* = concept c
|
||||||
c.startupDidLoad()
|
c.startupDidLoad()
|
||||||
|
c.accountCreated()
|
|
@ -0,0 +1,63 @@
|
||||||
|
import NimQml
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type AccountItem* = ref object of QObject
|
||||||
|
name: string
|
||||||
|
identicon: string
|
||||||
|
keyUid: string
|
||||||
|
thumbnailImage: string
|
||||||
|
largeImage: string
|
||||||
|
|
||||||
|
proc setup(self: AccountItem) =
|
||||||
|
self.QObject.setup
|
||||||
|
|
||||||
|
proc delete*(self: AccountItem) =
|
||||||
|
self.QObject.delete
|
||||||
|
|
||||||
|
proc setAccountItemData*(self: AccountItem, name, identicon, keyUid,
|
||||||
|
thumbnailImage, largeImage: string) =
|
||||||
|
self.name = name
|
||||||
|
self.identicon = identicon
|
||||||
|
self.keyUid = keyUid
|
||||||
|
self.thumbnailImage = thumbnailImage
|
||||||
|
self.largeImage = largeImage
|
||||||
|
|
||||||
|
proc newAccountItem*(): AccountItem =
|
||||||
|
new(result, delete)
|
||||||
|
result.setup
|
||||||
|
|
||||||
|
proc newAccountItem*(name, identicon, keyUid, thumbnailImage,
|
||||||
|
largeImage: string): AccountItem =
|
||||||
|
new(result, delete)
|
||||||
|
result.setup
|
||||||
|
result.setAccountItemData(name, identicon, keyUid, thumbnailImage, largeImage)
|
||||||
|
|
||||||
|
proc getName(self: AccountItem): string {.slot.} =
|
||||||
|
result = self.name
|
||||||
|
|
||||||
|
QtProperty[string] name:
|
||||||
|
read = getName
|
||||||
|
|
||||||
|
proc getIdenticon(self: AccountItem): string {.slot.} =
|
||||||
|
result = self.identicon
|
||||||
|
|
||||||
|
QtProperty[string] identicon:
|
||||||
|
read = getIdenticon
|
||||||
|
|
||||||
|
proc getKeyUid(self: AccountItem): string {.slot.} =
|
||||||
|
result = self.keyUid
|
||||||
|
|
||||||
|
QtProperty[string] keyUid:
|
||||||
|
read = getKeyUid
|
||||||
|
|
||||||
|
proc getThumbnailImage(self: AccountItem): string {.slot.} =
|
||||||
|
result = self.thumbnailImage
|
||||||
|
|
||||||
|
QtProperty[string] thumbnailImage:
|
||||||
|
read = getThumbnailImage
|
||||||
|
|
||||||
|
proc getLargeImage(self: AccountItem): string {.slot.} =
|
||||||
|
result = self.largeImage
|
||||||
|
|
||||||
|
QtProperty[string] largeImage:
|
||||||
|
read = getLargeImage
|
|
@ -1,6 +1,7 @@
|
||||||
import Tables
|
import Tables
|
||||||
|
|
||||||
import controller_interface
|
import controller_interface
|
||||||
|
import io_interface
|
||||||
|
|
||||||
import status/[signals]
|
import status/[signals]
|
||||||
import ../../../../app_service/[main]
|
import ../../../../app_service/[main]
|
||||||
|
@ -9,25 +10,27 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
||||||
export controller_interface
|
export controller_interface
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller*[T: controller_interface.DelegateInterface] =
|
Controller* = ref object of controller_interface.AccessInterface
|
||||||
ref object of controller_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
delegate: T
|
|
||||||
appService: AppService
|
appService: AppService
|
||||||
accountsService: accounts_service.ServiceInterface
|
accountsService: accounts_service.ServiceInterface
|
||||||
|
|
||||||
proc newController*[T](delegate: T,
|
proc newController*(delegate: io_interface.AccessInterface,
|
||||||
appService: AppService,
|
appService: AppService,
|
||||||
accountsService: accounts_service.ServiceInterface):
|
accountsService: accounts_service.ServiceInterface):
|
||||||
Controller[T] =
|
Controller =
|
||||||
result = Controller[T]()
|
result = Controller()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.appService = appService
|
result.appService = appService
|
||||||
result.accountsService = accountsService
|
result.accountsService = accountsService
|
||||||
|
|
||||||
method delete*[T](self: Controller[T]) =
|
method delete*(self: Controller) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method init*[T](self: Controller[T]) =
|
method getOpenedAccounts*(self: Controller): seq[AccountDto] =
|
||||||
|
return self.accountsService.openedAccounts()
|
||||||
|
|
||||||
|
method init*(self: Controller) =
|
||||||
self.appService.status.events.on(SignalType.NodeStopped.event) do(e:Args):
|
self.appService.status.events.on(SignalType.NodeStopped.event) do(e:Args):
|
||||||
echo "-NEW-LOGIN-- NodeStopped: ", repr(e)
|
echo "-NEW-LOGIN-- NodeStopped: ", repr(e)
|
||||||
#self.status.events.emit("nodeStopped", Args())
|
#self.status.events.emit("nodeStopped", Args())
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#import ../../../../app_service/service/community/service_interface as community_service
|
import ../../../../app_service/service/accounts/service_interface
|
||||||
|
|
||||||
type
|
type
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
@ -9,10 +9,6 @@ method delete*(self: AccessInterface) {.base.} =
|
||||||
|
|
||||||
method init*(self: AccessInterface) {.base.} =
|
method init*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getOpenedAccounts*(self: AccessInterface): seq[AccountDto] {.base.} =
|
||||||
type
|
raise newException(ValueError, "No implementation available")
|
||||||
## Abstract class (concept) which must be implemented by object/s used in this
|
|
||||||
## module.
|
|
||||||
DelegateInterface* = concept c
|
|
||||||
|
|
|
@ -1,24 +1,12 @@
|
||||||
type
|
# Defines how parent module accesses this module
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
include ./private_interfaces/module_base_interface
|
||||||
## Abstract class for any input/interaction with this module.
|
include ./private_interfaces/module_access_interface
|
||||||
|
|
||||||
method delete*(self: AccessInterface) {.base.} =
|
# Defines how this module view communicates with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
include ./private_interfaces/module_view_delegate_interface
|
||||||
|
|
||||||
method load*(self: AccessInterface) {.base.} =
|
# Defines how this controller communicates with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
include ./private_interfaces/module_controller_delegate_interface
|
||||||
|
|
||||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
# Defines how submodules of this module communicate with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
# will be added if needed
|
||||||
|
|
||||||
# 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")
|
|
||||||
|
|
||||||
type
|
|
||||||
## Abstract class (concept) which must be implemented by object/s used in this
|
|
||||||
## module.
|
|
||||||
DelegateInterface* = concept c
|
|
||||||
c.loginDidLoad()
|
|
|
@ -1,21 +0,0 @@
|
||||||
import NimQml
|
|
||||||
|
|
||||||
QtObject:
|
|
||||||
type
|
|
||||||
Item* = ref object of QObject
|
|
||||||
|
|
||||||
proc setup(self: Item) =
|
|
||||||
self.QObject.setup
|
|
||||||
|
|
||||||
proc delete*(self: Item) =
|
|
||||||
self.QObject.delete
|
|
||||||
|
|
||||||
proc newItem*(): Item =
|
|
||||||
new(result, delete)
|
|
||||||
result.setup()
|
|
||||||
|
|
||||||
proc id*(self: Item): string {.slot.} =
|
|
||||||
self.id
|
|
||||||
|
|
||||||
QtProperty[string] id:
|
|
||||||
read = id
|
|
|
@ -1,17 +1,60 @@
|
||||||
import NimQml
|
import NimQml, Tables, strutils, strformat
|
||||||
import item
|
|
||||||
|
import account_item
|
||||||
|
|
||||||
|
type
|
||||||
|
ModelRole {.pure.} = enum
|
||||||
|
Account = UserRole + 1
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
Model* = ref object of QAbstractListModel
|
Model* = ref object of QAbstractListModel
|
||||||
sections: seq[Item]
|
items: seq[AccountItem]
|
||||||
|
|
||||||
proc setup(self: Model) =
|
proc delete(self: Model) =
|
||||||
self.QAbstractListModel.setup
|
self.items = @[]
|
||||||
|
|
||||||
proc delete*(self: Model) =
|
|
||||||
self.QAbstractListModel.delete
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc setup(self: Model) =
|
||||||
|
self.QAbstractListModel.setup
|
||||||
|
|
||||||
proc newModel*(): Model =
|
proc newModel*(): Model =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.setup
|
result.setup
|
||||||
|
|
||||||
|
proc countChanged*(self: Model) {.signal.}
|
||||||
|
|
||||||
|
proc count*(self: Model): int {.slot.} =
|
||||||
|
self.items.len
|
||||||
|
|
||||||
|
QtProperty[int] count:
|
||||||
|
read = count
|
||||||
|
notify = countChanged
|
||||||
|
|
||||||
|
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||||
|
return self.items.len
|
||||||
|
|
||||||
|
method roleNames(self: Model): Table[int, string] =
|
||||||
|
{
|
||||||
|
ModelRole.Account.int:"account"
|
||||||
|
}.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.Account:
|
||||||
|
result = newQVariant(item)
|
||||||
|
|
||||||
|
proc setItems*(self: Model, items: seq[AccountItem]) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.items = items
|
||||||
|
self.endResetModel()
|
||||||
|
self.countChanged()
|
|
@ -1,5 +1,7 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
import io_interface, view, controller
|
import io_interface
|
||||||
|
import ../io_interface as delegate_interface
|
||||||
|
import view, controller, account_item
|
||||||
import ../../../../app/boot/global_singleton
|
import ../../../../app/boot/global_singleton
|
||||||
|
|
||||||
import ../../../../app_service/[main]
|
import ../../../../app_service/[main]
|
||||||
|
@ -8,42 +10,68 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
||||||
export io_interface
|
export io_interface
|
||||||
|
|
||||||
type
|
type
|
||||||
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
Module* = ref object of io_interface.AccessInterface
|
||||||
delegate: T
|
delegate: delegate_interface.AccessInterface
|
||||||
view: View
|
view: View
|
||||||
viewVariant: QVariant
|
viewVariant: QVariant
|
||||||
controller: controller.AccessInterface
|
controller: controller.AccessInterface
|
||||||
moduleLoaded: bool
|
moduleLoaded: bool
|
||||||
|
|
||||||
proc newModule*[T](delegate: T,
|
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||||
appService: AppService,
|
appService: AppService,
|
||||||
accountsService: accounts_service.ServiceInterface):
|
accountsService: accounts_service.ServiceInterface):
|
||||||
Module[T] =
|
Module =
|
||||||
result = Module[T]()
|
result = Module()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.view = view.newView(result)
|
result.view = view.newView(result)
|
||||||
result.viewVariant = newQVariant(result.view)
|
result.viewVariant = newQVariant(result.view)
|
||||||
result.controller = controller.newController[Module[T]](result, appService,
|
result.controller = controller.newController(result, appService, accountsService)
|
||||||
accountsService)
|
|
||||||
result.moduleLoaded = false
|
result.moduleLoaded = false
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("loginModule", result.viewVariant)
|
singletonInstance.engine.setRootContextProperty("loginModule", result.viewVariant)
|
||||||
|
|
||||||
method delete*[T](self: Module[T]) =
|
method delete*(self: Module) =
|
||||||
self.view.delete
|
self.view.delete
|
||||||
self.viewVariant.delete
|
self.viewVariant.delete
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
|
|
||||||
method load*[T](self: Module[T]) =
|
proc extractImages(self: Module, account: AccountDto, thumbnailImage: var string,
|
||||||
|
largeImage: var string) =
|
||||||
|
for img in account.images:
|
||||||
|
if(img.imgType == "thumbnail"):
|
||||||
|
thumbnailImage = img.uri
|
||||||
|
elif(img.imgType == "large"):
|
||||||
|
largeImage = img.uri
|
||||||
|
|
||||||
|
method load*(self: Module) =
|
||||||
singletonInstance.engine.setRootContextProperty("loginModule", self.viewVariant)
|
singletonInstance.engine.setRootContextProperty("loginModule", self.viewVariant)
|
||||||
self.controller.init()
|
self.controller.init()
|
||||||
self.view.load()
|
self.view.load()
|
||||||
|
|
||||||
self.moduleLoaded = true
|
let openedAccounts = self.controller.getOpenedAccounts()
|
||||||
self.delegate.loginDidLoad()
|
if(openedAccounts.len > 0):
|
||||||
|
var accounts: seq[AccountItem]
|
||||||
|
for acc in openedAccounts:
|
||||||
|
var thumbnailImage: string
|
||||||
|
var largeImage: string
|
||||||
|
self.extractImages(acc, thumbnailImage, largeImage)
|
||||||
|
accounts.add(newAccountItem(acc.name, acc.identicon, acc.keyUid,
|
||||||
|
thumbnailImage, largeImage))
|
||||||
|
|
||||||
method isLoaded*[T](self: Module[T]): bool =
|
self.view.setAccountsList(accounts)
|
||||||
|
|
||||||
|
# set the first account as a slected one
|
||||||
|
let selected = openedAccounts[0]
|
||||||
|
var thumbnailImage: string
|
||||||
|
var largeImage: string
|
||||||
|
self.extractImages(selected, thumbnailImage, largeImage)
|
||||||
|
|
||||||
|
self.view.setSelectedAccount(selected.name, selected.identicon, selected.keyUid,
|
||||||
|
thumbnailImage, largeImage)
|
||||||
|
|
||||||
|
method isLoaded*(self: Module): bool =
|
||||||
return self.moduleLoaded
|
return self.moduleLoaded
|
||||||
|
|
||||||
method viewDidLoad*(self: Module) =
|
method viewDidLoad*(self: Module) =
|
||||||
discard
|
self.moduleLoaded = true
|
||||||
|
self.delegate.loginDidLoad()
|
|
@ -0,0 +1,5 @@
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
|
||||||
|
# Since nim doesn't support using concepts in second level nested types we
|
||||||
|
# define delegate interfaces within access interface.
|
|
@ -0,0 +1,2 @@
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -1,22 +1,59 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
import model
|
import account_item, model
|
||||||
import io_interface
|
import io_interface
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
View* = ref object of QObject
|
View* = ref object of QObject
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
|
selectedAccount: AccountItem
|
||||||
|
selectedAccountVariant: QVariant
|
||||||
model: Model
|
model: Model
|
||||||
|
modelVariant: QVariant
|
||||||
|
|
||||||
proc delete*(self: View) =
|
proc delete*(self: View) =
|
||||||
|
self.selectedAccount.delete
|
||||||
|
self.selectedAccountVariant.delete
|
||||||
self.model.delete
|
self.model.delete
|
||||||
|
self.modelVariant.delete
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.QObject.setup
|
result.QObject.setup
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
|
result.selectedAccount = newAccountItem()
|
||||||
|
result.selectedAccountVariant = newQVariant(result.selectedAccount)
|
||||||
result.model = newModel()
|
result.model = newModel()
|
||||||
|
result.modelVariant = newQVariant(result.model)
|
||||||
|
|
||||||
proc load*(self: View) =
|
proc load*(self: View) =
|
||||||
self.delegate.viewDidLoad()
|
self.delegate.viewDidLoad()
|
||||||
|
|
||||||
|
proc selectedAccountChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc getSelectedAccount(self: View): QVariant {.slot.} =
|
||||||
|
return self.selectedAccountVariant
|
||||||
|
|
||||||
|
proc setSelectedAccount*(self: View, name, identicon, keyUid, thumbnailImage,
|
||||||
|
largeImage: string) =
|
||||||
|
self.selectedAccount.setAccountItemData(name, identicon, keyUid, thumbnailImage,
|
||||||
|
largeImage)
|
||||||
|
self.selectedAccountChanged()
|
||||||
|
|
||||||
|
QtProperty[QVariant] selectedAccount:
|
||||||
|
read = getSelectedAccount
|
||||||
|
notify = selectedAccountChanged
|
||||||
|
|
||||||
|
proc modelChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc getModel(self: View): QVariant {.slot.} =
|
||||||
|
return self.modelVariant
|
||||||
|
|
||||||
|
proc setAccountsList*(self: View, accounts: seq[AccountItem]) =
|
||||||
|
self.model.setItems(accounts)
|
||||||
|
self.modelChanged()
|
||||||
|
|
||||||
|
QtProperty[QVariant] accountsModel:
|
||||||
|
read = getModel
|
||||||
|
notify = modelChanged
|
|
@ -1,6 +1,7 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
|
|
||||||
import io_interface, view, controller
|
import io_interface
|
||||||
|
import view, controller
|
||||||
import ../../../app/boot/global_singleton
|
import ../../../app/boot/global_singleton
|
||||||
|
|
||||||
import onboarding/module as onboarding_module
|
import onboarding/module as onboarding_module
|
||||||
|
@ -20,20 +21,6 @@ type
|
||||||
onboardingModule: onboarding_module.AccessInterface
|
onboardingModule: onboarding_module.AccessInterface
|
||||||
loginModule: login_module.AccessInterface
|
loginModule: login_module.AccessInterface
|
||||||
|
|
||||||
#################################################
|
|
||||||
# Forward declaration section
|
|
||||||
|
|
||||||
# Controller Delegate Interface
|
|
||||||
|
|
||||||
|
|
||||||
# Onboarding Module Delegate Interface
|
|
||||||
proc onboardingDidLoad*[T](self: Module[T])
|
|
||||||
|
|
||||||
# Login Module Delegate Interface
|
|
||||||
proc loginDidLoad*[T](self: Module[T])
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
|
|
||||||
proc newModule*[T](delegate: T,
|
proc newModule*[T](delegate: T,
|
||||||
appService: AppService,
|
appService: AppService,
|
||||||
accountsService: accounts_service.ServiceInterface):
|
accountsService: accounts_service.ServiceInterface):
|
||||||
|
@ -42,13 +29,11 @@ proc newModule*[T](delegate: T,
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.view = view.newView(result)
|
result.view = view.newView(result)
|
||||||
result.viewVariant = newQVariant(result.view)
|
result.viewVariant = newQVariant(result.view)
|
||||||
result.controller = controller.newController[Module[T]](result, accountsService)
|
result.controller = controller.newController(result, accountsService)
|
||||||
|
|
||||||
# Submodules
|
# Submodules
|
||||||
result.onboardingModule = onboarding_module.newModule[Module[T]](result,
|
result.onboardingModule = onboarding_module.newModule(result, appService, accountsService)
|
||||||
appService, accountsService)
|
result.loginModule = login_module.newModule(result, appService, accountsService)
|
||||||
result.loginModule = login_module.newModule[Module[T]](result, appService,
|
|
||||||
accountsService)
|
|
||||||
|
|
||||||
method delete*[T](self: Module[T]) =
|
method delete*[T](self: Module[T]) =
|
||||||
self.onboardingModule.delete
|
self.onboardingModule.delete
|
||||||
|
@ -61,14 +46,15 @@ method load*[T](self: Module[T]) =
|
||||||
singletonInstance.engine.setRootContextProperty("startupModule", self.viewVariant)
|
singletonInstance.engine.setRootContextProperty("startupModule", self.viewVariant)
|
||||||
self.controller.init()
|
self.controller.init()
|
||||||
self.view.load()
|
self.view.load()
|
||||||
self.view.setStartWithOnboardingScreen(self.controller.shouldStartWithOnboardingScreen())
|
|
||||||
|
var initialAppState = AppState.OnboardingState
|
||||||
|
if(not self.controller.shouldStartWithOnboardingScreen()):
|
||||||
|
initialAppState = AppState.LoginState
|
||||||
|
self.view.setAppState(initialAppState)
|
||||||
|
|
||||||
self.onboardingModule.load()
|
self.onboardingModule.load()
|
||||||
self.loginModule.load()
|
self.loginModule.load()
|
||||||
|
|
||||||
method viewDidLoad*[T](self: Module[T]) =
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc checkIfModuleDidLoad[T](self: Module[T]) =
|
proc checkIfModuleDidLoad[T](self: Module[T]) =
|
||||||
if(not self.onboardingModule.isLoaded()):
|
if(not self.onboardingModule.isLoaded()):
|
||||||
return
|
return
|
||||||
|
@ -78,8 +64,17 @@ proc checkIfModuleDidLoad[T](self: Module[T]) =
|
||||||
|
|
||||||
self.delegate.startupDidLoad()
|
self.delegate.startupDidLoad()
|
||||||
|
|
||||||
proc onboardingDidLoad*[T](self: Module[T]) =
|
method viewDidLoad*[T](self: Module[T]) =
|
||||||
self.checkIfModuleDidLoad()
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
proc loginDidLoad*[T](self: Module[T]) =
|
method onboardingDidLoad*[T](self: Module[T]) =
|
||||||
self.checkIfModuleDidLoad()
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method loginDidLoad*[T](self: Module[T]) =
|
||||||
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method accountCreated*[T](self: Module[T]) =
|
||||||
|
self.delegate.accountCreated()
|
||||||
|
|
||||||
|
method moveToAppState*[T](self: Module[T]) =
|
||||||
|
self.view.setAppState(AppState.MainAppState)
|
|
@ -1,6 +1,7 @@
|
||||||
import Tables
|
import Tables, chronicles
|
||||||
|
|
||||||
import controller_interface
|
import controller_interface
|
||||||
|
import io_interface
|
||||||
|
|
||||||
import status/[signals]
|
import status/[signals]
|
||||||
import ../../../../app_service/[main]
|
import ../../../../app_service/[main]
|
||||||
|
@ -8,39 +9,62 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
||||||
|
|
||||||
export controller_interface
|
export controller_interface
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "onboarding-controller"
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller*[T: controller_interface.DelegateInterface] =
|
Controller* =
|
||||||
ref object of controller_interface.AccessInterface
|
ref object of controller_interface.AccessInterface
|
||||||
delegate: T
|
delegate: io_interface.AccessInterface
|
||||||
appService: AppService
|
appService: AppService
|
||||||
accountsService: accounts_service.ServiceInterface
|
accountsService: accounts_service.ServiceInterface
|
||||||
selectedAccountId: string
|
selectedAccountId: string
|
||||||
|
|
||||||
proc newController*[T](delegate: T,
|
proc newController*(delegate: io_interface.AccessInterface,
|
||||||
appService: AppService,
|
appService: AppService,
|
||||||
accountsService: accounts_service.ServiceInterface):
|
accountsService: accounts_service.ServiceInterface):
|
||||||
Controller[T] =
|
Controller =
|
||||||
result = Controller[T]()
|
result = Controller()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.appService = appService
|
result.appService = appService
|
||||||
result.accountsService = accountsService
|
result.accountsService = accountsService
|
||||||
|
|
||||||
method delete*[T](self: Controller[T]) =
|
method delete*(self: Controller) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
method init*[T](self: Controller[T]) =
|
method init*(self: Controller) =
|
||||||
self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args):
|
self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args):
|
||||||
echo "-NEW-ONBOARDING-- OnNodeLoginEvent: ", repr(e)
|
let signal = NodeSignal(e)
|
||||||
#self.handleNodeLogin(NodeSignal(e))
|
echo "-NEW-ONBOARDING-- OnNodeLoginEvent: ", repr(signal)
|
||||||
|
if signal.event.error == "":
|
||||||
|
echo "-NEW-ONBOARDING-- OnNodeLoginEventA: ", repr(signal.event.error)
|
||||||
|
self.delegate.accountCreated()
|
||||||
|
else:
|
||||||
|
error "error: ", methodName="init", errDesription = "onboarding login error " & signal.event.error
|
||||||
|
|
||||||
method getGeneratedAccounts*[T](self: Controller[T]): seq[GeneratedAccountDto] =
|
method getGeneratedAccounts*(self: Controller): seq[GeneratedAccountDto] =
|
||||||
return self.accountsService.generatedAccounts()
|
return self.accountsService.generatedAccounts()
|
||||||
|
|
||||||
method setSelectedAccountId*[T](self: Controller[T], id: string) =
|
method getImportedAccount*(self: Controller): GeneratedAccountDto =
|
||||||
self.selectedAccountId = id
|
return self.accountsService.getImportedAccount()
|
||||||
|
|
||||||
method storeSelectedAccountAndLogin*[T](self: Controller[T], password: string) =
|
method setSelectedAccountByIndex*(self: Controller, index: int) =
|
||||||
let account = self.accountsService.setupAccount(self.appService.status.fleet.config,
|
let accounts = self.getGeneratedAccounts()
|
||||||
self.selectedAccountId, password)
|
self.selectedAccountId = accounts[index].id
|
||||||
|
|
||||||
echo "RECEIVED ACCOUNT: ", repr(account)
|
method storeSelectedAccountAndLogin*(self: Controller, password: string) =
|
||||||
|
if(not self.accountsService.setupAccount(self.appService.status.fleet.config,
|
||||||
|
self.selectedAccountId, password)):
|
||||||
|
self.delegate.setupAccountError()
|
||||||
|
|
||||||
|
method validateMnemonic*(self: Controller, mnemonic: string): string =
|
||||||
|
return self.accountsService.validateMnemonic(mnemonic)
|
||||||
|
|
||||||
|
method importMnemonic*(self: Controller, mnemonic: string) =
|
||||||
|
if(self.accountsService.importMnemonic(mnemonic)):
|
||||||
|
self.selectedAccountId = self.getImportedAccount().id
|
||||||
|
self.delegate.importAccountSuccess()
|
||||||
|
else:
|
||||||
|
self.delegate.importAccountError()
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,19 @@ method getGeneratedAccounts*(self: AccessInterface):
|
||||||
seq[GeneratedAccountDto] {.base.} =
|
seq[GeneratedAccountDto] {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method setSelectedAccountId*(self: AccessInterface, id: string) {.base.} =
|
method setSelectedAccountByIndex*(self: AccessInterface, index: int) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method storeSelectedAccountAndLogin*(self: AccessInterface, password: string)
|
method storeSelectedAccountAndLogin*(self: AccessInterface, password: string)
|
||||||
{.base.} =
|
{.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getImportedAccount*(self: AccessInterface): GeneratedAccountDto {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
type
|
method validateMnemonic*(self: AccessInterface, mnemonic: string):
|
||||||
## Abstract class (concept) which must be implemented by object/s used in this
|
string {.base.} =
|
||||||
## module.
|
raise newException(ValueError, "No implementation available")
|
||||||
DelegateInterface* = concept c
|
|
||||||
|
method importMnemonic*(self: AccessInterface, mnemonic: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -1,31 +1,12 @@
|
||||||
type
|
# Defines how parent module accesses this module
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
include ./private_interfaces/module_base_interface
|
||||||
## Abstract class for any input/interaction with this module.
|
include ./private_interfaces/module_access_interface
|
||||||
|
|
||||||
method delete*(self: AccessInterface) {.base.} =
|
# Defines how this module view communicates with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
include ./private_interfaces/module_view_delegate_interface
|
||||||
|
|
||||||
method load*(self: AccessInterface) {.base.} =
|
# Defines how this controller communicates with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
include ./private_interfaces/module_controller_delegate_interface
|
||||||
|
|
||||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
# Defines how submodules of this module communicate with this module
|
||||||
raise newException(ValueError, "No implementation available")
|
# will be added if needed
|
||||||
|
|
||||||
# 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 setSelectedAccountId*(self: AccessInterface, id: string) {.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
|
||||||
|
|
||||||
method storeSelectedAccountAndLogin*(self: AccessInterface, password: string)
|
|
||||||
{.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
|
||||||
|
|
||||||
type
|
|
||||||
## Abstract class (concept) which must be implemented by object/s used in this
|
|
||||||
## module.
|
|
||||||
DelegateInterface* = concept c
|
|
||||||
c.onboardingDidLoad()
|
|
|
@ -32,7 +32,7 @@ QtObject:
|
||||||
method roleNames(self: Model): Table[int, string] =
|
method roleNames(self: Model): Table[int, string] =
|
||||||
{
|
{
|
||||||
ModelRole.Id.int:"accountId",
|
ModelRole.Id.int:"accountId",
|
||||||
ModelRole.Alias.int:"alias",
|
ModelRole.Alias.int:"username",
|
||||||
ModelRole.Identicon.int:"identicon",
|
ModelRole.Identicon.int:"identicon",
|
||||||
ModelRole.Address.int:"address",
|
ModelRole.Address.int:"address",
|
||||||
ModelRole.KeyUid.int:"keyUid"
|
ModelRole.KeyUid.int:"keyUid"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
import io_interface, view, controller, item
|
import io_interface
|
||||||
|
import ../io_interface as delegate_interface
|
||||||
|
import view, controller, item
|
||||||
import ../../../../app/boot/global_singleton
|
import ../../../../app/boot/global_singleton
|
||||||
|
|
||||||
import ../../../../app_service/[main]
|
import ../../../../app_service/[main]
|
||||||
|
@ -8,33 +10,32 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
||||||
export io_interface
|
export io_interface
|
||||||
|
|
||||||
type
|
type
|
||||||
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
Module* = ref object of io_interface.AccessInterface
|
||||||
delegate: T
|
delegate: delegate_interface.AccessInterface
|
||||||
view: View
|
view: View
|
||||||
viewVariant: QVariant
|
viewVariant: QVariant
|
||||||
controller: controller.AccessInterface
|
controller: controller.AccessInterface
|
||||||
moduleLoaded: bool
|
moduleLoaded: bool
|
||||||
|
|
||||||
proc newModule*[T](delegate: T,
|
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||||
appService: AppService,
|
appService: AppService,
|
||||||
accountsService: accounts_service.ServiceInterface):
|
accountsService: accounts_service.ServiceInterface):
|
||||||
Module[T] =
|
Module =
|
||||||
result = Module[T]()
|
result = Module()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.view = view.newView(result)
|
result.view = view.newView(result)
|
||||||
result.viewVariant = newQVariant(result.view)
|
result.viewVariant = newQVariant(result.view)
|
||||||
result.controller = controller.newController[Module[T]](result, appService,
|
result.controller = controller.newController(result, appService, accountsService)
|
||||||
accountsService)
|
|
||||||
result.moduleLoaded = false
|
result.moduleLoaded = false
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("onboardingModule", result.viewVariant)
|
singletonInstance.engine.setRootContextProperty("onboardingModule", result.viewVariant)
|
||||||
|
|
||||||
method delete*[T](self: Module[T]) =
|
method delete*(self: Module) =
|
||||||
self.view.delete
|
self.view.delete
|
||||||
self.viewVariant.delete
|
self.viewVariant.delete
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
|
|
||||||
method load*[T](self: Module[T]) =
|
method load*(self: Module) =
|
||||||
singletonInstance.engine.setRootContextProperty("onboardingModule", self.viewVariant)
|
singletonInstance.engine.setRootContextProperty("onboardingModule", self.viewVariant)
|
||||||
self.controller.init()
|
self.controller.init()
|
||||||
self.view.load()
|
self.view.load()
|
||||||
|
@ -44,19 +45,38 @@ method load*[T](self: Module[T]) =
|
||||||
for acc in generatedAccounts:
|
for acc in generatedAccounts:
|
||||||
accounts.add(initItem(acc.id, acc.alias, acc.identicon, acc.address, acc.keyUid))
|
accounts.add(initItem(acc.id, acc.alias, acc.identicon, acc.address, acc.keyUid))
|
||||||
|
|
||||||
self.view.setAccountList(accounts)
|
self.view.setAccountList(accounts)
|
||||||
|
|
||||||
self.moduleLoaded = true
|
method isLoaded*(self: Module): bool =
|
||||||
self.delegate.onboardingDidLoad()
|
|
||||||
|
|
||||||
method isLoaded*[T](self: Module[T]): bool =
|
|
||||||
return self.moduleLoaded
|
return self.moduleLoaded
|
||||||
|
|
||||||
method viewDidLoad*(self: Module) =
|
method viewDidLoad*(self: Module) =
|
||||||
discard
|
self.moduleLoaded = true
|
||||||
|
self.delegate.onboardingDidLoad()
|
||||||
|
|
||||||
method setSelectedAccountId*[T](self: Module[T], id: string) =
|
method setSelectedAccountByIndex*(self: Module, index: int) =
|
||||||
self.controller.setSelectedAccountId(id)
|
self.controller.setSelectedAccountByIndex(index)
|
||||||
|
|
||||||
method storeSelectedAccountAndLogin*[T](self: Module[T], password: string) =
|
method storeSelectedAccountAndLogin*(self: Module, password: string) =
|
||||||
self.controller.storeSelectedAccountAndLogin(password)
|
self.controller.storeSelectedAccountAndLogin(password)
|
||||||
|
|
||||||
|
method accountCreated*(self: Module) =
|
||||||
|
self.delegate.accountCreated()
|
||||||
|
|
||||||
|
method setupAccountError*(self: Module) =
|
||||||
|
self.view.setupAccountError()
|
||||||
|
|
||||||
|
method getImportedAccount*(self: Module): GeneratedAccountDto =
|
||||||
|
return self.controller.getImportedAccount()
|
||||||
|
|
||||||
|
method validateMnemonic*(self: Module, mnemonic: string): string =
|
||||||
|
return self.controller.validateMnemonic(mnemonic)
|
||||||
|
|
||||||
|
method importMnemonic*(self: Module, mnemonic: string) =
|
||||||
|
self.controller.importMnemonic(mnemonic)
|
||||||
|
|
||||||
|
method importAccountError*(self: Module) =
|
||||||
|
self.view.importAccountError()
|
||||||
|
|
||||||
|
method importAccountSuccess*(self: Module) =
|
||||||
|
self.view.importAccountSuccess()
|
|
@ -0,0 +1,5 @@
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
|
||||||
|
# Since nim doesn't support using concepts in second level nested types we
|
||||||
|
# define delegate interfaces within access interface.
|
|
@ -0,0 +1,11 @@
|
||||||
|
method accountCreated*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method setupAccountError*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method importAccountError*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method importAccountSuccess*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,21 @@
|
||||||
|
import ../../../../../app_service/service/accounts/service_interface
|
||||||
|
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method setSelectedAccountByIndex*(self: AccessInterface, index: int) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method storeSelectedAccountAndLogin*(self: AccessInterface, password: string)
|
||||||
|
{.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getImportedAccount*(self: AccessInterface): GeneratedAccountDto {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method validateMnemonic*(self: AccessInterface, mnemonic: string):
|
||||||
|
string {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method importMnemonic*(self: AccessInterface, mnemonic: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -24,20 +24,63 @@ QtObject:
|
||||||
proc load*(self: View) =
|
proc load*(self: View) =
|
||||||
self.delegate.viewDidLoad()
|
self.delegate.viewDidLoad()
|
||||||
|
|
||||||
proc setAccountList*(self: View, accounts: seq[Item]) =
|
|
||||||
self.model.setItems(accounts)
|
|
||||||
|
|
||||||
proc modelChanged*(self: View) {.signal.}
|
proc modelChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
proc getModel(self: View): QVariant {.slot.} =
|
proc getModel(self: View): QVariant {.slot.} =
|
||||||
return self.modelVariant
|
return self.modelVariant
|
||||||
|
|
||||||
|
proc setAccountList*(self: View, accounts: seq[Item]) =
|
||||||
|
self.model.setItems(accounts)
|
||||||
|
self.modelChanged()
|
||||||
|
|
||||||
QtProperty[QVariant] accountsModel:
|
QtProperty[QVariant] accountsModel:
|
||||||
read = getModel
|
read = getModel
|
||||||
notify = modelChanged
|
notify = modelChanged
|
||||||
|
|
||||||
proc setSelectedAccountId*(self: View, id: string) {.slot.} =
|
proc importedAccountChanged*(self: View) {.signal.}
|
||||||
self.delegate.setSelectedAccountId(id)
|
|
||||||
|
proc getImportedAccountIdenticon*(self: View): string {.slot.} =
|
||||||
|
return self.delegate.getImportedAccount().identicon
|
||||||
|
|
||||||
|
QtProperty[string] importedAccountIdenticon:
|
||||||
|
read = getImportedAccountIdenticon
|
||||||
|
notify = importedAccountChanged
|
||||||
|
|
||||||
|
proc getImportedAccountAlias*(self: View): string {.slot.} =
|
||||||
|
return self.delegate.getImportedAccount().alias
|
||||||
|
|
||||||
|
QtProperty[string] importedAccountAlias:
|
||||||
|
read = getImportedAccountAlias
|
||||||
|
notify = importedAccountChanged
|
||||||
|
|
||||||
|
proc getImportedAccountAddress*(self: View): string {.slot.} =
|
||||||
|
return self.delegate.getImportedAccount().address
|
||||||
|
|
||||||
|
QtProperty[string] importedAccountAddress:
|
||||||
|
read = getImportedAccountAddress
|
||||||
|
notify = importedAccountChanged
|
||||||
|
|
||||||
|
proc setSelectedAccountByIndex*(self: View, index: int) {.slot.} =
|
||||||
|
self.delegate.setSelectedAccountByIndex(index)
|
||||||
|
|
||||||
proc storeSelectedAccountAndLogin*(self: View, password: string) {.slot.} =
|
proc storeSelectedAccountAndLogin*(self: View, password: string) {.slot.} =
|
||||||
self.delegate.storeSelectedAccountAndLogin(password)
|
self.delegate.storeSelectedAccountAndLogin(password)
|
||||||
|
|
||||||
|
proc accountSetupError*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc setupAccountError*(self: View) =
|
||||||
|
self.accountSetupError()
|
||||||
|
|
||||||
|
proc validateMnemonic*(self: View, mnemonic: string): string {.slot.} =
|
||||||
|
return self.delegate.validateMnemonic(mnemonic)
|
||||||
|
|
||||||
|
proc importMnemonic*(self: View, mnemonic: string) {.slot.} =
|
||||||
|
self.delegate.importMnemonic(mnemonic)
|
||||||
|
|
||||||
|
proc accountImportError*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc importAccountError*(self: View) =
|
||||||
|
self.accountImportError() # In QML we can connect to this signal and notify a user
|
||||||
|
|
||||||
|
proc importAccountSuccess*(self: View) =
|
||||||
|
self.importedAccountChanged()
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method load*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method moveToAppState*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,5 @@
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
|
||||||
|
# Since nim doesn't support using concepts in second level nested types we
|
||||||
|
# define delegate interfaces within access interface.
|
|
@ -0,0 +1,2 @@
|
||||||
|
method loginDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,5 @@
|
||||||
|
method onboardingDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method accountCreated*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,2 @@
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -1,11 +1,17 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
import io_interface
|
import io_interface
|
||||||
|
|
||||||
|
type
|
||||||
|
AppState* {.pure.} = enum
|
||||||
|
OnboardingState = 0
|
||||||
|
LoginState
|
||||||
|
MainAppState
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
View* = ref object of QObject
|
View* = ref object of QObject
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
startWithOnboardingScreen: bool
|
appState: AppState
|
||||||
|
|
||||||
proc delete*(self: View) =
|
proc delete*(self: View) =
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
@ -14,24 +20,24 @@ QtObject:
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.QObject.setup
|
result.QObject.setup
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.startWithOnboardingScreen = true
|
result.appState = AppState.OnboardingState
|
||||||
|
|
||||||
proc load*(self: View) =
|
proc load*(self: View) =
|
||||||
# In some point, here, we will setup some exposed main module related things.
|
# In some point, here, we will setup some exposed main module related things.
|
||||||
self.delegate.viewDidLoad()
|
self.delegate.viewDidLoad()
|
||||||
|
|
||||||
proc startWithOnboardingScreenChanged*(self: View) {.signal.}
|
proc appStateChanged*(self: View, state: int) {.signal.}
|
||||||
|
|
||||||
proc getStartWithOnboardingScreen(self: View): bool {.slot.} =
|
proc getAppState(self: View): int {.slot.} =
|
||||||
return self.startWithOnboardingScreen
|
return self.appState.int
|
||||||
|
|
||||||
proc setStartWithOnboardingScreen*(self: View, value: bool) {.slot.} =
|
proc setAppState*(self: View, state: AppState) =
|
||||||
if(self.startWithOnboardingScreen == value):
|
if(self.appState == state):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.startWithOnboardingScreen = value
|
self.appState = state
|
||||||
self.startWithOnboardingScreenChanged()
|
self.appStateChanged(self.appState.int)
|
||||||
|
|
||||||
QtProperty[bool] startWithOnboardingScreen:
|
QtProperty[int] appState:
|
||||||
read = getStartWithOnboardingScreen
|
read = getAppState
|
||||||
notify = startWithOnboardingScreenChanged
|
notify = appStateChanged
|
|
@ -5,7 +5,7 @@ import json
|
||||||
include ../../../common/json_utils
|
include ../../../common/json_utils
|
||||||
|
|
||||||
type
|
type
|
||||||
Image* = ref object
|
Image* = object
|
||||||
keyUid*: string
|
keyUid*: string
|
||||||
imgType*: string
|
imgType*: string
|
||||||
uri*: string
|
uri*: string
|
||||||
|
@ -14,7 +14,7 @@ type
|
||||||
fileSize: int
|
fileSize: int
|
||||||
resizeTarget: int
|
resizeTarget: int
|
||||||
|
|
||||||
type AccountDto* = ref object
|
type AccountDto* = object
|
||||||
name*: string
|
name*: string
|
||||||
timestamp*: int64
|
timestamp*: int64
|
||||||
identicon*: string
|
identicon*: string
|
||||||
|
@ -22,6 +22,9 @@ type AccountDto* = ref object
|
||||||
keyUid*: string
|
keyUid*: string
|
||||||
images*: seq[Image]
|
images*: seq[Image]
|
||||||
|
|
||||||
|
proc isValid*(self: AccountDto): bool =
|
||||||
|
result = self.name.len > 0 and self.keyUid.len > 0
|
||||||
|
|
||||||
proc toImage(jsonObj: JsonNode): Image =
|
proc toImage(jsonObj: JsonNode): Image =
|
||||||
result = Image()
|
result = Image()
|
||||||
discard jsonObj.getProp("keyUid", result.keyUid)
|
discard jsonObj.getProp("keyUid", result.keyUid)
|
||||||
|
|
|
@ -17,7 +17,7 @@ type DerivedAccounts* = object
|
||||||
defaultWallet*: DerivedAccountDetails
|
defaultWallet*: DerivedAccountDetails
|
||||||
eip1581*: DerivedAccountDetails
|
eip1581*: DerivedAccountDetails
|
||||||
|
|
||||||
type GeneratedAccountDto* = ref object
|
type GeneratedAccountDto* = object
|
||||||
id*: string
|
id*: string
|
||||||
publicKey*: string
|
publicKey*: string
|
||||||
address*: string
|
address*: string
|
||||||
|
@ -28,6 +28,10 @@ type GeneratedAccountDto* = ref object
|
||||||
alias*: string
|
alias*: string
|
||||||
identicon*: string
|
identicon*: string
|
||||||
|
|
||||||
|
proc isValid*(self: GeneratedAccountDto): bool =
|
||||||
|
result = self.id.len > 0 and self.publicKey.len > 0 and
|
||||||
|
self.address.len > 0 and self.keyUid.len > 0
|
||||||
|
|
||||||
proc toDerivedAccountDetails(jsonObj: JsonNode, derivationPath: string):
|
proc toDerivedAccountDetails(jsonObj: JsonNode, derivationPath: string):
|
||||||
DerivedAccountDetails =
|
DerivedAccountDetails =
|
||||||
# Mapping this DTO is not strightforward since only keys are used for id. We
|
# Mapping this DTO is not strightforward since only keys are used for id. We
|
||||||
|
|
|
@ -4,6 +4,7 @@ import service_interface
|
||||||
import ./dto/accounts
|
import ./dto/accounts
|
||||||
import ./dto/generated_accounts
|
import ./dto/generated_accounts
|
||||||
import status/statusgo_backend_new/accounts as status_go
|
import status/statusgo_backend_new/accounts as status_go
|
||||||
|
import status/statusgo_backend_new/general as status_go_general
|
||||||
|
|
||||||
import ../../common/[account_constants, utils, string_utils]
|
import ../../common/[account_constants, utils, string_utils]
|
||||||
import ../../../constants as main_constants
|
import ../../../constants as main_constants
|
||||||
|
@ -17,12 +18,25 @@ const PATHS = @[PATH_WALLET_ROOT, PATH_EIP_1581, PATH_WHISPER, PATH_DEFAULT_WALL
|
||||||
type
|
type
|
||||||
Service* = ref object of ServiceInterface
|
Service* = ref object of ServiceInterface
|
||||||
generatedAccounts: seq[GeneratedAccountDto]
|
generatedAccounts: seq[GeneratedAccountDto]
|
||||||
|
loggedInAccount: AccountDto
|
||||||
|
importedAccount: GeneratedAccountDto
|
||||||
|
isFirstTimeAccountLogin: bool
|
||||||
|
|
||||||
method delete*(self: Service) =
|
method delete*(self: Service) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc newService*(): Service =
|
proc newService*(): Service =
|
||||||
result = Service()
|
result = Service()
|
||||||
|
result.isFirstTimeAccountLogin = false
|
||||||
|
|
||||||
|
method getLoggedInAccount*(self: Service): AccountDto =
|
||||||
|
return self.loggedInAccount
|
||||||
|
|
||||||
|
method getImportedAccount*(self: Service): GeneratedAccountDto =
|
||||||
|
return self.importedAccount
|
||||||
|
|
||||||
|
method isFirstTimeAccountLogin*(self: Service): bool =
|
||||||
|
return self.isFirstTimeAccountLogin
|
||||||
|
|
||||||
method init*(self: Service) =
|
method init*(self: Service) =
|
||||||
try:
|
try:
|
||||||
|
@ -43,6 +57,20 @@ method init*(self: Service) =
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", methodName="init", errName = e.name, errDesription = e.msg
|
error "error: ", methodName="init", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
method validateMnemonic*(self: Service, mnemonic: string): string =
|
||||||
|
try:
|
||||||
|
let response = status_go_general.validateMnemonic(mnemonic)
|
||||||
|
|
||||||
|
var error = "response doesn't contain \"error\""
|
||||||
|
if(response.result.contains("error")):
|
||||||
|
error = response.result["error"].getStr
|
||||||
|
|
||||||
|
# An empty error means that mnemonic is valid.
|
||||||
|
return error
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
error "error: ", methodName="validateMnemonic", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
method generatedAccounts*(self: Service): seq[GeneratedAccountDto] =
|
method generatedAccounts*(self: Service): seq[GeneratedAccountDto] =
|
||||||
if(self.generatedAccounts.len == 0):
|
if(self.generatedAccounts.len == 0):
|
||||||
error "There was some issue initiating account service"
|
error "There was some issue initiating account service"
|
||||||
|
@ -82,6 +110,7 @@ proc saveAccountAndLogin(self: Service, hashedPassword: string, account,
|
||||||
error = response.result["error"].getStr
|
error = response.result["error"].getStr
|
||||||
if error == "":
|
if error == "":
|
||||||
debug "Account saved succesfully"
|
debug "Account saved succesfully"
|
||||||
|
self.isFirstTimeAccountLogin = true
|
||||||
result = toAccountDto(account)
|
result = toAccountDto(account)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -91,70 +120,93 @@ proc saveAccountAndLogin(self: Service, hashedPassword: string, account,
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", methodName="saveAccountAndLogin", errName = e.name, errDesription = e.msg
|
error "error: ", methodName="saveAccountAndLogin", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
proc prepareAccountJsonObject(self: Service, account: GeneratedAccountDto): JsonNode =
|
||||||
|
result = %* {
|
||||||
|
"name": account.alias,
|
||||||
|
"address": account.address,
|
||||||
|
"identicon": account.identicon,
|
||||||
|
"key-uid": account.keyUid,
|
||||||
|
"keycard-pairing": nil
|
||||||
|
}
|
||||||
|
|
||||||
proc getAccountDataForAccountId(self: Service, accountId: string): JsonNode =
|
proc getAccountDataForAccountId(self: Service, accountId: string): JsonNode =
|
||||||
for acc in self.generatedAccounts:
|
for acc in self.generatedAccounts:
|
||||||
if(acc.id == accountId):
|
if(acc.id == accountId):
|
||||||
result = %* {
|
return self.prepareAccountJsonObject(acc)
|
||||||
"name": acc.alias,
|
|
||||||
"address": acc.address,
|
if(self.importedAccount.isValid()):
|
||||||
"identicon": acc.identicon,
|
if(self.importedAccount.id == accountId):
|
||||||
"key-uid": acc.keyUid,
|
return self.prepareAccountJsonObject(self.importedAccount)
|
||||||
"keycard-pairing": nil
|
|
||||||
}
|
proc prepareSubaccountJsonObject(self: Service, account: GeneratedAccountDto):
|
||||||
|
JsonNode =
|
||||||
|
result = %* [
|
||||||
|
{
|
||||||
|
"public-key": account.derivedAccounts.defaultWallet.publicKey,
|
||||||
|
"address": account.derivedAccounts.defaultWallet.address,
|
||||||
|
"color": "#4360df",
|
||||||
|
"wallet": true,
|
||||||
|
"path": PATH_DEFAULT_WALLET,
|
||||||
|
"name": "Status account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"public-key": account.derivedAccounts.whisper.publicKey,
|
||||||
|
"address": account.derivedAccounts.whisper.address,
|
||||||
|
"name": account.alias,
|
||||||
|
"identicon": account.identicon,
|
||||||
|
"path": PATH_WHISPER,
|
||||||
|
"chat": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
proc getSubaccountDataForAccountId(self: Service, accountId: string): JsonNode =
|
proc getSubaccountDataForAccountId(self: Service, accountId: string): JsonNode =
|
||||||
for acc in self.generatedAccounts:
|
for acc in self.generatedAccounts:
|
||||||
if(acc.id == accountId):
|
if(acc.id == accountId):
|
||||||
result = %* [
|
return self.prepareSubaccountJsonObject(acc)
|
||||||
{
|
|
||||||
"public-key": acc.derivedAccounts.defaultWallet.publicKey,
|
if(self.importedAccount.isValid()):
|
||||||
"address": acc.derivedAccounts.defaultWallet.address,
|
if(self.importedAccount.id == accountId):
|
||||||
"color": "#4360df",
|
return self.prepareSubaccountJsonObject(self.importedAccount)
|
||||||
"wallet": true,
|
|
||||||
"path": PATH_DEFAULT_WALLET,
|
|
||||||
"name": "Status account"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"public-key": acc.derivedAccounts.whisper.publicKey,
|
|
||||||
"address": acc.derivedAccounts.whisper.address,
|
|
||||||
"name": acc.alias,
|
|
||||||
"identicon": acc.identicon,
|
|
||||||
"path": PATH_WHISPER,
|
|
||||||
"chat": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
proc prepareAccountSettingsJsonObject(self: Service, account: GeneratedAccountDto,
|
||||||
|
installationId: string): JsonNode =
|
||||||
|
result = %* {
|
||||||
|
"key-uid": account.keyUid,
|
||||||
|
"mnemonic": account.mnemonic,
|
||||||
|
"public-key": account.derivedAccounts.whisper.publicKey,
|
||||||
|
"name": account.alias,
|
||||||
|
"address": account.address,
|
||||||
|
"eip1581-address": account.derivedAccounts.eip1581.address,
|
||||||
|
"dapps-address": account.derivedAccounts.defaultWallet.address,
|
||||||
|
"wallet-root-address": account.derivedAccounts.walletRoot.address,
|
||||||
|
"preview-privacy?": true,
|
||||||
|
"signing-phrase": generateSigningPhrase(3),
|
||||||
|
"log-level": "INFO",
|
||||||
|
"latest-derived-path": 0,
|
||||||
|
"networks/networks": DEFAULT_NETWORKS,
|
||||||
|
"currency": "usd",
|
||||||
|
"identicon": account.identicon,
|
||||||
|
"waku-enabled": true,
|
||||||
|
"wallet/visible-tokens": {
|
||||||
|
"mainnet": ["SNT"]
|
||||||
|
},
|
||||||
|
"appearance": 0,
|
||||||
|
"networks/current-network": DEFAULT_NETWORK_NAME,
|
||||||
|
"installation-id": installationId
|
||||||
|
}
|
||||||
|
|
||||||
proc getAccountSettings(self: Service, accountId: string,
|
proc getAccountSettings(self: Service, accountId: string,
|
||||||
installationId: string): JsonNode =
|
installationId: string): JsonNode =
|
||||||
for acc in self.generatedAccounts:
|
for acc in self.generatedAccounts:
|
||||||
if(acc.id == accountId):
|
if(acc.id == accountId):
|
||||||
result = %* {
|
return self.prepareAccountSettingsJsonObject(acc, installationId)
|
||||||
"key-uid": acc.keyUid,
|
|
||||||
"mnemonic": acc.mnemonic,
|
|
||||||
"public-key": acc.derivedAccounts.whisper.publicKey,
|
|
||||||
"name": acc.alias,
|
|
||||||
"address": acc.address,
|
|
||||||
"eip1581-address": acc.derivedAccounts.eip1581.address,
|
|
||||||
"dapps-address": acc.derivedAccounts.defaultWallet.address,
|
|
||||||
"wallet-root-address": acc.derivedAccounts.walletRoot.address,
|
|
||||||
"preview-privacy?": true,
|
|
||||||
"signing-phrase": generateSigningPhrase(3),
|
|
||||||
"log-level": "INFO",
|
|
||||||
"latest-derived-path": 0,
|
|
||||||
"networks/networks": DEFAULT_NETWORKS,
|
|
||||||
"currency": "usd",
|
|
||||||
"identicon": acc.identicon,
|
|
||||||
"waku-enabled": true,
|
|
||||||
"wallet/visible-tokens": {
|
|
||||||
"mainnet": ["SNT"]
|
|
||||||
},
|
|
||||||
"appearance": 0,
|
|
||||||
"networks/current-network": DEFAULT_NETWORK_NAME,
|
|
||||||
"installation-id": installationId
|
|
||||||
}
|
|
||||||
|
|
||||||
proc getDefaultNodeConfig*(self: Service, fleetConfig: FleetConfig, installationId: string):
|
if(self.importedAccount.isValid()):
|
||||||
JsonNode =
|
if(self.importedAccount.id == accountId):
|
||||||
|
return self.prepareAccountSettingsJsonObject(self.importedAccount, installationId)
|
||||||
|
|
||||||
|
proc getDefaultNodeConfig*(self: Service, fleetConfig: FleetConfig,
|
||||||
|
installationId: string): JsonNode =
|
||||||
let networkConfig = getNetworkConfig(DEFAULT_NETWORK_NAME)
|
let networkConfig = getNetworkConfig(DEFAULT_NETWORK_NAME)
|
||||||
let upstreamUrl = networkConfig["config"]["UpstreamConfig"]["URL"]
|
let upstreamUrl = networkConfig["config"]["UpstreamConfig"]["URL"]
|
||||||
let fleet = Fleet.PROD
|
let fleet = Fleet.PROD
|
||||||
|
@ -184,18 +236,50 @@ proc getDefaultNodeConfig*(self: Service, fleetConfig: FleetConfig, installation
|
||||||
# result["ListenAddr"] = if existsEnv("STATUS_PORT"): newJString("0.0.0.0:" & $getEnv("STATUS_PORT")) else: newJString("0.0.0.0:30305")
|
# result["ListenAddr"] = if existsEnv("STATUS_PORT"): newJString("0.0.0.0:" & $getEnv("STATUS_PORT")) else: newJString("0.0.0.0:30305")
|
||||||
|
|
||||||
method setupAccount*(self: Service, fleetConfig: FleetConfig, accountId,
|
method setupAccount*(self: Service, fleetConfig: FleetConfig, accountId,
|
||||||
password: string): AccountDto =
|
password: string): bool =
|
||||||
try:
|
try:
|
||||||
let installationId = $genUUID()
|
let installationId = $genUUID()
|
||||||
let accountDataJson = self.getAccountDataForAccountId(accountId)
|
let accountDataJson = self.getAccountDataForAccountId(accountId)
|
||||||
let subaccountDataJson = self.getSubaccountDataForAccountId(accountId)
|
let subaccountDataJson = self.getSubaccountDataForAccountId(accountId)
|
||||||
let settingsJSON = self.getAccountSettings(accountId, installationId)
|
let settingsJson = self.getAccountSettings(accountId, installationId)
|
||||||
let nodeConfig = self.getDefaultNodeConfig(fleetConfig, installationId)
|
let nodeConfigJson = self.getDefaultNodeConfig(fleetConfig, installationId)
|
||||||
|
|
||||||
|
if(accountDataJson.isNil or subaccountDataJson.isNil or settingsJson.isNil or
|
||||||
|
nodeConfigJson.isNil):
|
||||||
|
let description = "at least one json object is not prepared well"
|
||||||
|
error "error: ", methodName="setupAccount", errDesription = description
|
||||||
|
return false
|
||||||
|
|
||||||
let hashedPassword = hashString(password)
|
let hashedPassword = hashString(password)
|
||||||
discard self.storeDerivedAccounts(accountId, hashedPassword, PATHS)
|
discard self.storeDerivedAccounts(accountId, hashedPassword, PATHS)
|
||||||
return self.saveAccountAndLogin(hashedPassword, accountDataJson,
|
|
||||||
subaccountDataJson, settingsJSON, nodeConfig)
|
self.loggedInAccount = self.saveAccountAndLogin(hashedPassword,
|
||||||
|
accountDataJson, subaccountDataJson, settingsJson, nodeConfigJson)
|
||||||
|
|
||||||
|
return self.getLoggedInAccount.isValid()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", methodName="setupAccount", errName = e.name, errDesription = e.msg
|
error "error: ", methodName="setupAccount", errName = e.name, errDesription = e.msg
|
||||||
|
return false
|
||||||
|
|
||||||
|
method importMnemonic*(self: Service, mnemonic: string): bool =
|
||||||
|
try:
|
||||||
|
let response = status_go.multiAccountImportMnemonic(mnemonic)
|
||||||
|
self.importedAccount = toGeneratedAccountDto(response.result)
|
||||||
|
|
||||||
|
let responseDerived = status_go.deriveAccounts(self.importedAccount.id, PATHS)
|
||||||
|
self.importedAccount.derivedAccounts = toDerivedAccounts(responseDerived.result)
|
||||||
|
|
||||||
|
let responseAlias = status_go.generateAlias(
|
||||||
|
self.importedAccount.derivedAccounts.whisper.publicKey)
|
||||||
|
self.importedAccount.alias = responseAlias.result.getStr
|
||||||
|
|
||||||
|
let responseIdenticon = status_go.generateIdenticon(
|
||||||
|
self.importedAccount.derivedAccounts.whisper.publicKey)
|
||||||
|
self.importedAccount.identicon = responseIdenticon.result.getStr
|
||||||
|
|
||||||
|
return self.importedAccount.isValid()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
error "error: ", methodName="importMnemonic", errName = e.name, errDesription = e.msg
|
||||||
|
return false
|
|
@ -26,6 +26,22 @@ method generatedAccounts*(self: ServiceInterface):
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method setupAccount*(self: ServiceInterface, fleetConfig: FleetConfig,
|
method setupAccount*(self: ServiceInterface, fleetConfig: FleetConfig,
|
||||||
accountId, password: string):
|
accountId, password: string): bool {.base.} =
|
||||||
AccountDto {.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getLoggedInAccount*(self: ServiceInterface): AccountDto {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getImportedAccount*(self: ServiceInterface): GeneratedAccountDto
|
||||||
|
{.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method isFirstTimeAccountLogin*(self: ServiceInterface): bool {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method validateMnemonic*(self: ServiceInterface, mnemonic: string):
|
||||||
|
string {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method importMnemonic*(self: ServiceInterface, mnemonic: string): bool {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -269,7 +269,7 @@ proc mainProc() =
|
||||||
# https://doc.qt.io/archives/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-linguist-programmers.html
|
# https://doc.qt.io/archives/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-linguist-programmers.html
|
||||||
changeLanguage("en")
|
changeLanguage("en")
|
||||||
|
|
||||||
singletonInstance.engine.load(newQUrl("qrc:///main.qml"))
|
#singletonInstance.engine.load(newQUrl("qrc:///main.qml"))
|
||||||
|
|
||||||
# Please note that this must use the `cdecl` calling convention because
|
# Please note that this must use the `cdecl` calling convention because
|
||||||
# it will be passed as a regular C function to statusgo_backend. This means that
|
# it will be passed as a regular C function to statusgo_backend. This means that
|
||||||
|
|
|
@ -10,7 +10,7 @@ import shared.status 1.0
|
||||||
import StatusQ.Controls 0.1 as StatusQControls
|
import StatusQ.Controls 0.1 as StatusQControls
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Components 0.1
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: accountViewDelegate
|
id: accountViewDelegate
|
||||||
|
|
||||||
property string username: "Jotaro Kujo"
|
property string username: "Jotaro Kujo"
|
||||||
|
@ -20,7 +20,7 @@ Rectangle {
|
||||||
property var onAccountSelect: function() {}
|
property var onAccountSelect: function() {}
|
||||||
property var isSelected: function() {}
|
property var isSelected: function() {}
|
||||||
property bool selected: {
|
property bool selected: {
|
||||||
return isSelected(accountId, keyUid)
|
return isSelected(index, keyUid)
|
||||||
}
|
}
|
||||||
property bool isHovered: false
|
property bool isHovered: false
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
onAccountSelect(accountId)
|
onAccountSelect(index)
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
accountViewDelegate.isHovered = true
|
accountViewDelegate.isHovered = true
|
||||||
|
|
|
@ -1,37 +1,31 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
import "./samples/"
|
|
||||||
|
import "../controls"
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
property var accounts: AccountsData {}
|
id: accountsView
|
||||||
|
|
||||||
property var isSelected: function () {}
|
property var isSelected: function () {}
|
||||||
property var onAccountSelect: function () {}
|
property var onAccountSelect: function () {}
|
||||||
|
|
||||||
id: accountsView
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: accounts
|
|
||||||
focus: true
|
focus: true
|
||||||
spacing: Style.current.smallPadding
|
spacing: Style.current.smallPadding
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
delegate: AccountView {
|
delegate: AccountViewDelegate {
|
||||||
username: model.alias
|
username: model.username
|
||||||
identicon: model.thumbnailImage || model.identicon
|
identicon: model.thumbnailImage || model.identicon
|
||||||
keyUid: model.keyUid
|
keyUid: model.keyUid
|
||||||
address: model.address || ''
|
address: model.address || ''
|
||||||
isSelected: function (accountId, keyUid) {
|
isSelected: function (index, keyUid) {
|
||||||
return accountsView.isSelected(accountId, keyUid)
|
return accountsView.isSelected(index, keyUid)
|
||||||
}
|
}
|
||||||
onAccountSelect: function (accountId) {
|
onAccountSelect: function (index) {
|
||||||
accountsView.onAccountSelect(accountId)
|
accountsView.onAccountSelect(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*##^##
|
|
||||||
Designer {
|
|
||||||
D{i:0;autoSize:true;height:480;width:640}
|
|
||||||
}
|
|
||||||
##^##*/
|
|
||||||
|
|
|
@ -1,31 +1,37 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
import QtGraphicalEffects 1.13
|
import QtGraphicalEffects 1.13
|
||||||
|
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import "../shared"
|
|
||||||
import "./Login"
|
|
||||||
|
|
||||||
|
import "../../../../shared"
|
||||||
|
import "../../../../shared/popups"
|
||||||
|
import "../panels"
|
||||||
|
import "../stores"
|
||||||
|
|
||||||
|
// TODO: replace with StatusModal
|
||||||
ModalPopup {
|
ModalPopup {
|
||||||
property string selectedId: ""
|
property int selectedIndex: 0
|
||||||
property var onClosed: function () {}
|
property var onClosed: function () {}
|
||||||
property var onNextClick: function () {}
|
property var onNextClick: function () {}
|
||||||
id: popup
|
id: popup
|
||||||
//% "Choose a chat name"
|
//% "Choose a chat name"
|
||||||
title: qsTrId("intro-wizard-title2")
|
title: qsTrId("intro-wizard-title2")
|
||||||
|
height: 504
|
||||||
|
|
||||||
AccountList {
|
AccountListPanel {
|
||||||
id: accountList
|
id: accountList
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
accounts: onboardingModule.accountsModel
|
model: OnboardingStore.onBoardingModul.accountsModel
|
||||||
isSelected: function (accId) {
|
isSelected: function (index) {
|
||||||
return accId === selectedId
|
return index === selectedIndex
|
||||||
}
|
}
|
||||||
onAccountSelect: function(accId) {
|
onAccountSelect: function(index) {
|
||||||
selectedId = accId
|
selectedIndex = index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
footer: StatusRoundButton {
|
footer: StatusRoundButton {
|
||||||
|
@ -38,14 +44,8 @@ ModalPopup {
|
||||||
icon.width: 20
|
icon.width: 20
|
||||||
icon.height: 16
|
icon.height: 16
|
||||||
onClicked : {
|
onClicked : {
|
||||||
onNextClick(selectedId);
|
onNextClick(selectedIndex);
|
||||||
popup.close()
|
popup.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*##^##
|
|
||||||
Designer {
|
|
||||||
D{i:0;formeditorColor:"#ffffff";height:500;width:400}
|
|
||||||
}
|
|
||||||
##^##*/
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ ModalPopup {
|
||||||
|
|
||||||
StatusSmartIdenticon {
|
StatusSmartIdenticon {
|
||||||
id: identicon
|
id: identicon
|
||||||
|
source: OnboardingStore.onBoardingModul.importedAccountIdenticon
|
||||||
anchors.top: info.bottom
|
anchors.top: info.bottom
|
||||||
anchors.topMargin: Style.current.bigPadding
|
anchors.topMargin: Style.current.bigPadding
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
@ -53,7 +54,7 @@ ModalPopup {
|
||||||
anchors.top: identicon.bottom
|
anchors.top: identicon.bottom
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.topMargin: Style.current.padding
|
||||||
anchors.horizontalCenter: identicon.horizontalCenter
|
anchors.horizontalCenter: identicon.horizontalCenter
|
||||||
text: OnboardingStore.currentAccount.username
|
text: OnboardingStore.onBoardingModul.importedAccountAlias
|
||||||
font.weight: Font.Bold
|
font.weight: Font.Bold
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
}
|
}
|
||||||
|
@ -62,7 +63,7 @@ ModalPopup {
|
||||||
anchors.top: username.bottom
|
anchors.top: username.bottom
|
||||||
anchors.topMargin: Style.current.halfPadding
|
anchors.topMargin: Style.current.halfPadding
|
||||||
anchors.horizontalCenter: username.horizontalCenter
|
anchors.horizontalCenter: username.horizontalCenter
|
||||||
text: OnboardingStore.currentAccount.address
|
text: OnboardingStore.onBoardingModul.importedAccountAddress
|
||||||
width: 120
|
width: 120
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,16 +149,12 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connections {
|
Connections {
|
||||||
// target: onboardingModel
|
target: onboardingModule
|
||||||
// ignoreUnknownSignals: true
|
onAccountSetupError: {
|
||||||
// onLoginResponseChanged: {
|
importLoginError.open()
|
||||||
// if (error) {
|
}
|
||||||
// loading = false
|
}
|
||||||
// importLoginError.open()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (storingPasswordModal)
|
if (storingPasswordModal)
|
||||||
|
@ -170,18 +166,16 @@ ModalPopup {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loading = true
|
loading = true
|
||||||
// loginModel.isCurrentFlow = false;
|
|
||||||
// onboardingModel.isCurrentFlow = true;
|
|
||||||
const result = onboardingModule.storeSelectedAccountAndLogin(repeatPasswordField.text);
|
const result = onboardingModule.storeSelectedAccountAndLogin(repeatPasswordField.text);
|
||||||
const error = JSON.parse(result).error
|
const error = JSON.parse(result).error
|
||||||
if (error) {
|
if (error) {
|
||||||
importError.text += error
|
importError.text += error
|
||||||
return importError.open()
|
return importError.open()
|
||||||
}
|
}
|
||||||
onboardingModel.firstTimeLogin = true
|
|
||||||
|
|
||||||
applicationWindow.checkForStoringPassToKeychain(onboardingModel.currentAccount.username,
|
// NEED TO HANDLE IT
|
||||||
repeatPasswordField.text, true)
|
// applicationWindow.checkForStoringPassToKeychain(onboardingModel.currentAccount.username,
|
||||||
|
// repeatPasswordField.text, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,14 @@ pragma Singleton
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
property var onBoardingModel: onboardingModel
|
property var onBoardingModul: onboardingModule
|
||||||
property var currentAccount: onboardingModel.currentAccount
|
|
||||||
|
|
||||||
function importMnemonic(mnemonic) {
|
function importMnemonic(mnemonic) {
|
||||||
onboardingModel.importMnemonic(mnemonic)
|
onBoardingModul.importMnemonic(mnemonic)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCurrentAccount(selectedAccountIdx) {
|
function setCurrentAccount(selectedAccountIdx) {
|
||||||
onboardingModel.setCurrentAccount(selectedAccountIdx)
|
onBoardingModul.setSelectedAccountByIndex(selectedAccountIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
property ListModel accountsSampleData: ListModel {
|
property ListModel accountsSampleData: ListModel {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
|
||||||
|
import "../popups"
|
||||||
|
import "../stores"
|
||||||
|
import "../shared"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property var onClosed: function () {}
|
property var onClosed: function () {}
|
||||||
id: genKeyView
|
id: genKeyView
|
||||||
|
@ -12,9 +16,9 @@ Item {
|
||||||
GenKeyModal {
|
GenKeyModal {
|
||||||
property bool wentNext: false
|
property bool wentNext: false
|
||||||
id: genKeyModal
|
id: genKeyModal
|
||||||
onNextClick: function (accId) {
|
onNextClick: function (selectedIndex) {
|
||||||
wentNext = true
|
wentNext = true
|
||||||
onboardingModule.setSelectedAccountId(accId)
|
OnboardingStore.setCurrentAccount(selectedIndex)
|
||||||
createPasswordModal.open()
|
createPasswordModal.open()
|
||||||
}
|
}
|
||||||
onClosed: function () {
|
onClosed: function () {
|
||||||
|
@ -31,9 +35,3 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*##^##
|
|
||||||
Designer {
|
|
||||||
D{i:0;autoSize:true;formeditorColor:"#ffffff";height:480;width:640}
|
|
||||||
}
|
|
||||||
##^##*/
|
|
||||||
|
|
|
@ -25,16 +25,10 @@ Item {
|
||||||
id: loginView
|
id: loginView
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
function setCurrentFlow(isLogin) {
|
|
||||||
LoginStore.loginModelInst.isCurrentFlow = isLogin;
|
|
||||||
OnboardingStore.onBoardingModel.isCurrentFlow = !isLogin;
|
|
||||||
}
|
|
||||||
|
|
||||||
function doLogin(password) {
|
function doLogin(password) {
|
||||||
if (loading || password.length === 0)
|
if (loading || password.length === 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
setCurrentFlow(true);
|
|
||||||
loading = true
|
loading = true
|
||||||
LoginStore.login(password)
|
LoginStore.login(password)
|
||||||
applicationWindow.checkForStoringPassToKeychain(LoginStore.currentAccount.username, password, false)
|
applicationWindow.checkForStoringPassToKeychain(LoginStore.currentAccount.username, password, false)
|
||||||
|
@ -116,7 +110,6 @@ Item {
|
||||||
ConfirmAddExistingKeyModal {
|
ConfirmAddExistingKeyModal {
|
||||||
id: confirmAddExstingKeyModal
|
id: confirmAddExstingKeyModal
|
||||||
onOpenModalClick: function () {
|
onOpenModalClick: function () {
|
||||||
setCurrentFlow(false);
|
|
||||||
onExistingKeyClicked()
|
onExistingKeyClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +121,6 @@ Item {
|
||||||
resetLogin()
|
resetLogin()
|
||||||
}
|
}
|
||||||
onOpenModalClick: function () {
|
onOpenModalClick: function () {
|
||||||
setCurrentFlow(true);
|
|
||||||
onExistingKeyClicked()
|
onExistingKeyClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +177,7 @@ Item {
|
||||||
anchors.top: changeAccountBtn.bottom
|
anchors.top: changeAccountBtn.bottom
|
||||||
anchors.topMargin: Style.current.padding * 2
|
anchors.topMargin: Style.current.padding * 2
|
||||||
enabled: !loading
|
enabled: !loading
|
||||||
placeholderText: loading ?
|
placeholderText: loading ?
|
||||||
//% "Connecting..."
|
//% "Connecting..."
|
||||||
qsTrId("connecting") :
|
qsTrId("connecting") :
|
||||||
//% "Enter password"
|
//% "Enter password"
|
||||||
|
@ -259,7 +251,6 @@ Item {
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
onClicked: {
|
onClicked: {
|
||||||
setCurrentFlow(false);
|
|
||||||
onGenKeyClicked()
|
onGenKeyClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,11 @@ Item {
|
||||||
width: walletView.width
|
width: walletView.width
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if(RootStore.firstTimeLogin){
|
// Read in RootStore
|
||||||
RootStore.firstTimeLogin = false
|
// if(RootStore.firstTimeLogin){
|
||||||
RootStore.setInitialRange()
|
// RootStore.firstTimeLogin = false
|
||||||
}
|
// RootStore.setInitialRange()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
|
|
@ -25,7 +25,12 @@ QtObject {
|
||||||
|
|
||||||
property var historyView: walletModel.historyView
|
property var historyView: walletModel.historyView
|
||||||
|
|
||||||
property bool firstTimeLogin: onboardingModel.isFirstTimeLogin
|
// This should be exposed to the UI via "walletModule", WalletModule should use
|
||||||
|
// Accounts Service which keeps the info about that. Then in the View of WalletModule
|
||||||
|
// we may have either QtProperty or Q_INVOKABLE function (proc marked as slot)
|
||||||
|
// depends on logic/need.
|
||||||
|
|
||||||
|
//property bool firstTimeLogin: walletModule.isFirstTimeLogin
|
||||||
|
|
||||||
property var tokens: {
|
property var tokens: {
|
||||||
let count = walletModel.tokensView.defaultTokenList.rowCount()
|
let count = walletModel.tokensView.defaultTokenList.rowCount()
|
||||||
|
|
|
@ -54,10 +54,11 @@ Item {
|
||||||
width: walletView.width
|
width: walletView.width
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (walletView.store.onboardingModelInst.firstTimeLogin) {
|
// Read in RootStore
|
||||||
walletView.store.onboardingModelInst.firstTimeLogin = false;
|
// if (walletView.store.onboardingModelInst.firstTimeLogin) {
|
||||||
walletView.store.walletModelInst.setInitialRange();
|
// walletView.store.onboardingModelInst.firstTimeLogin = false;
|
||||||
}
|
// walletView.store.walletModelInst.setInitialRange();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPanel: LeftTabView {
|
leftPanel: LeftTabView {
|
||||||
|
|
|
@ -24,7 +24,7 @@ Item {
|
||||||
//% "Invalid seed phrase"
|
//% "Invalid seed phrase"
|
||||||
errorText.text = qsTrId("custom-seed-phrase")
|
errorText.text = qsTrId("custom-seed-phrase")
|
||||||
} else {
|
} else {
|
||||||
errorText.text = onboardingModel.validateMnemonic(mnemonicTextField.textField.text)
|
errorText.text = onboardingModule.validateMnemonic(mnemonicTextField.textField.text)
|
||||||
const regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
|
const regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
|
||||||
if (regex.test(errorText.text)) {
|
if (regex.test(errorText.text)) {
|
||||||
//% "Invalid seed phrase"
|
//% "Invalid seed phrase"
|
||||||
|
|
|
@ -3,6 +3,10 @@ pragma Singleton
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
readonly property int onboardingAppState: 0
|
||||||
|
readonly property int loginAppSate: 1
|
||||||
|
readonly property int mainAppState: 2
|
||||||
|
|
||||||
readonly property int communityImported: 0
|
readonly property int communityImported: 0
|
||||||
readonly property int communityImportingInProgress: 1
|
readonly property int communityImportingInProgress: 1
|
||||||
readonly property int communityImportingError: 2
|
readonly property int communityImportingError: 2
|
||||||
|
|
14
ui/main.qml
14
ui/main.qml
|
@ -20,7 +20,7 @@ import "./app/AppLayouts/Onboarding/views"
|
||||||
import "./app"
|
import "./app"
|
||||||
|
|
||||||
StatusWindow {
|
StatusWindow {
|
||||||
property bool hasAccounts: startupModule.startWithOnboardingScreen
|
property bool hasAccounts: startupModule.appState !== Constants.onboardingAppState
|
||||||
property bool removeMnemonicAfterLogin: false
|
property bool removeMnemonicAfterLogin: false
|
||||||
property alias dragAndDrop: dragTarget
|
property alias dragAndDrop: dragTarget
|
||||||
property bool popupOpened: false
|
property bool popupOpened: false
|
||||||
|
@ -361,7 +361,8 @@ StatusWindow {
|
||||||
|
|
||||||
DSM.SignalTransition {
|
DSM.SignalTransition {
|
||||||
targetState: appState
|
targetState: appState
|
||||||
signal: onboardingModel.moveToAppState
|
signal: startupModule.appStateChanged
|
||||||
|
guard: state == Constants.mainAppState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +372,8 @@ StatusWindow {
|
||||||
|
|
||||||
DSM.SignalTransition {
|
DSM.SignalTransition {
|
||||||
targetState: appState
|
targetState: appState
|
||||||
signal: onboardingModel.moveToAppState
|
signal: startupModule.appStateChanged
|
||||||
|
guard: state == Constants.mainAppState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +383,8 @@ StatusWindow {
|
||||||
|
|
||||||
DSM.SignalTransition {
|
DSM.SignalTransition {
|
||||||
targetState: appState
|
targetState: appState
|
||||||
signal: onboardingModel.moveToAppState
|
signal: startupModule.appStateChanged
|
||||||
|
guard: state == Constants.mainAppState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +394,8 @@ StatusWindow {
|
||||||
|
|
||||||
DSM.SignalTransition {
|
DSM.SignalTransition {
|
||||||
targetState: appState
|
targetState: appState
|
||||||
signal: loginModel.moveToAppState
|
signal: startupModule.appStateChanged
|
||||||
|
guard: state == Constants.mainAppState
|
||||||
}
|
}
|
||||||
|
|
||||||
DSM.SignalTransition {
|
DSM.SignalTransition {
|
||||||
|
|
Loading…
Reference in New Issue