2020-07-20 14:28:32 +00:00
|
|
|
import NimQml, eventemitter, chronicles, os, strformat
|
2020-05-29 19:54:35 +00:00
|
|
|
|
2020-05-15 22:02:20 +00:00
|
|
|
import app/chat/core as chat
|
|
|
|
import app/wallet/core as wallet
|
|
|
|
import app/node/core as node
|
2020-09-15 19:47:13 +00:00
|
|
|
import app/utilsView/core as utilsView
|
2020-05-20 01:59:15 +00:00
|
|
|
import app/profile/core as profile
|
2020-05-20 17:36:44 +00:00
|
|
|
import app/onboarding/core as onboarding
|
2020-05-27 07:15:42 +00:00
|
|
|
import app/login/core as login
|
2020-09-02 13:30:40 +00:00
|
|
|
import status/signals/core as signals
|
2020-07-15 17:34:14 +00:00
|
|
|
import status/libstatus/types
|
|
|
|
import nim_status
|
2020-05-29 19:54:35 +00:00
|
|
|
import status/status as statuslib
|
2020-05-16 23:46:46 +00:00
|
|
|
|
2020-05-18 18:48:20 +00:00
|
|
|
var signalsQObjPointer: pointer
|
2020-05-11 17:31:07 +00:00
|
|
|
|
2020-05-21 19:07:55 +00:00
|
|
|
logScope:
|
|
|
|
topics = "main"
|
|
|
|
|
2020-05-06 17:40:00 +00:00
|
|
|
proc mainProc() =
|
2020-05-29 19:54:35 +00:00
|
|
|
let status = statuslib.newStatusInstance()
|
2020-06-04 07:38:24 +00:00
|
|
|
status.initNode()
|
2020-05-29 19:54:35 +00:00
|
|
|
|
2020-06-23 19:31:52 +00:00
|
|
|
enableHDPI()
|
2020-07-15 21:06:47 +00:00
|
|
|
initializeOpenGL()
|
2020-06-23 19:31:52 +00:00
|
|
|
|
2020-09-04 16:07:11 +00:00
|
|
|
let app = newQApplication("Status Desktop")
|
build: implement packaging steps for the Windows build
Implement a `pkg-windows` target that ultimately results in `Status.zip` being
written to `pkg/`.
Note: this commit does not introduce code signing for the Windows build since
that piece is still a work in progress.
`pkg-windows` creates a portable folder in `tmp/windows/dist` with the help of
[`windeployqt`][windeployqt], which copies the needed portions of Qt into the
folder.
Since DLL resolution is relatively inflexible, a launcher `Status.exe` is
created at the top-level of the folder; the launcher opens `bin/Status.exe`
while adding the portable folder's `bin/` to the `PATH`, allowing
`bin/Status.exe` to resolve the DLLs in that folder.
A few additional tools need to be installed (e.g. with [scoop][scoop]) and
availble in `PATH`:
* 7-zip
* dos2unix (provides unix2dos)
* findutils
* go
* rcedit
* wget
The above list builds on the tools list in PR #521, and the other requirements
and instructions in that PR's description still apply.
**Why not build an installer?**
When starting work on packaging for the Windows build, my initial plan was to
build an installer, and for that purpose I researched the [WiX Toolset][wix],
the [Qt Installer Framework][qtif], and some other options.
I found that building an installer is a bit complex. I then recalled, from
personal experience, that [Cmder][cmder]'s [Mini download][mini] is
installer-less. You simply unzip the download and place the `cmder_mini` folder
wherever you prefer. Such an approach was also recommended to me in one of the
Nim language's community chats.
In addition to being simpler, the installer-less approach also gives
installation of Status Desktop a lower profile than an installer-application
would since nothing is written to the Windows registry, added to the *Add or
remove programs* list, etc. I think that's a benefit given the privacy-security
focus of Status, but others may feel differently so please provide feedback on
this point!
[windeployqt]: https://doc.qt.io/qt-5/windows-deployment.html
[scoop]: https://scoop.sh/
[wix]: https://wixtoolset.org/
[qtif]: https://doc.qt.io/qtinstallerframework/index.html
[cmder]: https://cmder.net/
[mini]: https://github.com/cmderdev/cmder/releases/download/v1.3.15/cmder_mini.zip
2020-07-15 22:45:56 +00:00
|
|
|
let resources =
|
|
|
|
if defined(windows) and getEnv("NIM_STATUS_CLIENT_DEV").string == "":
|
|
|
|
"/../resources/resources.rcc"
|
|
|
|
else:
|
|
|
|
"/../resources.rcc"
|
|
|
|
QResource.registerResource(app.applicationDirPath & resources)
|
|
|
|
|
2020-09-17 20:11:31 +00:00
|
|
|
let statusAppIcon =
|
|
|
|
if defined(macosx):
|
|
|
|
if getEnv("NIM_STATUS_CLIENT_DEV").string == "":
|
|
|
|
"/../Resources/status-icon.icns"
|
build: implement packaging steps for the Windows build
Implement a `pkg-windows` target that ultimately results in `Status.zip` being
written to `pkg/`.
Note: this commit does not introduce code signing for the Windows build since
that piece is still a work in progress.
`pkg-windows` creates a portable folder in `tmp/windows/dist` with the help of
[`windeployqt`][windeployqt], which copies the needed portions of Qt into the
folder.
Since DLL resolution is relatively inflexible, a launcher `Status.exe` is
created at the top-level of the folder; the launcher opens `bin/Status.exe`
while adding the portable folder's `bin/` to the `PATH`, allowing
`bin/Status.exe` to resolve the DLLs in that folder.
A few additional tools need to be installed (e.g. with [scoop][scoop]) and
availble in `PATH`:
* 7-zip
* dos2unix (provides unix2dos)
* findutils
* go
* rcedit
* wget
The above list builds on the tools list in PR #521, and the other requirements
and instructions in that PR's description still apply.
**Why not build an installer?**
When starting work on packaging for the Windows build, my initial plan was to
build an installer, and for that purpose I researched the [WiX Toolset][wix],
the [Qt Installer Framework][qtif], and some other options.
I found that building an installer is a bit complex. I then recalled, from
personal experience, that [Cmder][cmder]'s [Mini download][mini] is
installer-less. You simply unzip the download and place the `cmder_mini` folder
wherever you prefer. Such an approach was also recommended to me in one of the
Nim language's community chats.
In addition to being simpler, the installer-less approach also gives
installation of Status Desktop a lower profile than an installer-application
would since nothing is written to the Windows registry, added to the *Add or
remove programs* list, etc. I think that's a benefit given the privacy-security
focus of Status, but others may feel differently so please provide feedback on
this point!
[windeployqt]: https://doc.qt.io/qt-5/windows-deployment.html
[scoop]: https://scoop.sh/
[wix]: https://wixtoolset.org/
[qtif]: https://doc.qt.io/qtinstallerframework/index.html
[cmder]: https://cmder.net/
[mini]: https://github.com/cmderdev/cmder/releases/download/v1.3.15/cmder_mini.zip
2020-07-15 22:45:56 +00:00
|
|
|
else:
|
2020-09-17 20:11:31 +00:00
|
|
|
"/../status-icon.icns"
|
|
|
|
elif defined(windows) and getEnv("NIM_STATUS_CLIENT_DEV").string == "":
|
|
|
|
"/../resources/status.svg"
|
|
|
|
else:
|
|
|
|
"/../status.svg"
|
|
|
|
app.icon(app.applicationDirPath & statusAppIcon)
|
2020-06-23 22:54:21 +00:00
|
|
|
|
2020-08-10 20:19:15 +00:00
|
|
|
var i18nPath = ""
|
|
|
|
if (getEnv("NIM_STATUS_CLIENT_DEV").string != ""):
|
|
|
|
i18nPath = joinPath(getAppDir(), "../ui/i18n")
|
|
|
|
elif (defined(windows)):
|
|
|
|
i18nPath = joinPath(getAppDir(), "../resources/i18n")
|
|
|
|
elif (defined(macosx)):
|
|
|
|
i18nPath = joinPath(getAppDir(), "../i18n")
|
|
|
|
elif (defined(linux)):
|
|
|
|
i18nPath = joinPath(getAppDir(), "../i18n")
|
|
|
|
|
|
|
|
|
2020-05-18 20:32:53 +00:00
|
|
|
let engine = newQQmlApplicationEngine()
|
2020-09-02 13:30:40 +00:00
|
|
|
let signalController = signals.newController(status)
|
2020-05-18 18:48:20 +00:00
|
|
|
|
|
|
|
# We need this global variable in order to be able to access the application
|
|
|
|
# from the non-closure callback passed to `libstatus.setSignalEventCallback`
|
|
|
|
signalsQObjPointer = cast[pointer](signalController.vptr)
|
|
|
|
|
2020-05-29 19:54:35 +00:00
|
|
|
var wallet = wallet.newController(status)
|
2020-06-02 20:10:48 +00:00
|
|
|
engine.setRootContextProperty("walletModel", wallet.variant)
|
2020-05-13 19:14:35 +00:00
|
|
|
|
2020-05-29 19:54:35 +00:00
|
|
|
var chat = chat.newController(status)
|
2020-05-15 21:40:05 +00:00
|
|
|
engine.setRootContextProperty("chatsModel", chat.variant)
|
2020-05-11 21:24:08 +00:00
|
|
|
|
2020-05-29 19:54:35 +00:00
|
|
|
var node = node.newController(status)
|
2020-05-15 21:40:05 +00:00
|
|
|
engine.setRootContextProperty("nodeModel", node.variant)
|
2020-05-20 17:11:30 +00:00
|
|
|
|
2020-09-15 19:47:13 +00:00
|
|
|
var utilsController = utilsView.newController(status)
|
|
|
|
engine.setRootContextProperty("utilsModel", utilsController.variant)
|
|
|
|
|
2020-07-20 14:28:32 +00:00
|
|
|
proc changeLanguage(locale: string) =
|
2020-08-10 20:19:15 +00:00
|
|
|
engine.setTranslationPackage(joinPath(i18nPath, fmt"qml_{locale}.qm"))
|
2020-07-20 14:28:32 +00:00
|
|
|
|
|
|
|
var profile = profile.newController(status, changeLanguage)
|
2020-05-20 01:59:15 +00:00
|
|
|
engine.setRootContextProperty("profileModel", profile.variant)
|
|
|
|
|
2020-08-25 20:19:46 +00:00
|
|
|
var login = login.newController(status)
|
|
|
|
var onboarding = onboarding.newController(status)
|
|
|
|
|
2020-06-17 16:13:13 +00:00
|
|
|
status.events.once("login") do(a: Args):
|
2020-05-22 12:35:40 +00:00
|
|
|
var args = AccountArgs(a)
|
2020-08-25 20:19:46 +00:00
|
|
|
# Delete login and onboarding from memory to remove any mnemonic that would have been saved in the accounts list
|
|
|
|
login.delete()
|
|
|
|
onboarding.delete()
|
|
|
|
|
2020-05-29 19:54:35 +00:00
|
|
|
status.startMessenger()
|
2020-05-27 07:15:42 +00:00
|
|
|
profile.init(args.account)
|
2020-06-25 13:26:58 +00:00
|
|
|
wallet.init()
|
|
|
|
chat.init()
|
2020-09-15 19:47:13 +00:00
|
|
|
utilsController.init()
|
build: implement packaging steps for the Windows build
Implement a `pkg-windows` target that ultimately results in `Status.zip` being
written to `pkg/`.
Note: this commit does not introduce code signing for the Windows build since
that piece is still a work in progress.
`pkg-windows` creates a portable folder in `tmp/windows/dist` with the help of
[`windeployqt`][windeployqt], which copies the needed portions of Qt into the
folder.
Since DLL resolution is relatively inflexible, a launcher `Status.exe` is
created at the top-level of the folder; the launcher opens `bin/Status.exe`
while adding the portable folder's `bin/` to the `PATH`, allowing
`bin/Status.exe` to resolve the DLLs in that folder.
A few additional tools need to be installed (e.g. with [scoop][scoop]) and
availble in `PATH`:
* 7-zip
* dos2unix (provides unix2dos)
* findutils
* go
* rcedit
* wget
The above list builds on the tools list in PR #521, and the other requirements
and instructions in that PR's description still apply.
**Why not build an installer?**
When starting work on packaging for the Windows build, my initial plan was to
build an installer, and for that purpose I researched the [WiX Toolset][wix],
the [Qt Installer Framework][qtif], and some other options.
I found that building an installer is a bit complex. I then recalled, from
personal experience, that [Cmder][cmder]'s [Mini download][mini] is
installer-less. You simply unzip the download and place the `cmder_mini` folder
wherever you prefer. Such an approach was also recommended to me in one of the
Nim language's community chats.
In addition to being simpler, the installer-less approach also gives
installation of Status Desktop a lower profile than an installer-application
would since nothing is written to the Windows registry, added to the *Add or
remove programs* list, etc. I think that's a benefit given the privacy-security
focus of Status, but others may feel differently so please provide feedback on
this point!
[windeployqt]: https://doc.qt.io/qt-5/windows-deployment.html
[scoop]: https://scoop.sh/
[wix]: https://wixtoolset.org/
[qtif]: https://doc.qt.io/qtinstallerframework/index.html
[cmder]: https://cmder.net/
[mini]: https://github.com/cmderdev/cmder/releases/download/v1.3.15/cmder_mini.zip
2020-07-15 22:45:56 +00:00
|
|
|
|
2020-09-11 17:23:57 +00:00
|
|
|
wallet.checkPendingTransactions()
|
|
|
|
wallet.start()
|
|
|
|
|
2020-05-28 04:06:57 +00:00
|
|
|
engine.setRootContextProperty("loginModel", login.variant)
|
|
|
|
engine.setRootContextProperty("onboardingModel", onboarding.variant)
|
2020-05-21 20:52:00 +00:00
|
|
|
|
2020-06-26 14:08:08 +00:00
|
|
|
let isExperimental = if getEnv("EXPERIMENTAL") == "1": "1" else: "0" # value explicity passed to avoid trusting input
|
|
|
|
let experimentalFlag = newQVariant(isExperimental)
|
|
|
|
engine.setRootContextProperty("isExperimental", experimentalFlag)
|
|
|
|
|
2020-06-18 21:56:04 +00:00
|
|
|
defer:
|
|
|
|
error "TODO: if user is logged in, logout"
|
|
|
|
engine.delete()
|
|
|
|
app.delete()
|
|
|
|
signalController.delete()
|
|
|
|
login.delete()
|
|
|
|
onboarding.delete()
|
|
|
|
wallet.delete()
|
|
|
|
chat.delete()
|
|
|
|
profile.delete()
|
2020-09-15 19:47:13 +00:00
|
|
|
utilsController.delete()
|
2020-06-18 21:56:04 +00:00
|
|
|
|
|
|
|
|
2020-06-04 07:38:24 +00:00
|
|
|
# Initialize only controllers whose init functions
|
|
|
|
# do not need a running node
|
|
|
|
proc initControllers() =
|
|
|
|
node.init()
|
|
|
|
login.init()
|
|
|
|
onboarding.init()
|
build: implement packaging steps for the Windows build
Implement a `pkg-windows` target that ultimately results in `Status.zip` being
written to `pkg/`.
Note: this commit does not introduce code signing for the Windows build since
that piece is still a work in progress.
`pkg-windows` creates a portable folder in `tmp/windows/dist` with the help of
[`windeployqt`][windeployqt], which copies the needed portions of Qt into the
folder.
Since DLL resolution is relatively inflexible, a launcher `Status.exe` is
created at the top-level of the folder; the launcher opens `bin/Status.exe`
while adding the portable folder's `bin/` to the `PATH`, allowing
`bin/Status.exe` to resolve the DLLs in that folder.
A few additional tools need to be installed (e.g. with [scoop][scoop]) and
availble in `PATH`:
* 7-zip
* dos2unix (provides unix2dos)
* findutils
* go
* rcedit
* wget
The above list builds on the tools list in PR #521, and the other requirements
and instructions in that PR's description still apply.
**Why not build an installer?**
When starting work on packaging for the Windows build, my initial plan was to
build an installer, and for that purpose I researched the [WiX Toolset][wix],
the [Qt Installer Framework][qtif], and some other options.
I found that building an installer is a bit complex. I then recalled, from
personal experience, that [Cmder][cmder]'s [Mini download][mini] is
installer-less. You simply unzip the download and place the `cmder_mini` folder
wherever you prefer. Such an approach was also recommended to me in one of the
Nim language's community chats.
In addition to being simpler, the installer-less approach also gives
installation of Status Desktop a lower profile than an installer-application
would since nothing is written to the Windows registry, added to the *Add or
remove programs* list, etc. I think that's a benefit given the privacy-security
focus of Status, but others may feel differently so please provide feedback on
this point!
[windeployqt]: https://doc.qt.io/qt-5/windows-deployment.html
[scoop]: https://scoop.sh/
[wix]: https://wixtoolset.org/
[qtif]: https://doc.qt.io/qtinstallerframework/index.html
[cmder]: https://cmder.net/
[mini]: https://github.com/cmderdev/cmder/releases/download/v1.3.15/cmder_mini.zip
2020-07-15 22:45:56 +00:00
|
|
|
|
2020-06-04 07:38:24 +00:00
|
|
|
initControllers()
|
|
|
|
|
|
|
|
# Handle node.stopped signal when user has logged out
|
2020-06-17 16:13:13 +00:00
|
|
|
status.events.once("nodeStopped") do(a: Args):
|
2020-06-04 07:38:24 +00:00
|
|
|
# TODO: remove this once accounts are not tracked in the AccountsModel
|
|
|
|
status.reset()
|
|
|
|
|
|
|
|
# 1. Reset controller data
|
|
|
|
login.reset()
|
|
|
|
onboarding.reset()
|
|
|
|
# TODO: implement all controller resets
|
|
|
|
# chat.reset()
|
|
|
|
# node.reset()
|
|
|
|
# wallet.reset()
|
|
|
|
# profile.reset()
|
build: implement packaging steps for the Windows build
Implement a `pkg-windows` target that ultimately results in `Status.zip` being
written to `pkg/`.
Note: this commit does not introduce code signing for the Windows build since
that piece is still a work in progress.
`pkg-windows` creates a portable folder in `tmp/windows/dist` with the help of
[`windeployqt`][windeployqt], which copies the needed portions of Qt into the
folder.
Since DLL resolution is relatively inflexible, a launcher `Status.exe` is
created at the top-level of the folder; the launcher opens `bin/Status.exe`
while adding the portable folder's `bin/` to the `PATH`, allowing
`bin/Status.exe` to resolve the DLLs in that folder.
A few additional tools need to be installed (e.g. with [scoop][scoop]) and
availble in `PATH`:
* 7-zip
* dos2unix (provides unix2dos)
* findutils
* go
* rcedit
* wget
The above list builds on the tools list in PR #521, and the other requirements
and instructions in that PR's description still apply.
**Why not build an installer?**
When starting work on packaging for the Windows build, my initial plan was to
build an installer, and for that purpose I researched the [WiX Toolset][wix],
the [Qt Installer Framework][qtif], and some other options.
I found that building an installer is a bit complex. I then recalled, from
personal experience, that [Cmder][cmder]'s [Mini download][mini] is
installer-less. You simply unzip the download and place the `cmder_mini` folder
wherever you prefer. Such an approach was also recommended to me in one of the
Nim language's community chats.
In addition to being simpler, the installer-less approach also gives
installation of Status Desktop a lower profile than an installer-application
would since nothing is written to the Windows registry, added to the *Add or
remove programs* list, etc. I think that's a benefit given the privacy-security
focus of Status, but others may feel differently so please provide feedback on
this point!
[windeployqt]: https://doc.qt.io/qt-5/windows-deployment.html
[scoop]: https://scoop.sh/
[wix]: https://wixtoolset.org/
[qtif]: https://doc.qt.io/qtinstallerframework/index.html
[cmder]: https://cmder.net/
[mini]: https://github.com/cmderdev/cmder/releases/download/v1.3.15/cmder_mini.zip
2020-07-15 22:45:56 +00:00
|
|
|
|
2020-06-04 07:38:24 +00:00
|
|
|
# 2. Re-init controllers that don't require a running node
|
|
|
|
initControllers()
|
|
|
|
|
2020-05-18 15:07:30 +00:00
|
|
|
engine.setRootContextProperty("signals", signalController.variant)
|
|
|
|
|
2020-06-30 21:35:24 +00:00
|
|
|
engine.load(newQUrl("qrc:///main.qml"))
|
2020-05-18 18:48:20 +00:00
|
|
|
|
|
|
|
# Please note that this must use the `cdecl` calling convention because
|
|
|
|
# it will be passed as a regular C function to libstatus. This means that
|
|
|
|
# we cannot capture any local variables here (we must rely on globals)
|
|
|
|
var callback: SignalCallback = proc(p0: cstring) {.cdecl.} =
|
2020-06-04 21:18:11 +00:00
|
|
|
setupForeignThreadGc()
|
2020-05-18 15:07:30 +00:00
|
|
|
signal_handler(signalsQObjPointer, p0, "receiveSignal")
|
2020-06-04 21:18:11 +00:00
|
|
|
tearDownForeignThreadGc()
|
2020-05-16 23:46:46 +00:00
|
|
|
|
2020-07-15 17:34:14 +00:00
|
|
|
nim_status.setSignalEventCallback(callback)
|
2020-05-15 21:10:00 +00:00
|
|
|
|
2020-05-10 23:24:06 +00:00
|
|
|
# Qt main event loop is entered here
|
|
|
|
# The termination of the loop will be performed when exit() or quit() is called
|
2020-05-21 19:07:55 +00:00
|
|
|
info "Starting application..."
|
2020-05-06 17:40:00 +00:00
|
|
|
app.exec()
|
|
|
|
|
|
|
|
when isMainModule:
|
|
|
|
mainProc()
|
|
|
|
GC_fullcollect()
|