status-desktop/src/app/boot/app_controller.nim
2022-12-09 18:56:33 +03:00

430 lines
18 KiB
Nim

import NimQml, sequtils, sugar, chronicles
import ../../app_service/service/general/service as general_service
import ../../app_service/service/keychain/service as keychain_service
import ../../app_service/service/keycard/service as keycard_service
import ../../app_service/service/accounts/service as accounts_service
import ../../app_service/service/contacts/service as contacts_service
import ../../app_service/service/language/service as language_service
import ../../app_service/service/chat/service as chat_service
import ../../app_service/service/community/service as community_service
import ../../app_service/service/message/service as message_service
import ../../app_service/service/token/service as token_service
import ../../app_service/service/transaction/service as transaction_service
import ../../app_service/service/collectible/service as collectible_service
import ../../app_service/service/wallet_account/service as wallet_account_service
import ../../app_service/service/bookmarks/service as bookmark_service
import ../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../../app_service/service/privacy/service as privacy_service
import ../../app_service/service/provider/service as provider_service
import ../../app_service/service/node/service as node_service
import ../../app_service/service/profile/service as profile_service
import ../../app_service/service/settings/service as settings_service
import ../../app_service/service/stickers/service as stickers_service
import ../../app_service/service/about/service as about_service
import ../../app_service/service/node_configuration/service as node_configuration_service
import ../../app_service/service/network/service as network_service
import ../../app_service/service/activity_center/service as activity_center_service
import ../../app_service/service/saved_address/service as saved_address_service
import ../../app_service/service/devices/service as devices_service
import ../../app_service/service/mailservers/service as mailservers_service
import ../../app_service/service/gif/service as gif_service
import ../../app_service/service/ens/service as ens_service
import ../../app_service/common/account_constants
import ../modules/startup/module as startup_module
import ../modules/main/module as main_module
import ../core/notifications/notifications_manager
import ../global/global_singleton
import ../core/[main]
logScope:
topics = "app-controller"
type
AppController* = ref object of RootObj
storeKeyPair: bool
statusFoundation: StatusFoundation
notificationsManager*: NotificationsManager
# Global
appSettingsVariant: QVariant
localAppSettingsVariant: QVariant
localAccountSettingsVariant: QVariant
localAccountSensitiveSettingsVariant: QVariant
userProfileVariant: QVariant
globalUtilsVariant: QVariant
# Services
generalService: general_service.Service
keycardService*: keycard_service.Service
keychainService: keychain_service.Service
accountsService: accounts_service.Service
contactsService: contacts_service.Service
chatService: chat_service.Service
communityService: community_service.Service
messageService: message_service.Service
tokenService: token_service.Service
transactionService: transaction_service.Service
collectibleService: collectible_service.Service
walletAccountService: wallet_account_service.Service
bookmarkService: bookmark_service.Service
dappPermissionsService: dapp_permissions_service.Service
providerService: provider_service.Service
profileService: profile_service.Service
settingsService: settings_service.Service
stickersService: stickers_service.Service
aboutService: about_service.Service
networkService: network_service.Service
activityCenterService: activity_center_service.Service
languageService: language_service.Service
# mnemonicService: mnemonic_service.Service
privacyService: privacy_service.Service
nodeConfigurationService: node_configuration_service.Service
savedAddressService: saved_address_service.Service
devicesService: devices_service.Service
mailserversService: mailservers_service.Service
nodeService: node_service.Service
gifService: gif_service.Service
ensService: ens_service.Service
# Modules
startupModule: startup_module.AccessInterface
mainModule: main_module.AccessInterface
#################################################
# Forward declaration section
proc load(self: AppController)
proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController)
proc buildAndRegisterUserProfile(self: AppController)
# Startup Module Delegate Interface
proc startupDidLoad*(self: AppController)
proc userLoggedIn*(self: AppController)
proc logout*(self: AppController)
proc storeKeyPairForNewKeycardUser*(self: AppController)
# Main Module Delegate Interface
proc mainDidLoad*(self: AppController)
#################################################
proc connect(self: AppController) =
self.statusFoundation.events.once("nodeStopped") do(a: Args):
# not sure, but maybe we should take some actions when node stops
discard
proc newAppController*(statusFoundation: StatusFoundation): AppController =
result = AppController()
result.storeKeyPair = false
result.statusFoundation = statusFoundation
# Preparing settings service to be exposed later as global QObject
result.settingsService = settings_service.newService(statusFoundation.events)
result.appSettingsVariant = newQVariant(result.settingsService)
result.notificationsManager = newNotificationsManager(statusFoundation.events, result.settingsService)
# Global
result.localAppSettingsVariant = newQVariant(singletonInstance.localAppSettings)
result.localAccountSettingsVariant = newQVariant(singletonInstance.localAccountSettings)
result.localAccountSensitiveSettingsVariant = newQVariant(singletonInstance.localAccountSensitiveSettings)
result.userProfileVariant = newQVariant(singletonInstance.userProfile)
result.globalUtilsVariant = newQVariant(singletonInstance.utils)
# Services
result.generalService = general_service.newService()
result.activityCenterService = activity_center_service.newService(statusFoundation.events, statusFoundation.threadpool)
result.keycardService = keycard_service.newService(statusFoundation.events, statusFoundation.threadpool)
result.nodeConfigurationService = node_configuration_service.newService(statusFoundation.fleetConfiguration,
result.settingsService, statusFoundation.events)
result.keychainService = keychain_service.newService(statusFoundation.events)
result.accountsService = accounts_service.newService(statusFoundation.events, statusFoundation.threadpool,
statusFoundation.fleetConfiguration)
result.networkService = network_service.newService(statusFoundation.events, result.settingsService)
result.contactsService = contacts_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.networkService, result.settingsService,
result.activityCenterService
)
result.chatService = chat_service.newService(statusFoundation.events, result.contactsService)
result.communityService = community_service.newService(statusFoundation.events,
statusFoundation.threadpool, result.chatService, result.activityCenterService)
result.tokenService = token_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.networkService
)
result.collectibleService = collectible_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService)
result.walletAccountService = wallet_account_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.settingsService, result.accountsService,
result.tokenService, result.networkService,
)
result.messageService = message_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.contactsService, result.tokenService, result.walletAccountService, result.networkService
)
result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService, result.settingsService, result.tokenService)
result.bookmarkService = bookmark_service.newService(statusFoundation.events)
result.profileService = profile_service.newService(result.contactsService, result.settingsService)
result.stickersService = stickers_service.newService(
statusFoundation.events,
statusFoundation.threadpool,
result.settingsService,
result.walletAccountService,
result.transactionService,
result.networkService,
result.chatService,
result.tokenService
)
result.aboutService = about_service.newService(statusFoundation.events, statusFoundation.threadpool)
result.dappPermissionsService = dapp_permissions_service.newService()
result.languageService = language_service.newService(statusFoundation.events)
# result.mnemonicService = mnemonic_service.newService()
result.privacyService = privacy_service.newService(statusFoundation.events, result.settingsService,
result.accountsService)
result.savedAddressService = saved_address_service.newService(statusFoundation.events, result.networkService)
result.devicesService = devices_service.newService(statusFoundation.events, result.settingsService)
result.mailserversService = mailservers_service.newService(statusFoundation.events, statusFoundation.threadpool,
result.settingsService, result.nodeConfigurationService, statusFoundation.fleetConfiguration)
result.nodeService = node_service.newService(statusFoundation.events, statusFoundation.threadpool,
result.settingsService, result.nodeConfigurationService)
result.gifService = gif_service.newService(result.settingsService)
result.ensService = ens_service.newService(statusFoundation.events, statusFoundation.threadpool,
result.settingsService, result.walletAccountService, result.transactionService,
result.networkService, result.tokenService)
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
# Modules
result.startupModule = startup_module.newModule[AppController](
result,
statusFoundation.events,
result.keychainService,
result.accountsService,
result.generalService,
result.profileService,
result.keycardService
)
result.mainModule = main_module.newModule[AppController](
result,
statusFoundation.events,
statusFoundation.urlsManager,
result.keychainService,
result.accountsService,
result.chatService,
result.communityService,
result.messageService,
result.tokenService,
result.transactionService,
result.collectibleService,
result.walletAccountService,
result.bookmarkService,
result.profileService,
result.settingsService,
result.contactsService,
result.aboutService,
result.dappPermissionsService,
result.languageService,
# result.mnemonicService,
result.privacyService,
result.providerService,
result.stickersService,
result.activityCenterService,
result.savedAddressService,
result.nodeConfigurationService,
result.devicesService,
result.mailserversService,
result.nodeService,
result.gifService,
result.ensService,
result.networkService,
result.generalService,
result.keycardService
)
# Do connections
result.connect()
proc delete*(self: AppController) =
singletonInstance.delete
self.notificationsManager.delete
self.keychainService.delete
self.contactsService.delete
self.bookmarkService.delete
self.gifService.delete
if not self.startupModule.isNil:
self.startupModule.delete
self.mainModule.delete
self.languageService.delete
self.appSettingsVariant.delete
self.localAppSettingsVariant.delete
self.localAccountSettingsVariant.delete
self.localAccountSensitiveSettingsVariant.delete
self.userProfileVariant.delete
self.globalUtilsVariant.delete
self.accountsService.delete
self.chatService.delete
self.communityService.delete
self.tokenService.delete
self.transactionService.delete
self.collectibleService.delete
self.walletAccountService.delete
self.aboutService.delete
self.networkService.delete
self.activityCenterService.delete
self.dappPermissionsService.delete
self.providerService.delete
self.nodeConfigurationService.delete
self.nodeService.delete
self.settingsService.delete
self.stickersService.delete
self.savedAddressService.delete
self.devicesService.delete
self.mailserversService.delete
self.messageService.delete
self.privacyService.delete
self.profileService.delete
self.generalService.delete
self.ensService.delete
self.gifService.delete
self.keycardService.delete
proc startupDidLoad*(self: AppController) =
singletonInstance.engine.setRootContextProperty("localAppSettings", self.localAppSettingsVariant)
singletonInstance.engine.setRootContextProperty("localAccountSettings", self.localAccountSettingsVariant)
singletonInstance.engine.setRootContextProperty("globalUtils", self.globalUtilsVariant)
singletonInstance.engine.load(newQUrl("qrc:///main.qml"))
# We need to init a language service once qml is loaded
self.languageService.init()
# We need this to set app width/height appropriatelly on the app start.
self.startupModule.startUpUIRaised()
proc mainDidLoad*(self: AppController) =
self.startupModule.moveToAppState()
self.mainModule.checkForStoringPassword()
proc start*(self: AppController) =
self.keycardService.init()
self.keychainService.init()
self.generalService.init()
self.accountsService.init()
self.startupModule.load()
proc load(self: AppController) =
self.notificationsManager.init()
self.settingsService.init()
self.nodeConfigurationService.init()
self.mailserversService.init()
self.contactsService.init()
self.chatService.init()
self.messageService.init()
self.communityService.init()
self.bookmarkService.init()
self.dappPermissionsService.init()
self.providerService.init()
self.transactionService.init()
self.stickersService.init()
self.activityCenterService.init()
self.savedAddressService.init()
self.aboutService.init()
self.devicesService.init()
self.ensService.init()
self.gifService.init()
# Accessible after user login
singletonInstance.engine.setRootContextProperty("appSettings", self.appSettingsVariant)
singletonInstance.engine.setRootContextProperty("globalUtils", self.globalUtilsVariant)
self.buildAndRegisterLocalAccountSensitiveSettings()
self.buildAndRegisterUserProfile()
self.networkService.init()
self.tokenService.init()
self.walletAccountService.init()
# load main module
self.mainModule.load(
self.statusFoundation.events,
self.settingsService,
self.nodeConfigurationService,
self.contactsService,
self.chatService,
self.communityService,
self.messageService,
self.gifService,
self.mailserversService,
)
proc userLoggedIn*(self: AppController) =
self.generalService.startMessenger()
self.load()
self.statusFoundation.userLoggedIn()
# Once user is logged in and main module is loaded we need to check if it gets here importing mnemonic or not
# and delete mnemonic in the first case.
let importedAccount = self.accountsService.getImportedAccount()
if(importedAccount.isValid()):
self.privacyService.removeMnemonic()
if not self.startupModule.isNil:
self.startupModule.delete
proc logout*(self: AppController) =
self.generalService.logout()
proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController) =
var pubKey = self.settingsService.getPublicKey()
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)
singletonInstance.engine.setRootContextProperty("localAccountSensitiveSettings", self.localAccountSensitiveSettingsVariant)
proc buildAndRegisterUserProfile(self: AppController) =
let pubKey = self.settingsService.getPublicKey()
let alias = self.settingsService.getName()
let preferredName = self.settingsService.getPreferredName()
var displayName = self.settingsService.getDisplayName()
let ensUsernames = self.settingsService.getEnsUsernames()
let firstEnsName = if (ensUsernames.len > 0): ensUsernames[0] else: ""
let currentUserStatus = self.settingsService.getCurrentUserStatus()
let loggedInAccount = self.accountsService.getLoggedInAccount()
var thumbnail, large: string
for img in loggedInAccount.images:
if(img.imgType == "large"):
large = img.uri
elif(img.imgType == "thumbnail"):
thumbnail = img.uri
singletonInstance.userProfile.setFixedData(alias, loggedInAccount.keyUid, pubKey, loggedInAccount.keycardPairing.len > 0)
singletonInstance.userProfile.setDisplayName(displayName)
singletonInstance.userProfile.setPreferredName(preferredName)
singletonInstance.userProfile.setEnsName(firstEnsName)
singletonInstance.userProfile.setThumbnailImage(thumbnail)
singletonInstance.userProfile.setLargeImage(large)
singletonInstance.userProfile.setCurrentUserStatus(currentUserStatus.statusType.int)
singletonInstance.engine.setRootContextProperty("userProfile", self.userProfileVariant)
if self.storeKeyPair and singletonInstance.userProfile.getIsKeycardUser():
let allAccounts = self.walletAccountService.fetchAccounts()
let defaultWalletAccounts = allAccounts.filter(a =>
a.walletType == WalletTypeDefaultStatusAccount and
a.path == account_constants.PATH_DEFAULT_WALLET and
not a.isChat and
a.isWallet
)
if defaultWalletAccounts.len == 0:
error "default wallet account was not generated"
return
let defaultWalletAddress = defaultWalletAccounts[0].address
let keyPair = KeyPairDto(keycardUid: self.keycardService.getLastReceivedKeycardData().flowEvent.instanceUID,
keycardName: displayName,
keycardLocked: false,
accountsAddresses: @[defaultWalletAddress],
keyUid: loggedInAccount.keyUid)
let keystoreDir = self.accountsService.getKeyStoreDir()
discard self.walletAccountService.addMigratedKeyPair(keyPair, keystoreDir)
proc storeKeyPairForNewKeycardUser*(self: AppController) =
self.storeKeyPair = true