Events class is forwarded instead of whole AppService

This commit is contained in:
Sale Djenic 2021-10-16 18:14:08 +02:00 committed by Iuri Matias
parent c3a374c36a
commit 3e0d312fee
11 changed files with 171 additions and 43 deletions

View File

@ -1,6 +1,7 @@
import NimQml, os, strformat
import ../../app_service/service/local_settings/service as local_settings_service
import ../../app_service/service/keychain/service as keychain_service
import ../../app_service/service/accounts/service as accounts_service
import ../../app_service/service/contacts/service as contact_service
import ../../app_service/service/chat/service as chat_service
@ -14,6 +15,8 @@ import global_singleton
# and improved some services, like EventsService which should implement
# provider/subscriber principe:
import ../../app_service/[main]
import eventemitter
import status/[fleet]
#################################################
# At the end of refactoring this will be moved to
@ -49,6 +52,7 @@ type
appService: AppService
# Services
localSettingsService: local_settings_service.Service
keychainService: keychain_service.Service
accountsService: accounts_service.Service
contactService: contact_service.Service
chatService: chat_service.Service
@ -100,13 +104,15 @@ proc newAppController*(appService: AppService): AppController =
result.appService = appService
# Services
result.localSettingsService = local_settings_service.newService()
result.keychainService = keychain_service.newService(result.localSettingsService, appService.status.events)
result.accountsService = accounts_service.newService()
result.contactService = contact_service.newService()
result.chatService = chat_service.newService()
result.communityService = community_service.newService(result.chatService)
# Modules
result.startupModule = startup_module.newModule[AppController](result, appService,
result.accountsService)
result.startupModule = startup_module.newModule[AppController](result,
appService.status.events, appService.status.fleet, result.localSettingsService,
result.keychainService, result.accountsService)
result.mainModule = main_module.newModule[AppController](result, result.chatService,
result.communityService)

View File

@ -3,10 +3,13 @@ import Tables, chronicles
import controller_interface
import io_interface
import status/[signals]
import ../../../app_service/[main]
import ../../../app_service/service/local_settings/service as local_settings_service
import ../../../app_service/service/keychain/service as keychain_service
import ../../../app_service/service/accounts/service_interface as accounts_service
import eventemitter
import status/[signals]
export controller_interface
logScope:
@ -15,35 +18,39 @@ logScope:
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
appService: AppService
events: EventEmitter
localSettingsService: local_settings_service.Service
keychainService: keychain_service.Service
accountsService: accounts_service.ServiceInterface
proc newController*(delegate: io_interface.AccessInterface,
appService: AppService,
events: EventEmitter,
localSettingsService: local_settings_service.Service,
keychainService: keychain_service.Service,
accountsService: accounts_service.ServiceInterface):
Controller =
result = Controller()
result.delegate = delegate
result.appService = appService
result.events = events
result.accountsService = accountsService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args):
self.events.on(SignalType.NodeLogin.event) do(e:Args):
let signal = NodeSignal(e)
if signal.event.error == "":
self.delegate.userLoggedIn()
else:
error "error: ", methodName="init", errDesription = "login error " & signal.event.error
self.appService.status.events.on(SignalType.NodeStopped.event) do(e:Args):
self.events.on(SignalType.NodeStopped.event) do(e:Args):
echo "-NEW-EVENT-- NodeStopped: ", repr(e)
#self.status.events.emit("nodeStopped", Args())
#self.view.onLoggedOut()
self.appService.status.events.on(SignalType.NodeReady.event) do(e:Args):
self.events.on(SignalType.NodeReady.event) do(e:Args):
echo "-NEW-EVENT-- NodeReady: ", repr(e)
#self.status.events.emit("nodeReady", Args())

View File

@ -3,33 +3,34 @@ import Tables
import controller_interface
import io_interface
import status/[signals]
import ../../../../app_service/[main]
import ../../../../app_service/service/accounts/service_interface as accounts_service
import eventemitter
import status/[signals]
export controller_interface
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
appService: AppService
events: EventEmitter
accountsService: accounts_service.ServiceInterface
selectedAccountKeyUid: string
proc newController*(delegate: io_interface.AccessInterface,
appService: AppService,
events: EventEmitter,
accountsService: accounts_service.ServiceInterface):
Controller =
result = Controller()
result.delegate = delegate
result.appService = appService
result.events = events
result.accountsService = accountsService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args):
self.events.on(SignalType.NodeLogin.event) do(e:Args):
let signal = NodeSignal(e)
if signal.event.error != "":
self.delegate.loginAccountError(signal.event.error)

