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
|
||||
proc startupDidLoad*(self: AppController)
|
||||
proc accountCreated*(self: AppController)
|
||||
|
||||
# Main Module Delegate Interface
|
||||
proc mainDidLoad*(self: AppController)
|
||||
|
@ -95,12 +96,14 @@ proc delete*(self: AppController) =
|
|||
|
||||
proc startupDidLoad*(self: AppController) =
|
||||
echo "StartupDidLoad"
|
||||
singletonInstance.engine.load(newQUrl("qrc:///main.qml"))
|
||||
# self.login.init()
|
||||
# self.onboarding.init()
|
||||
|
||||
proc mainDidLoad*(self: AppController) =
|
||||
# This to will be adapted to appropriate modules later:
|
||||
self.appService.onLoggedIn()
|
||||
self.startupModule.moveToAppState()
|
||||
|
||||
# Reset login and onboarding to remove any mnemonic that would have been saved in the accounts list
|
||||
# self.login.reset()
|
||||
|
@ -121,4 +124,8 @@ proc load*(self: AppController) =
|
|||
self.chatService.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 controller_interface
|
||||
import io_interface
|
||||
|
||||
import ../../../app_service/service/accounts/service_interface as accounts_service
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
Controller* = ref object of controller_interface.AccessInterface
|
||||
delegate: io_interface.AccessInterface
|
||||
accountsService: accounts_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T,
|
||||
proc newController*(delegate: io_interface.AccessInterface,
|
||||
accountsService: accounts_service.ServiceInterface):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.accountsService = accountsService
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
method delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
method init*[T](self: Controller[T]) =
|
||||
method init*(self: Controller) =
|
||||
discard
|
||||
|
||||
method shouldStartWithOnboardingScreen*[T](self: Controller[T]): bool =
|
||||
return self.accountsService.openedAccounts().len > 0
|
||||
method shouldStartWithOnboardingScreen*(self: Controller): bool =
|
||||
return self.accountsService.openedAccounts().len == 0
|
|
@ -10,9 +10,4 @@ method init*(self: AccessInterface) {.base.} =
|
|||
|
||||
method shouldStartWithOnboardingScreen*(self: AccessInterface): bool {.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
|
||||
|
|
@ -1,22 +1,19 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
# Defines how parent module accesses this module
|
||||
include ./private_interfaces/module_base_interface
|
||||
include ./private_interfaces/module_access_interface
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
# Defines how this module view communicates with this module
|
||||
include ./private_interfaces/module_view_delegate_interface
|
||||
|
||||
method load*(self: AccessInterface) {.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")
|
||||
# Defines how this controller communicates with this module
|
||||
include ./private_interfaces/module_controller_delegate_interface
|
||||
|
||||
# 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
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
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 controller_interface
|
||||
import io_interface
|
||||
|
||||
import status/[signals]
|
||||
import ../../../../app_service/[main]
|
||||
|
@ -9,25 +10,27 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
|||
export controller_interface
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
Controller* = ref object of controller_interface.AccessInterface
|
||||
delegate: io_interface.AccessInterface
|
||||
appService: AppService
|
||||
accountsService: accounts_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T,
|
||||
proc newController*(delegate: io_interface.AccessInterface,
|
||||
appService: AppService,
|
||||
accountsService: accounts_service.ServiceInterface):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.appService = appService
|
||||
result.accountsService = accountsService
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
method delete*(self: Controller) =
|
||||
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):
|
||||
echo "-NEW-LOGIN-- NodeStopped: ", repr(e)
|
||||
#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
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
@ -9,10 +9,6 @@ method delete*(self: AccessInterface) {.base.} =
|
|||
|
||||
method init*(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
|
||||
|
||||
|
||||
method getOpenedAccounts*(self: AccessInterface): seq[AccountDto] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -1,24 +1,12 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
# Defines how parent module accesses this module
|
||||
include ./private_interfaces/module_base_interface
|
||||
include ./private_interfaces/module_access_interface
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
# Defines how this module view communicates with this module
|
||||
include ./private_interfaces/module_view_delegate_interface
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
# Defines how this controller communicates with this module
|
||||
include ./private_interfaces/module_controller_delegate_interface
|
||||
|
||||
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")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
c.loginDidLoad()
|
||||
# Defines how submodules of this module communicate with this module
|
||||
# will be added if needed
|
|
@ -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 item
|
||||
import NimQml, Tables, strutils, strformat
|
||||
|
||||
import account_item
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Account = UserRole + 1
|
||||
|
||||
QtObject:
|
||||
type
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
sections: seq[Item]
|
||||
items: seq[AccountItem]
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc delete*(self: Model) =
|
||||
proc delete(self: Model) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newModel*(): Model =
|
||||
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 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_service/[main]
|
||||
|
@ -8,42 +10,68 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
|||
export io_interface
|
||||
|
||||
type
|
||||
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
||||
delegate: T
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: controller.AccessInterface
|
||||
moduleLoaded: bool
|
||||
|
||||
proc newModule*[T](delegate: T,
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||
appService: AppService,
|
||||
accountsService: accounts_service.ServiceInterface):
|
||||
Module[T] =
|
||||
result = Module[T]()
|
||||
Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result, appService,
|
||||
accountsService)
|
||||
result.controller = controller.newController(result, appService, accountsService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("loginModule", result.viewVariant)
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.viewVariant.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)
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.loginDidLoad()
|
||||
let openedAccounts = self.controller.getOpenedAccounts()
|
||||
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
|
||||
|
||||
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 model
|
||||
import account_item, model
|
||||
import io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
selectedAccount: AccountItem
|
||||
selectedAccountVariant: QVariant
|
||||
model: Model
|
||||
modelVariant: QVariant
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.selectedAccount.delete
|
||||
self.selectedAccountVariant.delete
|
||||
self.model.delete
|
||||
self.modelVariant.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.selectedAccount = newAccountItem()
|
||||
result.selectedAccountVariant = newQVariant(result.selectedAccount)
|
||||
result.model = newModel()
|
||||
result.modelVariant = newQVariant(result.model)
|
||||
|
||||
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 io_interface, view, controller
|
||||
import io_interface
|
||||
import view, controller
|
||||
import ../../../app/boot/global_singleton
|
||||
|
||||
import onboarding/module as onboarding_module
|
||||
|
@ -20,20 +21,6 @@ type
|
|||
onboardingModule: onboarding_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,
|
||||
appService: AppService,
|
||||
accountsService: accounts_service.ServiceInterface):
|
||||
|
@ -42,13 +29,11 @@ proc newModule*[T](delegate: T,
|
|||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result, accountsService)
|
||||
result.controller = controller.newController(result, accountsService)
|
||||
|
||||
# Submodules
|
||||
result.onboardingModule = onboarding_module.newModule[Module[T]](result,
|
||||
appService, accountsService)
|
||||
result.loginModule = login_module.newModule[Module[T]](result, appService,
|
||||
accountsService)
|
||||
result.onboardingModule = onboarding_module.newModule(result, appService, accountsService)
|
||||
result.loginModule = login_module.newModule(result, appService, accountsService)
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.onboardingModule.delete
|
||||
|
@ -61,14 +46,15 @@ method load*[T](self: Module[T]) =
|
|||
singletonInstance.engine.setRootContextProperty("startupModule", self.viewVariant)
|
||||
self.controller.init()
|
||||
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.loginModule.load()
|
||||
|
||||
method viewDidLoad*[T](self: Module[T]) =
|
||||
discard
|
||||
|
||||
proc checkIfModuleDidLoad[T](self: Module[T]) =
|
||||
if(not self.onboardingModule.isLoaded()):
|
||||
return
|
||||
|
@ -78,8 +64,17 @@ proc checkIfModuleDidLoad[T](self: Module[T]) =
|
|||
|
||||
self.delegate.startupDidLoad()
|
||||
|
||||
proc onboardingDidLoad*[T](self: Module[T]) =
|
||||
method viewDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
proc loginDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
method onboardingDidLoad*[T](self: Module[T]) =
|
||||
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 io_interface
|
||||
|
||||
import status/[signals]
|
||||
import ../../../../app_service/[main]
|
||||
|
@ -8,39 +9,62 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
|||
|
||||
export controller_interface
|
||||
|
||||
logScope:
|
||||
topics = "onboarding-controller"
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
Controller* =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
delegate: io_interface.AccessInterface
|
||||
appService: AppService
|
||||
accountsService: accounts_service.ServiceInterface
|
||||
selectedAccountId: string
|
||||
|
||||
proc newController*[T](delegate: T,
|
||||
proc newController*(delegate: io_interface.AccessInterface,
|
||||
appService: AppService,
|
||||
accountsService: accounts_service.ServiceInterface):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.appService = appService
|
||||
result.accountsService = accountsService
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
method delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
method init*[T](self: Controller[T]) =
|
||||
method init*(self: Controller) =
|
||||
self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args):
|
||||
echo "-NEW-ONBOARDING-- OnNodeLoginEvent: ", repr(e)
|
||||
#self.handleNodeLogin(NodeSignal(e))
|
||||
let signal = 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()
|
||||
|
||||
method setSelectedAccountId*[T](self: Controller[T], id: string) =
|
||||
self.selectedAccountId = id
|
||||
method getImportedAccount*(self: Controller): GeneratedAccountDto =
|
||||
return self.accountsService.getImportedAccount()
|
||||
|
||||
method storeSelectedAccountAndLogin*[T](self: Controller[T], password: string) =
|
||||
let account = self.accountsService.setupAccount(self.appService.status.fleet.config,
|
||||
self.selectedAccountId, password)
|
||||
method setSelectedAccountByIndex*(self: Controller, index: int) =
|
||||
let accounts = self.getGeneratedAccounts()
|
||||
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.} =
|
||||
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")
|
||||
|
||||
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")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
|
||||
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")
|
|
@ -1,31 +1,12 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
# Defines how parent module accesses this module
|
||||
include ./private_interfaces/module_base_interface
|
||||
include ./private_interfaces/module_access_interface
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
# Defines how this module view communicates with this module
|
||||
include ./private_interfaces/module_view_delegate_interface
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
# Defines how this controller communicates with this module
|
||||
include ./private_interfaces/module_controller_delegate_interface
|
||||
|
||||
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 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()
|
||||
# Defines how submodules of this module communicate with this module
|
||||
# will be added if needed
|
|
@ -32,7 +32,7 @@ QtObject:
|
|||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
ModelRole.Id.int:"accountId",
|
||||
ModelRole.Alias.int:"alias",
|
||||
ModelRole.Alias.int:"username",
|
||||
ModelRole.Identicon.int:"identicon",
|
||||
ModelRole.Address.int:"address",
|
||||
ModelRole.KeyUid.int:"keyUid"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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_service/[main]
|
||||
|
@ -8,33 +10,32 @@ import ../../../../app_service/service/accounts/service_interface as accounts_se
|
|||
export io_interface
|
||||
|
||||
type
|
||||
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
||||
delegate: T
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: controller.AccessInterface
|
||||
moduleLoaded: bool
|
||||
|
||||
proc newModule*[T](delegate: T,
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||
appService: AppService,
|
||||
accountsService: accounts_service.ServiceInterface):
|
||||
Module[T] =
|
||||
result = Module[T]()
|
||||
Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result, appService,
|
||||
accountsService)
|
||||
result.controller = controller.newController(result, appService, accountsService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("onboardingModule", result.viewVariant)
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("onboardingModule", self.viewVariant)
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
@ -44,19 +45,38 @@ method load*[T](self: Module[T]) =
|
|||
for acc in generatedAccounts:
|
||||
accounts.add(initItem(acc.id, acc.alias, acc.identicon, acc.address, acc.keyUid))
|
||||
|
||||
self.view.setAccountList(accounts)
|
||||
self.view.setAccountList(accounts)
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.onboardingDidLoad()
|
||||
|
||||
method isLoaded*[T](self: Module[T]): bool =
|
||||
method isLoaded*(self: Module): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
discard
|
||||
self.moduleLoaded = true
|
||||
self.delegate.onboardingDidLoad()
|
||||
|
||||
method setSelectedAccountId*[T](self: Module[T], id: string) =
|
||||
self.controller.setSelectedAccountId(id)
|
||||
method setSelectedAccountByIndex*(self: Module, index: int) =
|
||||
self.controller.setSelectedAccountByIndex(index)
|
||||
|
||||
method storeSelectedAccountAndLogin*[T](self: Module[T], password: string) =
|
||||
self.controller.storeSelectedAccountAndLogin(password)
|
||||
method storeSelectedAccountAndLogin*(self: Module, password: string) =
|
||||
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) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc setAccountList*(self: View, accounts: seq[Item]) =
|
||||
self.model.setItems(accounts)
|
||||
|
||||
proc modelChanged*(self: View) {.signal.}
|
||||
|
||||
proc getModel(self: View): QVariant {.slot.} =
|
||||
return self.modelVariant
|
||||
|
||||
proc setAccountList*(self: View, accounts: seq[Item]) =
|
||||
self.model.setItems(accounts)
|
||||
self.modelChanged()
|
||||
|
||||
QtProperty[QVariant] accountsModel:
|
||||
read = getModel
|
||||
notify = modelChanged
|
||||
|
||||
proc setSelectedAccountId*(self: View, id: string) {.slot.} =
|
||||
self.delegate.setSelectedAccountId(id)
|
||||
proc importedAccountChanged*(self: View) {.signal.}
|
||||
|
||||
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.} =
|
||||
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 io_interface
|
||||
|
||||
type
|
||||
AppState* {.pure.} = enum
|
||||
OnboardingState = 0
|
||||
LoginState
|
||||
MainAppState
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
startWithOnboardingScreen: bool
|
||||
appState: AppState
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.QObject.delete
|
||||
|
@ -14,24 +20,24 @@ QtObject:
|
|||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.startWithOnboardingScreen = true
|
||||
result.appState = AppState.OnboardingState
|
||||
|
||||
proc load*(self: View) =
|
||||
# In some point, here, we will setup some exposed main module related things.
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc startWithOnboardingScreenChanged*(self: View) {.signal.}
|
||||
proc appStateChanged*(self: View, state: int) {.signal.}
|
||||
|
||||
proc getStartWithOnboardingScreen(self: View): bool {.slot.} =
|
||||
return self.startWithOnboardingScreen
|
||||
proc getAppState(self: View): int {.slot.} =
|
||||
return self.appState.int
|
||||
|
||||
proc setStartWithOnboardingScreen*(self: View, value: bool) {.slot.} =
|
||||
if(self.startWithOnboardingScreen == value):
|
||||
proc setAppState*(self: View, state: AppState) =
|
||||
if(self.appState == state):
|
||||
return
|
||||
|
||||
self.startWithOnboardingScreen = value
|
||||
self.startWithOnboardingScreenChanged()
|
||||
self.appState = state
|
||||
self.appStateChanged(self.appState.int)
|
||||
|
||||
QtProperty[bool] startWithOnboardingScreen:
|
||||
read = getStartWithOnboardingScreen
|
||||
notify = startWithOnboardingScreenChanged
|
||||
QtProperty[int] appState:
|
||||
read = getAppState
|
||||
notify = appStateChanged
|
|
@ -5,7 +5,7 @@ import json
|
|||
include ../../../common/json_utils
|
||||
|
||||
type
|
||||
Image* = ref object
|
||||
Image* = object
|
||||
keyUid*: string
|
||||
imgType*: string
|
||||
uri*: string
|
||||
|
@ -14,7 +14,7 @@ type
|
|||
fileSize: int
|
||||
resizeTarget: int
|
||||
|
||||
type AccountDto* = ref object
|
||||
type AccountDto* = object
|
||||
name*: string
|
||||
timestamp*: int64
|
||||
identicon*: string
|
||||
|
@ -22,6 +22,9 @@ type AccountDto* = ref object
|
|||
keyUid*: string
|
||||
images*: seq[Image]
|
||||
|
||||
proc isValid*(self: AccountDto): bool =
|
||||
result = self.name.len > 0 and self.keyUid.len > 0
|
||||
|
||||
proc toImage(jsonObj: JsonNode): Image =
|
||||
result = Image()
|
||||
discard jsonObj.getProp("keyUid", result.keyUid)
|
||||
|
|
|
@ -17,7 +17,7 @@ type DerivedAccounts* = object
|
|||
defaultWallet*: DerivedAccountDetails
|
||||
eip1581*: DerivedAccountDetails
|
||||
|
||||
type GeneratedAccountDto* = ref object
|
||||
type GeneratedAccountDto* = object
|
||||
id*: string
|
||||
publicKey*: string
|
||||
address*: string
|
||||
|
@ -28,6 +28,10 @@ type GeneratedAccountDto* = ref object
|
|||
alias*: 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):
|
||||
DerivedAccountDetails =
|
||||
# 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/generated_accounts
|
||||
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 ../../../constants as main_constants
|
||||
|
@ -17,12 +18,25 @@ const PATHS = @[PATH_WALLET_ROOT, PATH_EIP_1581, PATH_WHISPER, PATH_DEFAULT_WALL
|
|||
type
|
||||
Service* = ref object of ServiceInterface
|
||||
generatedAccounts: seq[GeneratedAccountDto]
|
||||
loggedInAccount: AccountDto
|
||||
importedAccount: GeneratedAccountDto
|
||||
isFirstTimeAccountLogin: bool
|
||||
|
||||
method delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(): 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) =
|
||||
try:
|
||||
|
@ -43,6 +57,20 @@ method init*(self: Service) =
|
|||
except Exception as e:
|
||||
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] =
|
||||
if(self.generatedAccounts.len == 0):
|
||||
error "There was some issue initiating account service"
|
||||
|
@ -82,6 +110,7 @@ proc saveAccountAndLogin(self: Service, hashedPassword: string, account,
|
|||
error = response.result["error"].getStr
|
||||
if error == "":
|
||||
debug "Account saved succesfully"
|
||||
self.isFirstTimeAccountLogin = true
|
||||
result = toAccountDto(account)
|
||||
return
|
||||
|
||||
|
@ -91,70 +120,93 @@ proc saveAccountAndLogin(self: Service, hashedPassword: string, account,
|
|||
except Exception as e:
|
||||
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 =
|
||||
for acc in self.generatedAccounts:
|
||||
if(acc.id == accountId):
|
||||
result = %* {
|
||||
"name": acc.alias,
|
||||
"address": acc.address,
|
||||
"identicon": acc.identicon,
|
||||
"key-uid": acc.keyUid,
|
||||
"keycard-pairing": nil
|
||||
}
|
||||
return self.prepareAccountJsonObject(acc)
|
||||
|
||||
if(self.importedAccount.isValid()):
|
||||
if(self.importedAccount.id == accountId):
|
||||
return self.prepareAccountJsonObject(self.importedAccount)
|
||||
|
||||
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 =
|
||||
for acc in self.generatedAccounts:
|
||||
if(acc.id == accountId):
|
||||
result = %* [
|
||||
{
|
||||
"public-key": acc.derivedAccounts.defaultWallet.publicKey,
|
||||
"address": acc.derivedAccounts.defaultWallet.address,
|
||||
"color": "#4360df",
|
||||
"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
|
||||
}
|
||||
]
|
||||
return self.prepareSubaccountJsonObject(acc)
|
||||
|
||||
if(self.importedAccount.isValid()):
|
||||
if(self.importedAccount.id == accountId):
|
||||
return self.prepareSubaccountJsonObject(self.importedAccount)
|
||||
|
||||
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,
|
||||
installationId: string): JsonNode =
|
||||
for acc in self.generatedAccounts:
|
||||
if(acc.id == accountId):
|
||||
result = %* {
|
||||
"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
|
||||
}
|
||||
return self.prepareAccountSettingsJsonObject(acc, installationId)
|
||||
|
||||
proc getDefaultNodeConfig*(self: Service, fleetConfig: FleetConfig, installationId: string):
|
||||
JsonNode =
|
||||
if(self.importedAccount.isValid()):
|
||||
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 upstreamUrl = networkConfig["config"]["UpstreamConfig"]["URL"]
|
||||
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")
|
||||
|
||||
method setupAccount*(self: Service, fleetConfig: FleetConfig, accountId,
|
||||
password: string): AccountDto =
|
||||
password: string): bool =
|
||||
try:
|
||||
let installationId = $genUUID()
|
||||
let accountDataJson = self.getAccountDataForAccountId(accountId)
|
||||
let subaccountDataJson = self.getSubaccountDataForAccountId(accountId)
|
||||
let settingsJSON = self.getAccountSettings(accountId, installationId)
|
||||
let nodeConfig = self.getDefaultNodeConfig(fleetConfig, installationId)
|
||||
let settingsJson = self.getAccountSettings(accountId, 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)
|
||||
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:
|
||||
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")
|
||||
|
||||
method setupAccount*(self: ServiceInterface, fleetConfig: FleetConfig,
|
||||
accountId, password: string):
|
||||
AccountDto {.base.} =
|
||||
accountId, password: string): bool {.base.} =
|
||||
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
|
||||
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
|
||||
# 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.Components 0.1
|
||||
|
||||
Rectangle {
|
||||
Rectangle {
|
||||
id: accountViewDelegate
|
||||
|
||||
property string username: "Jotaro Kujo"
|
||||
|
@ -20,7 +20,7 @@ Rectangle {
|
|||
property var onAccountSelect: function() {}
|
||||
property var isSelected: function() {}
|
||||
property bool selected: {
|
||||
return isSelected(accountId, keyUid)
|
||||
return isSelected(index, keyUid)
|
||||
}
|
||||
property bool isHovered: false
|
||||
|
||||
|
@ -85,7 +85,7 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
onAccountSelect(accountId)
|
||||
onAccountSelect(index)
|
||||
}
|
||||
onEntered: {
|
||||
accountViewDelegate.isHovered = true
|
||||
|
|
|
@ -1,37 +1,31 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import "./samples/"
|
||||
|
||||
import "../controls"
|
||||
|
||||
import utils 1.0
|
||||
|
||||
ListView {
|
||||
property var accounts: AccountsData {}
|
||||
id: accountsView
|
||||
|
||||
property var isSelected: function () {}
|
||||
property var onAccountSelect: function () {}
|
||||
|
||||
id: accountsView
|
||||
anchors.fill: parent
|
||||
model: accounts
|
||||
focus: true
|
||||
spacing: Style.current.smallPadding
|
||||
clip: true
|
||||
|
||||
delegate: AccountView {
|
||||
username: model.alias
|
||||
delegate: AccountViewDelegate {
|
||||
username: model.username
|
||||
identicon: model.thumbnailImage || model.identicon
|
||||
keyUid: model.keyUid
|
||||
address: model.address || ''
|
||||
isSelected: function (accountId, keyUid) {
|
||||
return accountsView.isSelected(accountId, keyUid)
|
||||
isSelected: function (index, keyUid) {
|
||||
return accountsView.isSelected(index, keyUid)
|
||||
}
|
||||
onAccountSelect: function (accountId) {
|
||||
accountsView.onAccountSelect(accountId)
|
||||
onAccountSelect: function (index) {
|
||||
accountsView.onAccountSelect(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*##^##
|
||||
Designer {
|
||||
D{i:0;autoSize:true;height:480;width:640}
|
||||
}
|
||||
##^##*/
|
||||
|
|
|
@ -1,31 +1,37 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import utils 1.0
|
||||
import "../shared"
|
||||
import "./Login"
|
||||
|
||||
import "../../../../shared"
|
||||
import "../../../../shared/popups"
|
||||
import "../panels"
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
property string selectedId: ""
|
||||
property int selectedIndex: 0
|
||||
property var onClosed: function () {}
|
||||
property var onNextClick: function () {}
|
||||
id: popup
|
||||
//% "Choose a chat name"
|
||||
title: qsTrId("intro-wizard-title2")
|
||||
height: 504
|
||||
|
||||
AccountList {
|
||||
AccountListPanel {
|
||||
id: accountList
|
||||
anchors.fill: parent
|
||||
interactive: false
|
||||
|
||||
accounts: onboardingModule.accountsModel
|
||||
isSelected: function (accId) {
|
||||
return accId === selectedId
|
||||
model: OnboardingStore.onBoardingModul.accountsModel
|
||||
isSelected: function (index) {
|
||||
return index === selectedIndex
|
||||
}
|
||||
onAccountSelect: function(accId) {
|
||||
selectedId = accId
|
||||
onAccountSelect: function(index) {
|
||||
selectedIndex = index
|
||||
}
|
||||
}
|
||||
footer: StatusRoundButton {
|
||||
|
@ -38,14 +44,8 @@ ModalPopup {
|
|||
icon.width: 20
|
||||
icon.height: 16
|
||||
onClicked : {
|
||||
onNextClick(selectedId);
|
||||
onNextClick(selectedIndex);
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*##^##
|
||||
Designer {
|
||||
D{i:0;formeditorColor:"#ffffff";height:500;width:400}
|
||||
}
|
||||
##^##*/
|
||||
|
|
|
@ -40,6 +40,7 @@ ModalPopup {
|
|||
|
||||
StatusSmartIdenticon {
|
||||
id: identicon
|
||||
source: OnboardingStore.onBoardingModul.importedAccountIdenticon
|
||||
anchors.top: info.bottom
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
@ -53,7 +54,7 @@ ModalPopup {
|
|||
anchors.top: identicon.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.horizontalCenter: identicon.horizontalCenter
|
||||
text: OnboardingStore.currentAccount.username
|
||||
text: OnboardingStore.onBoardingModul.importedAccountAlias
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ ModalPopup {
|
|||
anchors.top: username.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
anchors.horizontalCenter: username.horizontalCenter
|
||||
text: OnboardingStore.currentAccount.address
|
||||
text: OnboardingStore.onBoardingModul.importedAccountAddress
|
||||
width: 120
|
||||
}
|
||||
|
||||
|
|
|
@ -149,16 +149,12 @@ ModalPopup {
|
|||
}
|
||||
}
|
||||
|
||||
// Connections {
|
||||
// target: onboardingModel
|
||||
// ignoreUnknownSignals: true
|
||||
// onLoginResponseChanged: {
|
||||
// if (error) {
|
||||
// loading = false
|
||||
// importLoginError.open()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Connections {
|
||||
target: onboardingModule
|
||||
onAccountSetupError: {
|
||||
importLoginError.open()
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (storingPasswordModal)
|
||||
|
@ -170,18 +166,16 @@ ModalPopup {
|
|||
else
|
||||
{
|
||||
loading = true
|
||||
// loginModel.isCurrentFlow = false;
|
||||
// onboardingModel.isCurrentFlow = true;
|
||||
const result = onboardingModule.storeSelectedAccountAndLogin(repeatPasswordField.text);
|
||||
const error = JSON.parse(result).error
|
||||
if (error) {
|
||||
importError.text += error
|
||||
return importError.open()
|
||||
}
|
||||
onboardingModel.firstTimeLogin = true
|
||||
|
||||
applicationWindow.checkForStoringPassToKeychain(onboardingModel.currentAccount.username,
|
||||
repeatPasswordField.text, true)
|
||||
// NEED TO HANDLE IT
|
||||
// applicationWindow.checkForStoringPassToKeychain(onboardingModel.currentAccount.username,
|
||||
// repeatPasswordField.text, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,14 @@ pragma Singleton
|
|||
import QtQuick 2.13
|
||||
|
||||
QtObject {
|
||||
property var onBoardingModel: onboardingModel
|
||||
property var currentAccount: onboardingModel.currentAccount
|
||||
property var onBoardingModul: onboardingModule
|
||||
|
||||
function importMnemonic(mnemonic) {
|
||||
onboardingModel.importMnemonic(mnemonic)
|
||||
onBoardingModul.importMnemonic(mnemonic)
|
||||
}
|
||||
|
||||
function setCurrentAccount(selectedAccountIdx) {
|
||||
onboardingModel.setCurrentAccount(selectedAccountIdx)
|
||||
onBoardingModul.setSelectedAccountByIndex(selectedAccountIdx)
|
||||
}
|
||||
|
||||
property ListModel accountsSampleData: ListModel {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import QtQuick 2.13
|
||||
|
||||
import "../popups"
|
||||
import "../stores"
|
||||
import "../shared"
|
||||
|
||||
Item {
|
||||
property var onClosed: function () {}
|
||||
id: genKeyView
|
||||
|
@ -12,9 +16,9 @@ Item {
|
|||
GenKeyModal {
|
||||
property bool wentNext: false
|
||||
id: genKeyModal
|
||||
onNextClick: function (accId) {
|
||||
onNextClick: function (selectedIndex) {
|
||||
wentNext = true
|
||||
onboardingModule.setSelectedAccountId(accId)
|
||||
OnboardingStore.setCurrentAccount(selectedIndex)
|
||||
createPasswordModal.open()
|
||||
}
|
||||
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
|
||||
anchors.fill: parent
|
||||
|
||||
function setCurrentFlow(isLogin) {
|
||||
LoginStore.loginModelInst.isCurrentFlow = isLogin;
|
||||
OnboardingStore.onBoardingModel.isCurrentFlow = !isLogin;
|
||||
}
|
||||
|
||||
function doLogin(password) {
|
||||
if (loading || password.length === 0)
|
||||
return
|
||||
|
||||
setCurrentFlow(true);
|
||||
loading = true
|
||||
LoginStore.login(password)
|
||||
applicationWindow.checkForStoringPassToKeychain(LoginStore.currentAccount.username, password, false)
|
||||
|
@ -116,7 +110,6 @@ Item {
|
|||
ConfirmAddExistingKeyModal {
|
||||
id: confirmAddExstingKeyModal
|
||||
onOpenModalClick: function () {
|
||||
setCurrentFlow(false);
|
||||
onExistingKeyClicked()
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +121,6 @@ Item {
|
|||
resetLogin()
|
||||
}
|
||||
onOpenModalClick: function () {
|
||||
setCurrentFlow(true);
|
||||
onExistingKeyClicked()
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +177,7 @@ Item {
|
|||
anchors.top: changeAccountBtn.bottom
|
||||
anchors.topMargin: Style.current.padding * 2
|
||||
enabled: !loading
|
||||
placeholderText: loading ?
|
||||
placeholderText: loading ?
|
||||
//% "Connecting..."
|
||||
qsTrId("connecting") :
|
||||
//% "Enter password"
|
||||
|
@ -259,7 +251,6 @@ Item {
|
|||
anchors.topMargin: 16
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
onClicked: {
|
||||
setCurrentFlow(false);
|
||||
onGenKeyClicked()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,10 +42,11 @@ Item {
|
|||
width: walletView.width
|
||||
|
||||
Component.onCompleted: {
|
||||
if(RootStore.firstTimeLogin){
|
||||
RootStore.firstTimeLogin = false
|
||||
RootStore.setInitialRange()
|
||||
}
|
||||
// Read in RootStore
|
||||
// if(RootStore.firstTimeLogin){
|
||||
// RootStore.firstTimeLogin = false
|
||||
// RootStore.setInitialRange()
|
||||
// }
|
||||
}
|
||||
|
||||
Timer {
|
||||
|
|
|
@ -25,7 +25,12 @@ QtObject {
|
|||
|
||||
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: {
|
||||
let count = walletModel.tokensView.defaultTokenList.rowCount()
|
||||
|
|
|
@ -54,10 +54,11 @@ Item {
|
|||
width: walletView.width
|
||||
|
||||
Component.onCompleted: {
|
||||
if (walletView.store.onboardingModelInst.firstTimeLogin) {
|
||||
walletView.store.onboardingModelInst.firstTimeLogin = false;
|
||||
walletView.store.walletModelInst.setInitialRange();
|
||||
}
|
||||
// Read in RootStore
|
||||
// if (walletView.store.onboardingModelInst.firstTimeLogin) {
|
||||
// walletView.store.onboardingModelInst.firstTimeLogin = false;
|
||||
// walletView.store.walletModelInst.setInitialRange();
|
||||
// }
|
||||
}
|
||||
|
||||
leftPanel: LeftTabView {
|
||||
|
|
|
@ -24,7 +24,7 @@ Item {
|
|||
//% "Invalid seed phrase"
|
||||
errorText.text = qsTrId("custom-seed-phrase")
|
||||
} 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');
|
||||
if (regex.test(errorText.text)) {
|
||||
//% "Invalid seed phrase"
|
||||
|
|
|
@ -3,6 +3,10 @@ pragma Singleton
|
|||
import QtQuick 2.13
|
||||
|
||||
QtObject {
|
||||
readonly property int onboardingAppState: 0
|
||||
readonly property int loginAppSate: 1
|
||||
readonly property int mainAppState: 2
|
||||
|
||||
readonly property int communityImported: 0
|
||||
readonly property int communityImportingInProgress: 1
|
||||
readonly property int communityImportingError: 2
|
||||
|
|
14
ui/main.qml
14
ui/main.qml
|
@ -20,7 +20,7 @@ import "./app/AppLayouts/Onboarding/views"
|
|||
import "./app"
|
||||
|
||||
StatusWindow {
|
||||
property bool hasAccounts: startupModule.startWithOnboardingScreen
|
||||
property bool hasAccounts: startupModule.appState !== Constants.onboardingAppState
|
||||
property bool removeMnemonicAfterLogin: false
|
||||
property alias dragAndDrop: dragTarget
|
||||
property bool popupOpened: false
|
||||
|
@ -361,7 +361,8 @@ StatusWindow {
|
|||
|
||||
DSM.SignalTransition {
|
||||
targetState: appState
|
||||
signal: onboardingModel.moveToAppState
|
||||
signal: startupModule.appStateChanged
|
||||
guard: state == Constants.mainAppState
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,7 +372,8 @@ StatusWindow {
|
|||
|
||||
DSM.SignalTransition {
|
||||
targetState: appState
|
||||
signal: onboardingModel.moveToAppState
|
||||
signal: startupModule.appStateChanged
|
||||
guard: state == Constants.mainAppState
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,7 +383,8 @@ StatusWindow {
|
|||
|
||||
DSM.SignalTransition {
|
||||
targetState: appState
|
||||
signal: onboardingModel.moveToAppState
|
||||
signal: startupModule.appStateChanged
|
||||
guard: state == Constants.mainAppState
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,7 +394,8 @@ StatusWindow {
|
|||
|
||||
DSM.SignalTransition {
|
||||
targetState: appState
|
||||
signal: loginModel.moveToAppState
|
||||
signal: startupModule.appStateChanged
|
||||
guard: state == Constants.mainAppState
|
||||
}
|
||||
|
||||
DSM.SignalTransition {
|
||||
|
|
Loading…
Reference in New Issue