refactor(general): `nim_status_client.nim` file cleaned
Parts which are not refactored yet are moved to `AppController` and marked there (a comment is added for a sake of clarification) that those parts will be removed once we complete refactor phase.
This commit is contained in:
parent
1ccc98af98
commit
80b94d6519
|
@ -35,10 +35,18 @@ import ../global/global_singleton
|
||||||
# This will be removed later once we move to c++ and handle there async things
|
# This will be removed later once we move to c++ and handle there async things
|
||||||
# and improved some services, like EventsService which should implement
|
# and improved some services, like EventsService which should implement
|
||||||
# provider/subscriber principe, similar we should have SettingsService.
|
# provider/subscriber principe, similar we should have SettingsService.
|
||||||
|
import ../../constants
|
||||||
import ../core/[main]
|
import ../core/[main]
|
||||||
import eventemitter
|
import eventemitter
|
||||||
import status/[fleet]
|
import status/[fleet]
|
||||||
import ../profile/core as profile
|
import ../profile/core as profile
|
||||||
|
import ../chat/core as chat
|
||||||
|
import ../wallet/v1/core as wallet
|
||||||
|
import ../wallet/v2/core as walletV2
|
||||||
|
import ../node/core as node
|
||||||
|
import ../utilsView/core as utilsView
|
||||||
|
import ../provider/core as provider
|
||||||
|
import ../keycard/core as keycard
|
||||||
import status/types/[account, setting]
|
import status/types/[account, setting]
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
|
@ -103,9 +111,15 @@ type
|
||||||
mainModule: main_module.AccessInterface
|
mainModule: main_module.AccessInterface
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
# At the end of refactoring this will be moved to
|
# At the end of refactoring this will be moved to appropriate place or removed:
|
||||||
# appropriate place or removed:
|
|
||||||
profile: ProfileController
|
profile: ProfileController
|
||||||
|
wallet: wallet.WalletController
|
||||||
|
wallet2: walletV2.WalletController
|
||||||
|
chat: ChatController
|
||||||
|
node: NodeController
|
||||||
|
utilsController: UtilsController
|
||||||
|
provider: Web3ProviderController
|
||||||
|
keycard: KeycardController
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
|
@ -123,12 +137,25 @@ proc mainDidLoad*(self: AppController)
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
# At the end of refactoring this will be moved to
|
# At the end of refactoring this will be moved to appropriate place or removed:
|
||||||
# appropriate place or removed:
|
|
||||||
proc connect(self: AppController) =
|
proc connect(self: AppController) =
|
||||||
self.statusFoundation.status.events.once("loginCompleted") do(a: Args):
|
self.statusFoundation.status.events.once("loginCompleted") do(a: Args):
|
||||||
var args = AccountArgs(a)
|
var args = AccountArgs(a)
|
||||||
|
self.statusFoundation.status.startMessenger()
|
||||||
self.profile.init(args.account)
|
self.profile.init(args.account)
|
||||||
|
self.wallet.init()
|
||||||
|
self.wallet2.init()
|
||||||
|
self.provider.init()
|
||||||
|
self.chat.init()
|
||||||
|
self.utilsController.init()
|
||||||
|
self.node.init()
|
||||||
|
self.wallet.onLogin()
|
||||||
|
|
||||||
|
self.statusFoundation.status.events.once("nodeStopped") do(a: Args):
|
||||||
|
# TODO: remove this once accounts are not tracked in the AccountsModel
|
||||||
|
self.statusFoundation.status.reset()
|
||||||
|
# 2. Re-init controllers that don't require a running node
|
||||||
|
self.keycard.init()
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
|
@ -202,9 +229,15 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
)
|
)
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
# At the end of refactoring this will be moved to
|
# At the end of refactoring this will be moved to appropriate place or removed:
|
||||||
# appropriate place or removed:
|
|
||||||
result.profile = profile.newController(statusFoundation.status, statusFoundation, changeLanguage)
|
result.profile = profile.newController(statusFoundation.status, statusFoundation, changeLanguage)
|
||||||
|
result.wallet = wallet.newController(statusFoundation.status, statusFoundation)
|
||||||
|
result.wallet2 = walletV2.newController(statusFoundation.status, statusFoundation)
|
||||||
|
result.chat = chat.newController(statusFoundation.status, statusFoundation, OPENURI)
|
||||||
|
result.node = node.newController(statusFoundation)
|
||||||
|
result.utilsController = utilsView.newController(statusFoundation.status, statusFoundation)
|
||||||
|
result.provider = provider.newController(statusFoundation.status)
|
||||||
|
result.keycard = keycard.newController(statusFoundation.status)
|
||||||
result.connect()
|
result.connect()
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
|
@ -230,9 +263,15 @@ proc delete*(self: AppController) =
|
||||||
self.mainModule.delete
|
self.mainModule.delete
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
# At the end of refactoring this will be moved to
|
# At the end of refactoring this will be moved to appropriate place or removed:
|
||||||
# appropriate place or removed:
|
|
||||||
self.profile.delete
|
self.profile.delete
|
||||||
|
self.wallet.delete
|
||||||
|
self.wallet2.delete
|
||||||
|
self.chat.delete
|
||||||
|
self.node.delete
|
||||||
|
self.utilsController.delete
|
||||||
|
self.provider.delete
|
||||||
|
self.keycard.delete
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
self.localAppSettingsVariant.delete
|
self.localAppSettingsVariant.delete
|
||||||
|
@ -255,9 +294,15 @@ proc delete*(self: AppController) =
|
||||||
|
|
||||||
proc startupDidLoad*(self: AppController) =
|
proc startupDidLoad*(self: AppController) =
|
||||||
#################################################
|
#################################################
|
||||||
# At the end of refactoring this will be moved to
|
# At the end of refactoring this will be moved to appropriate place or removed:
|
||||||
# appropriate place or removed:
|
|
||||||
singletonInstance.engine.setRootContextProperty("profileModel", self.profile.variant)
|
singletonInstance.engine.setRootContextProperty("profileModel", self.profile.variant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("walletModel", self.wallet.variant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("walletV2Model", self.wallet2.variant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("chatsModel", self.chat.variant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("nodeModel", self.node.variant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("utilsModel", self.utilsController.variant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("web3Provider", self.provider.variant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("keycardModel", self.keycard.variant)
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("localAppSettings", self.localAppSettingsVariant)
|
singletonInstance.engine.setRootContextProperty("localAppSettings", self.localAppSettingsVariant)
|
||||||
|
@ -275,6 +320,11 @@ proc mainDidLoad*(self: AppController) =
|
||||||
self.mainModule.checkForStoringPassword()
|
self.mainModule.checkForStoringPassword()
|
||||||
|
|
||||||
proc start*(self: AppController) =
|
proc start*(self: AppController) =
|
||||||
|
#################################################
|
||||||
|
# At the end of refactoring this will be moved to appropriate place or removed:
|
||||||
|
self.keycard.init()
|
||||||
|
#################################################
|
||||||
|
|
||||||
self.accountsService.init()
|
self.accountsService.init()
|
||||||
|
|
||||||
self.startupModule.load()
|
self.startupModule.load()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import NimQml, chronicles, task_runner
|
import NimQml, chronicles, task_runner
|
||||||
|
import ../../constants
|
||||||
import status/status as status_lib_status
|
import status/status as status_lib_status
|
||||||
import
|
import
|
||||||
./tasks/marathon,
|
./tasks/marathon,
|
||||||
|
@ -18,19 +19,23 @@ type StatusFoundation* = ref object
|
||||||
mailserverController*: MailserverController
|
mailserverController*: MailserverController
|
||||||
mailserverWorker*: MailserverWorker
|
mailserverWorker*: MailserverWorker
|
||||||
|
|
||||||
proc newStatusFoundation*(status: Status): StatusFoundation =
|
proc newStatusFoundation*(fleetConfig: string): StatusFoundation =
|
||||||
result = StatusFoundation()
|
result = StatusFoundation()
|
||||||
result.status = status
|
|
||||||
result.mailserverController = newMailserverController(status)
|
result.status = newStatusInstance(fleetConfig)
|
||||||
|
result.status.initNode(STATUSGODIR, KEYSTOREDIR)
|
||||||
|
|
||||||
|
result.mailserverController = newMailserverController(result.status.events)
|
||||||
result.mailserverWorker = newMailserverWorker(cast[ByteAddress](result.mailserverController.vptr))
|
result.mailserverWorker = newMailserverWorker(cast[ByteAddress](result.mailserverController.vptr))
|
||||||
result.threadpool = newThreadPool()
|
result.threadpool = newThreadPool()
|
||||||
result.marathon = newMarathon(result.mailserverWorker)
|
result.marathon = newMarathon(result.mailserverWorker)
|
||||||
result.signalsManager = newSignalsManager(status.events)
|
result.signalsManager = newSignalsManager(result.status.events)
|
||||||
|
|
||||||
proc delete*(self: StatusFoundation) =
|
proc delete*(self: StatusFoundation) =
|
||||||
self.threadpool.teardown()
|
self.threadpool.teardown()
|
||||||
self.marathon.teardown()
|
self.marathon.teardown()
|
||||||
self.signalsManager.delete()
|
self.signalsManager.delete()
|
||||||
|
self.status.reset()
|
||||||
|
|
||||||
proc onLoggedIn*(self: StatusFoundation) =
|
proc onLoggedIn*(self: StatusFoundation) =
|
||||||
self.marathon.onLoggedIn()
|
self.marathon.onLoggedIn()
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
import # std libs
|
||||||
|
strutils
|
||||||
|
|
||||||
import # vendor libs
|
import # vendor libs
|
||||||
chronicles, NimQml, json_serialization
|
chronicles, NimQml, json_serialization
|
||||||
|
|
||||||
import # status-desktop libs
|
import events
|
||||||
status/status, ../../common as task_runner_common
|
import ../../common as task_runner_common
|
||||||
|
|
||||||
|
import eventemitter
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "mailserver controller"
|
topics = "mailserver controller"
|
||||||
|
@ -14,11 +19,11 @@ logScope:
|
||||||
################################################################################
|
################################################################################
|
||||||
QtObject:
|
QtObject:
|
||||||
type MailserverController* = ref object of QObject
|
type MailserverController* = ref object of QObject
|
||||||
status*: Status
|
events: EventEmitter
|
||||||
|
|
||||||
proc newMailserverController*(status: Status): MailserverController =
|
proc newMailserverController*(events: EventEmitter): MailserverController =
|
||||||
new(result)
|
new(result)
|
||||||
result.status = status
|
result.events = events
|
||||||
result.setup()
|
result.setup()
|
||||||
|
|
||||||
proc setup(self: MailserverController) =
|
proc setup(self: MailserverController) =
|
||||||
|
@ -26,3 +31,8 @@ QtObject:
|
||||||
|
|
||||||
proc delete*(self: MailserverController) =
|
proc delete*(self: MailserverController) =
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
|
proc receiveEvent(self: MailserverController, eventTuple: string) {.slot.} =
|
||||||
|
let event = Json.decode(eventTuple, tuple[name: string, arg: MailserverArgs])
|
||||||
|
trace "forwarding event from long-running mailserver task to the main thread", event=eventTuple
|
||||||
|
self.events.emit(event.name, event.arg)
|
|
@ -11,15 +11,13 @@ type NodeController* = ref object
|
||||||
statusFoundation: StatusFoundation
|
statusFoundation: StatusFoundation
|
||||||
view*: NodeView
|
view*: NodeView
|
||||||
variant*: QVariant
|
variant*: QVariant
|
||||||
networkAccessMananger*: QNetworkAccessManager
|
|
||||||
isWakuV2: bool
|
isWakuV2: bool
|
||||||
|
|
||||||
proc newController*(statusFoundation: StatusFoundation, nam: QNetworkAccessManager): NodeController =
|
proc newController*(statusFoundation: StatusFoundation): NodeController =
|
||||||
result = NodeController()
|
result = NodeController()
|
||||||
result.statusFoundation = statusFoundation
|
result.statusFoundation = statusFoundation
|
||||||
result.view = newNodeView(statusFoundation)
|
result.view = newNodeView(statusFoundation)
|
||||||
result.variant = newQVariant(result.view)
|
result.variant = newQVariant(result.view)
|
||||||
result.networkAccessMananger = nam
|
|
||||||
|
|
||||||
proc delete*(self: NodeController) =
|
proc delete*(self: NodeController) =
|
||||||
delete self.variant
|
delete self.variant
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, json, strutils, sugar, sequtils, tables
|
import NimQml, json, tables
|
||||||
import json_serialization
|
import json_serialization
|
||||||
import status/[status, settings]
|
import status/[status, settings]
|
||||||
import status/contacts as status_contacts
|
import status/contacts as status_contacts
|
||||||
|
|
|
@ -1,126 +1,45 @@
|
||||||
import NimQml, chronicles, os, strformat, times, md5, json
|
import NimQml, chronicles, os, strformat, times, md5, json
|
||||||
|
|
||||||
import app/chat/core as chat
|
|
||||||
import app/wallet/v1/core as wallet
|
|
||||||
import app/wallet/v2/core as walletV2
|
|
||||||
import app/node/core as node
|
|
||||||
import app/utilsView/core as utilsView
|
|
||||||
import app/keycard/core as keycard
|
|
||||||
import status/types/[account]
|
|
||||||
import status_go
|
import status_go
|
||||||
import status/status as statuslib
|
|
||||||
import eventemitter
|
|
||||||
import app/core/main
|
import app/core/main
|
||||||
import constants
|
import constants
|
||||||
|
|
||||||
import app/global/global_singleton
|
import app/global/global_singleton
|
||||||
import app/boot/app_controller
|
import app/boot/app_controller
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "status-app"
|
||||||
|
|
||||||
var signalsManagerQObjPointer: pointer
|
var signalsManagerQObjPointer: pointer
|
||||||
|
|
||||||
logScope:
|
proc isExperimental(): string =
|
||||||
topics = "main"
|
result = if getEnv("EXPERIMENTAL") == "1": "1" else: "0" # value explicity passed to avoid trusting input
|
||||||
|
|
||||||
proc mainProc() =
|
proc determineResourcePath(): string =
|
||||||
if defined(macosx) and defined(production):
|
result = if defined(windows) and defined(production): "/../resources/resources.rcc" else: "/../resources.rcc"
|
||||||
setCurrentDir(getAppDir())
|
|
||||||
|
|
||||||
ensureDirectories(DATADIR, TMPDIR, LOGDIR)
|
proc determineFleetsPath(): string =
|
||||||
|
result = if defined(windows) and defined(production): "/../resources/fleets.json" else: "/../fleets.json"
|
||||||
|
|
||||||
let fleets =
|
proc determineOpenUri(): string =
|
||||||
if defined(windows) and defined(production):
|
|
||||||
"/../resources/fleets.json"
|
|
||||||
else:
|
|
||||||
"/../fleets.json"
|
|
||||||
|
|
||||||
let
|
|
||||||
fleetConfig = readFile(joinPath(getAppDir(), fleets))
|
|
||||||
status = statuslib.newStatusInstance(fleetConfig)
|
|
||||||
|
|
||||||
let statusFoundation = newStatusFoundation(status)
|
|
||||||
defer: statusFoundation.delete()
|
|
||||||
|
|
||||||
status.initNode(STATUSGODIR, KEYSTOREDIR)
|
|
||||||
|
|
||||||
let uiScaleFilePath = joinPath(DATADIR, "ui-scale")
|
|
||||||
enableHDPI(uiScaleFilePath)
|
|
||||||
initializeOpenGL()
|
|
||||||
|
|
||||||
let app = newQGuiApplication()
|
|
||||||
defer: app.delete()
|
|
||||||
|
|
||||||
let appController = newAppController(statusFoundation)
|
|
||||||
defer: appController.delete()
|
|
||||||
|
|
||||||
let resources =
|
|
||||||
if defined(windows) and defined(production):
|
|
||||||
"/../resources/resources.rcc"
|
|
||||||
else:
|
|
||||||
"/../resources.rcc"
|
|
||||||
QResource.registerResource(app.applicationDirPath & resources)
|
|
||||||
|
|
||||||
var eventStr = ""
|
|
||||||
if OPENURI.len > 0:
|
if OPENURI.len > 0:
|
||||||
eventStr = $(%* { "uri": OPENURI })
|
result = $(%* { "uri": OPENURI })
|
||||||
let singleInstance = newSingleInstance($toMD5(DATADIR), eventStr)
|
|
||||||
defer: singleInstance.delete()
|
|
||||||
if singleInstance.secondInstance():
|
|
||||||
info "Terminating the app as the second instance"
|
|
||||||
quit()
|
|
||||||
|
|
||||||
let statusAppIcon =
|
proc determineStatusAppIconPath(): string =
|
||||||
if defined(production):
|
if defined(production):
|
||||||
if defined(macosx):
|
if defined(macosx):
|
||||||
"" # not used in macOS
|
return "" # not used in macOS
|
||||||
elif defined(windows):
|
elif defined(windows):
|
||||||
"/../resources/status.svg"
|
return "/../resources/status.svg"
|
||||||
else:
|
|
||||||
"/../status.svg"
|
|
||||||
else:
|
else:
|
||||||
if defined(macosx):
|
return "/../status.svg"
|
||||||
"" # not used in macOS
|
else:
|
||||||
else:
|
if defined(macosx):
|
||||||
"/../status-dev.svg"
|
return "" # not used in macOS
|
||||||
|
else:
|
||||||
if not defined(macosx):
|
return "/../status-dev.svg"
|
||||||
app.icon(app.applicationDirPath & statusAppIcon)
|
|
||||||
|
|
||||||
let networkAccessFactory = newQNetworkAccessManagerFactory(TMPDIR & "netcache")
|
|
||||||
|
|
||||||
singletonInstance.engine.addImportPath("qrc:/./StatusQ/src")
|
|
||||||
singletonInstance.engine.addImportPath("qrc:/./imports")
|
|
||||||
singletonInstance.engine.setNetworkAccessManagerFactory(networkAccessFactory)
|
|
||||||
singletonInstance.engine.setRootContextProperty("uiScaleFilePath", newQVariant(uiScaleFilePath))
|
|
||||||
|
|
||||||
# Register events objects
|
|
||||||
let dockShowAppEvent = newStatusDockShowAppEventObject(singletonInstance.engine)
|
|
||||||
defer: dockShowAppEvent.delete()
|
|
||||||
let osThemeEvent = newStatusOSThemeEventObject(singletonInstance.engine)
|
|
||||||
defer: osThemeEvent.delete()
|
|
||||||
app.installEventFilter(dockShowAppEvent)
|
|
||||||
app.installEventFilter(osThemeEvent)
|
|
||||||
|
|
||||||
let netAccMgr = newQNetworkAccessManager(singletonInstance.engine.getNetworkAccessManager())
|
|
||||||
|
|
||||||
status.events.on("network:connected") do(e: Args):
|
|
||||||
# This is a workaround for Qt bug https://bugreports.qt.io/browse/QTBUG-55180
|
|
||||||
# that was apparently reintroduced in 5.14.1 Unfortunately, the only workaround
|
|
||||||
# that could be found uses obsolete properties and methods
|
|
||||||
# (https://doc.qt.io/qt-5/qnetworkaccessmanager-obsolete.html), so this will
|
|
||||||
# need to be something we keep in mind when upgrading to Qt 6.
|
|
||||||
# The workaround is to manually set the NetworkAccessible property of the
|
|
||||||
# QNetworkAccessManager once peers have dropped (network connection is lost).
|
|
||||||
netAccMgr.clearConnectionCache()
|
|
||||||
netAccMgr.setNetworkAccessible(NetworkAccessibility.Accessible)
|
|
||||||
|
|
||||||
|
|
||||||
# We need this global variable in order to be able to access the application
|
|
||||||
# from the non-closure callback passed to `statusgo_backend.setSignalEventCallback`
|
|
||||||
signalsManagerQObjPointer = cast[pointer](statusFoundation.signalsManager.vptr)
|
|
||||||
defer:
|
|
||||||
signalsManagerQObjPointer = nil
|
|
||||||
|
|
||||||
|
proc prepareLogging() =
|
||||||
when compiles(defaultChroniclesStream.output.writer):
|
when compiles(defaultChroniclesStream.output.writer):
|
||||||
defaultChroniclesStream.output.writer =
|
defaultChroniclesStream.output.writer =
|
||||||
proc (logLevel: LogLevel, msg: LogOutputStr) {.gcsafe, raises: [Defect].} =
|
proc (logLevel: LogLevel, msg: LogOutputStr) {.gcsafe, raises: [Defect].} =
|
||||||
|
@ -133,95 +52,7 @@ proc mainProc() =
|
||||||
let logFile = fmt"app_{getTime().toUnix}.log"
|
let logFile = fmt"app_{getTime().toUnix}.log"
|
||||||
discard defaultChroniclesStream.outputs[1].open(LOGDIR & logFile, fmAppend)
|
discard defaultChroniclesStream.outputs[1].open(LOGDIR & logFile, fmAppend)
|
||||||
|
|
||||||
var wallet = wallet.newController(status, statusFoundation)
|
proc setupRemoteSignalsHandling() =
|
||||||
defer: wallet.delete()
|
|
||||||
singletonInstance.engine.setRootContextProperty("walletModel", wallet.variant)
|
|
||||||
|
|
||||||
var wallet2 = walletV2.newController(status, statusFoundation)
|
|
||||||
defer: wallet2.delete()
|
|
||||||
singletonInstance.engine.setRootContextProperty("walletV2Model", wallet2.variant)
|
|
||||||
|
|
||||||
var chat = chat.newController(status, statusFoundation, OPENURI)
|
|
||||||
defer: chat.delete()
|
|
||||||
singletonInstance.engine.setRootContextProperty("chatsModel", chat.variant)
|
|
||||||
|
|
||||||
var node = node.newController(statusFoundation, netAccMgr)
|
|
||||||
defer: node.delete()
|
|
||||||
singletonInstance.engine.setRootContextProperty("nodeModel", node.variant)
|
|
||||||
|
|
||||||
var utilsController = utilsView.newController(status, statusFoundation)
|
|
||||||
defer: utilsController.delete()
|
|
||||||
singletonInstance.engine.setRootContextProperty("utilsModel", utilsController.variant)
|
|
||||||
|
|
||||||
var keycard = keycard.newController(status)
|
|
||||||
defer: keycard.delete()
|
|
||||||
|
|
||||||
status.events.once("loginCompleted") do(a: Args):
|
|
||||||
var args = AccountArgs(a)
|
|
||||||
|
|
||||||
# At the end of refactoring all this will be in the AppController class.
|
|
||||||
status.startMessenger()
|
|
||||||
wallet.init()
|
|
||||||
wallet2.init()
|
|
||||||
chat.init()
|
|
||||||
utilsController.init()
|
|
||||||
node.init()
|
|
||||||
|
|
||||||
wallet.onLogin()
|
|
||||||
|
|
||||||
# this should be the last defer in the scope
|
|
||||||
defer:
|
|
||||||
info "Status app is shutting down..."
|
|
||||||
singletonInstance.delete()
|
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("keycardModel", keycard.variant)
|
|
||||||
singletonInstance.engine.setRootContextProperty("singleInstance", newQVariant(singleInstance))
|
|
||||||
|
|
||||||
let isExperimental = if getEnv("EXPERIMENTAL") == "1": "1" else: "0" # value explicity passed to avoid trusting input
|
|
||||||
let experimentalFlag = newQVariant(isExperimental)
|
|
||||||
singletonInstance.engine.setRootContextProperty("isExperimental", experimentalFlag)
|
|
||||||
|
|
||||||
# Initialize only controllers whose init functions
|
|
||||||
# do not need a running node
|
|
||||||
proc initControllers() =
|
|
||||||
keycard.init()
|
|
||||||
|
|
||||||
initControllers()
|
|
||||||
|
|
||||||
# Handle node.stopped signal when user has logged out
|
|
||||||
status.events.once("nodeStopped") do(a: Args):
|
|
||||||
# TODO: remove this once accounts are not tracked in the AccountsModel
|
|
||||||
status.reset()
|
|
||||||
|
|
||||||
# 1. Reset controller data
|
|
||||||
# TODO: implement all controller resets
|
|
||||||
# chat.reset()
|
|
||||||
# node.reset()
|
|
||||||
# wallet.reset()
|
|
||||||
# wallet2.reset()
|
|
||||||
# profile.reset()
|
|
||||||
|
|
||||||
# 2. Re-init controllers that don't require a running node
|
|
||||||
initControllers()
|
|
||||||
|
|
||||||
var signalsManagerQVariant = newQVariant(statusFoundation.signalsManager)
|
|
||||||
defer: signalsManagerQVariant.delete()
|
|
||||||
var mailserverControllerQVariant = newQVariant(statusFoundation.mailserverController)
|
|
||||||
defer: mailserverControllerQVariant.delete()
|
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("signals", signalsManagerQVariant)
|
|
||||||
singletonInstance.engine.setRootContextProperty("mailserver", mailserverControllerQVariant)
|
|
||||||
|
|
||||||
var prValue = newQVariant(if defined(production): true else: false)
|
|
||||||
singletonInstance.engine.setRootContextProperty("production", prValue)
|
|
||||||
|
|
||||||
# # We're applying default language before we load qml. Also we're aware that
|
|
||||||
# # switch language at runtime will have some impact to cpu usage.
|
|
||||||
# # https://doc.qt.io/archives/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-linguist-programmers.html
|
|
||||||
# changeLanguage("en")
|
|
||||||
|
|
||||||
appController.start()
|
|
||||||
|
|
||||||
# Please note that this must use the `cdecl` calling convention because
|
# Please note that this must use the `cdecl` calling convention because
|
||||||
# it will be passed as a regular C function to statusgo_backend. This means that
|
# it will be passed as a regular C function to statusgo_backend. This means that
|
||||||
# we cannot capture any local variables here (we must rely on globals)
|
# we cannot capture any local variables here (we must rely on globals)
|
||||||
|
@ -231,9 +62,84 @@ proc mainProc() =
|
||||||
|
|
||||||
status_go.setSignalEventCallback(callback)
|
status_go.setSignalEventCallback(callback)
|
||||||
|
|
||||||
# Qt main event loop is entered here
|
proc mainProc() =
|
||||||
# The termination of the loop will be performed when exit() or quit() is called
|
if defined(macosx) and defined(production):
|
||||||
info "Starting application..."
|
setCurrentDir(getAppDir())
|
||||||
|
|
||||||
|
ensureDirectories(DATADIR, TMPDIR, LOGDIR)
|
||||||
|
|
||||||
|
let isExperimental = isExperimental()
|
||||||
|
let resourcesPath = determineResourcePath()
|
||||||
|
let fleetsPath = determineFleetsPath()
|
||||||
|
let openUri = determineOpenUri()
|
||||||
|
let statusAppIconPath = determineStatusAppIconPath()
|
||||||
|
|
||||||
|
let fleetConfig = readFile(joinPath(getAppDir(), fleetsPath))
|
||||||
|
let statusFoundation = newStatusFoundation(fleetConfig)
|
||||||
|
let uiScaleFilePath = joinPath(DATADIR, "ui-scale")
|
||||||
|
enableHDPI(uiScaleFilePath)
|
||||||
|
initializeOpenGL()
|
||||||
|
|
||||||
|
let app = newQGuiApplication()
|
||||||
|
let appController = newAppController(statusFoundation)
|
||||||
|
let singleInstance = newSingleInstance($toMD5(DATADIR), openUri)
|
||||||
|
let networkAccessFactory = newQNetworkAccessManagerFactory(TMPDIR & "netcache")
|
||||||
|
|
||||||
|
let isProductionQVariant = newQVariant(if defined(production): true else: false)
|
||||||
|
let isExperimentalQVariant = newQVariant(isExperimental)
|
||||||
|
let signalsManagerQVariant = newQVariant(statusFoundation.signalsManager)
|
||||||
|
let mailserverControllerQVariant = newQVariant(statusFoundation.mailserverController)
|
||||||
|
|
||||||
|
QResource.registerResource(app.applicationDirPath & resourcesPath)
|
||||||
|
# Register events objects
|
||||||
|
let dockShowAppEvent = newStatusDockShowAppEventObject(singletonInstance.engine)
|
||||||
|
let osThemeEvent = newStatusOSThemeEventObject(singletonInstance.engine)
|
||||||
|
# We need this global variable in order to be able to access the application
|
||||||
|
# from the non-closure callback passed to `statusgo_backend.setSignalEventCallback`
|
||||||
|
signalsManagerQObjPointer = cast[pointer](statusFoundation.signalsManager.vptr)
|
||||||
|
setupRemoteSignalsHandling()
|
||||||
|
|
||||||
|
if not defined(macosx):
|
||||||
|
app.icon(app.applicationDirPath & statusAppIconPath)
|
||||||
|
|
||||||
|
prepareLogging()
|
||||||
|
|
||||||
|
singletonInstance.engine.addImportPath("qrc:/./StatusQ/src")
|
||||||
|
singletonInstance.engine.addImportPath("qrc:/./imports")
|
||||||
|
singletonInstance.engine.setNetworkAccessManagerFactory(networkAccessFactory)
|
||||||
|
singletonInstance.engine.setRootContextProperty("uiScaleFilePath", newQVariant(uiScaleFilePath))
|
||||||
|
singletonInstance.engine.setRootContextProperty("singleInstance", newQVariant(singleInstance))
|
||||||
|
singletonInstance.engine.setRootContextProperty("isExperimental", isExperimentalQVariant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("signals", signalsManagerQVariant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("mailserver", mailserverControllerQVariant)
|
||||||
|
singletonInstance.engine.setRootContextProperty("production", isProductionQVariant)
|
||||||
|
|
||||||
|
app.installEventFilter(dockShowAppEvent)
|
||||||
|
app.installEventFilter(osThemeEvent)
|
||||||
|
|
||||||
|
defer:
|
||||||
|
info "shutting down..."
|
||||||
|
signalsManagerQObjPointer = nil
|
||||||
|
isProductionQVariant.delete()
|
||||||
|
isExperimentalQVariant.delete()
|
||||||
|
signalsManagerQVariant.delete()
|
||||||
|
mailserverControllerQVariant.delete()
|
||||||
|
networkAccessFactory.delete()
|
||||||
|
dockShowAppEvent.delete()
|
||||||
|
osThemeEvent.delete()
|
||||||
|
statusFoundation.delete()
|
||||||
|
appController.delete()
|
||||||
|
singleInstance.delete()
|
||||||
|
app.delete()
|
||||||
|
|
||||||
|
# Checks below must be always after "defer", in case anything fails destructors will freed a memory.
|
||||||
|
if singleInstance.secondInstance():
|
||||||
|
info "Terminating the app as the second instance"
|
||||||
|
quit()
|
||||||
|
|
||||||
|
info "starting application controller..."
|
||||||
|
appController.start()
|
||||||
|
info "starting application..."
|
||||||
app.exec()
|
app.exec()
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
Loading…
Reference in New Issue