View File

@ -4,9 +4,10 @@ import ../io_interface as delegate_interface
import view, controller, item
import ../../../../app/boot/global_singleton
import ../../../../app_service/[main]
import ../../../../app_service/service/accounts/service_interface as accounts_service
import eventemitter
export io_interface
type
@ -18,14 +19,14 @@ type
moduleLoaded: bool
proc newModule*(delegate: delegate_interface.AccessInterface,
appService: AppService,
events: EventEmitter,
accountsService: accounts_service.ServiceInterface):
Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, appService, accountsService)
result.controller = controller.newController(result, events, accountsService)
result.moduleLoaded = false
singletonInstance.engine.setRootContextProperty("loginModule", result.viewVariant)

View File

@ -7,9 +7,13 @@ import ../../../app/boot/global_singleton
import onboarding/module as onboarding_module
import login/module as login_module
import ../../../app_service/[main]
import ../../../app_service/service/local_settings/service as local_settings_service
import ../../../app_service/service/keychain/service as keychain_service
import ../../../app_service/service/accounts/service_interface as accounts_service
import eventemitter
import status/[fleet]
export io_interface
type
@ -22,18 +26,22 @@ type
loginModule: login_module.AccessInterface
proc newModule*[T](delegate: T,
appService: AppService,
events: EventEmitter,
fleet: FleetModel,
localSettingsService: local_settings_service.Service,
keychainService: keychain_service.Service,
accountsService: accounts_service.ServiceInterface):
Module[T] =
result = Module[T]()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, appService, accountsService)
result.controller = controller.newController(result, events, localSettingsService,
keychainService, accountsService)
# Submodules
result.onboardingModule = onboarding_module.newModule(result, appService, accountsService)
result.loginModule = login_module.newModule(result, appService, accountsService)
result.onboardingModule = onboarding_module.newModule(result, events, fleet, accountsService)
result.loginModule = login_module.newModule(result, events, accountsService)
method delete*[T](self: Module[T]) =
self.onboardingModule.delete

View File

@ -3,10 +3,11 @@ import Tables, chronicles
import controller_interface
import io_interface
import status/[signals]
import ../../../../app_service/[main]
import ../../../../app_service/service/accounts/service_interface as accounts_service
import eventemitter
import status/[signals, fleet]
export controller_interface
logScope:
@ -16,24 +17,27 @@ type
Controller* =
ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
appService: AppService
events: EventEmitter
fleet: FleetModel
accountsService: accounts_service.ServiceInterface
selectedAccountId: string
proc newController*(delegate: io_interface.AccessInterface,
appService: AppService,
events: EventEmitter,
fleet: FleetModel,
accountsService: accounts_service.ServiceInterface):
Controller =
result = Controller()
result.delegate = delegate
result.appService = appService
result.events = events
result.fleet = fleet
result.accountsService = accountsService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args):
self.events.on(SignalType.NodeLogin.event) do(e:Args):
let signal = NodeSignal(e)
if signal.event.error != "":
self.delegate.setupAccountError()
@ -49,7 +53,7 @@ method setSelectedAccountByIndex*(self: Controller, index: int) =
self.selectedAccountId = accounts[index].id
method storeSelectedAccountAndLogin*(self: Controller, password: string) =
if(not self.accountsService.setupAccount(self.appService.status.fleet.config,
if(not self.accountsService.setupAccount(self.fleet.config,
self.selectedAccountId, password)):
self.delegate.setupAccountError()

View File

@ -4,9 +4,11 @@ import ../io_interface as delegate_interface
import view, controller, item
import ../../../../app/boot/global_singleton
import ../../../../app_service/[main]
import ../../../../app_service/service/accounts/service_interface as accounts_service
import eventemitter
import status/[fleet]
export io_interface
type
@ -18,14 +20,16 @@ type
moduleLoaded: bool
proc newModule*(delegate: delegate_interface.AccessInterface,
appService: AppService,
events: EventEmitter,
fleet: FleetModel,
accountsService: accounts_service.ServiceInterface):
Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, appService, accountsService)
result.controller = controller.newController(result, events, fleet,
accountsService)
result.moduleLoaded = false
singletonInstance.engine.setRootContextProperty("onboardingModule", result.viewVariant)

View File

@ -0,0 +1,88 @@
import NimQml, chronicles
#Tables, json, sequtils, strutils, strformat, uuids
#import json_serialization,
import ../local_settings/service as local_settings_service
import eventemitter
logScope:
topics = "keychain-service"
# Local Account Settings keys:
const LS_KEY_STORE_TO_KEYCHAIN* = "storeToKeychain"
# Local Account Settings values:
const LS_VALUE_STORE* = "store"
const ERROR_TYPE_AUTHENTICATION = "authentication"
const ERROR_TYPE_KEYCHAIN = "keychain"
type
KeyChainServiceArg* = ref object of Args
data*: string
errCode: int
errType: string
errDescription: string
QtObject:
type Service* = ref object of QObject
localSettingsService: local_settings_service.Service
events: EventEmitter
keychainManager: StatusKeychainManager
proc setup(self: Service) =
self.QObject.setup
self.keychainManager = newStatusKeychainManager("StatusDesktop", "authenticate you")
signalConnect(self.keychainManager, "success(QString)", self,
"onKeychainManagerSuccess(QString)", 2)
signalConnect(self.keychainManager, "error(QString, int, QString)", self,
"onKeychainManagerError(QString, int, QString)", 2)
proc delete*(self: Service) =
self.keychainManager.delete
self.QObject.delete
proc newService*(localSettingsService: local_settings_service.Service,
events: EventEmitter):
Service =
new(result, delete)
result.setup()
result.localSettingsService = localSettingsService
result.events = events
proc storePassword*(self: Service, username: string, password: string) =
let value = self.localSettingsService.getAccountValue(
LS_KEY_STORE_TO_KEYCHAIN).stringVal
if (value != LS_VALUE_STORE or username.len == 0):
return
self.keychainManager.storeDataAsync(username, password)
proc tryToObtainPassword*(self: Service, username: string) =
let value = self.localSettingsService.getAccountValue(
LS_KEY_STORE_TO_KEYCHAIN).stringVal
if (value != LS_VALUE_STORE):
return
self.keychainManager.readDataAsync(username)
proc onKeychainManagerError*(self: Service, errorType: string, errorCode: int,
errorDescription: string) {.slot.} =
## This slot is called in case an error occured while we're dealing with
## KeychainManager. So far we're just logging the error.
info "KeychainManager stopped: ", msg = errorCode, errorDescription
if (errorType == ERROR_TYPE_AUTHENTICATION):
return
# We are notifying user only about keychain errors.
self.localSettingsService.removeAccountValue(LS_KEY_STORE_TO_KEYCHAIN)
let arg = KeyChainServiceArg(errCode: errorCode, errType: errorType,
errDescription: errorDescription)
self.events.emit("obtainingPasswordError", arg)
proc onKeychainManagerSuccess*(self: Service, data: string) {.slot.} =
## This slot is called in case a password is successfully retrieved from the
## Keychain. In this case @data contains required password.
self.events.emit("obtainingPasswordSuccess", KeyChainServiceArg(data: data))

View File

@ -0,0 +1,7 @@
# We cannot have interface defined here, bacause of Nim limitation in terms of
# multiple inheritances, since this service already inherits from QtObject
# Concepts cannot be used also because of other limitation cause we cannot
# forward this class to appropriate submodule, cause Nim doesn't support
# nested types which depends on concepts.

View File

@ -1,11 +1,6 @@
import NimQml, os, chronicles
import ../../../constants
# Local Account Settings keys:
const LS_KEY_STORE_TO_KEYCHAIN* = "storeToKeychain"
# Local Account Settings values:
const LS_VALUE_STORE* = "store"
const UNKNOWN_ACCOUNT = "unknownAccount"
const UNKNOWN_PROFILE = "unknownProfile"

View File

@ -11,7 +11,11 @@ QtObject {
property var walletModelV2Inst: walletV2Model
property var profileModelInst: profileModel
property var chatsModelInst: chatsModel
property var onboardingModelInst: onboardingModel
// 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 var onboardingModelInst: onboardingModel
property int selectedAccount: 0
function getSavedAddressErrorText(savedAddresses, error) {
@ -57,9 +61,12 @@ QtObject {
property bool loadingAccounts: false
function seedPhraseNotFound(text) {
var seedValidationError = root.onboardingModelInst.validateMnemonic(text);
var regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
return regex.test(seedValidationError);
// Read in above
// var seedValidationError = root.onboardingModelInst.validateMnemonic(text);
// var regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
// return regex.test(seedValidationError);
return ""
}
function validateAddAccountPopup(text, model, keyOrSeedValid, accountNameValid) {