feat: Onboarding carousel

Onboarding carousel completed

Redo folder restructuring

NOTES:
1. nim_status_client binary is output to `./bin/nim_status_client`, so you'll need to update your workflow to run this file. README has been updated to reflect this. Also, if you're running VSCode, instructions for code reload were added.
2. All `ui` files now live in `ui/`
3. All lib files (ie `libstatus`) now live in `lib/`
4. Removed the Qt Creater user project file as this is unique to each user
5. Moved the project file to `ui/`, so just open up the `ui` folder in Qt creator and it should locate the project file
6. `-d:release` removed from compilation as it wasn't needed
7. Broke up main.qml in to the main app and onboarding components, however this should be broken down further into more reusable components
8. Click "Get started" to show chat

Format some files using nimpretty
This commit is contained in:
emizzle 2020-05-12 07:24:08 +10:00 committed by Jonathan Rainville
parent 8f09f08748
commit 4769f578a6
40 changed files with 1041 additions and 718 deletions

3
.gitignore vendored
View File

@ -6,3 +6,6 @@ data/
noBackup/
.idea
*.pro.user
*.pro.autosave
.vscode
bin/

View File

@ -1,7 +1,7 @@
SHELL := bash
build:
nim c -d:release -L:libstatus.a -L:-lm --outdir:. src/nim_status_client.nim
nim c -L:lib/libstatus.a -L:-lm --outdir:./bin src/nim_status_client.nim
build-osx:
nim c -d:release -L:libstatus.dylib -L:-lm -L:"-framework Foundation -framework Security -framework IOKit -framework CoreServices" --outdir:. src/nim_status_client.nim
nim c -L:lib/libstatus.dylib -L:-lm -L:"-framework Foundation -framework Security -framework IOKit -framework CoreServices" --outdir:./bin src/nim_status_client.nim

View File

@ -25,6 +25,7 @@ export PATH=$PATH:/path/to/Qt/5.14.2/clang_64/bin
### 3. Clone and build DOtherside
For Linux:
```
sudo apt-get install build-essential libgl1-mesa-dev
sudo apt-get install doxygen
@ -70,5 +71,69 @@ make build-osx
### 8. Run the app
```
./nim_status_client
./bin/nim_status_client
```
### 9. "Cold" reload using VSCode
We can setup a "cold" reload, whereby the app will be rebuilt and restarted when changes in the source are saved. This will not save state, as the app will be restarted, but it will save us some time from manually restarting the app. We can handily force an app rebuild/relaunch with the shortcut `Cmd+Shift+b` (execute the default build task, which we'll setup below).
To enable a meagre app reload during development, first creates a task in `.vscode/tasks.json`. This task sets up the default build task for the workspace, and depends on the task that compiles our nim:
```json
({
"label": "Build Nim Status Client",
"type": "shell",
"command": "nim",
"args": [
"c",
"-L:lib/libstatus.dylib",
"-L:-lm",
"-L:\"-framework Foundation -framework Security -framework IOKit -framework CoreServices\"",
"--outdir:./bin",
"src/nim_status_client.nim"
],
"options": {
"cwd": "${workspaceRoot}"
}
},
{
"label": "Run nim_status_client",
"type": "shell",
"command": "bash",
"args": ["./run.sh"],
"options": {
"cwd": "${workspaceRoot}/.vscode"
},
"dependsOn": ["Build Nim Status Client"],
"group": {
"kind": "build",
"isDefault": true
}
})
```
Next, add a `.vscode/run.sh` file, changing the `DOtherSide` lib path to be specific to your environment:
```bash
export LD_LIBRARY_PATH="/Users/emizzle/repos/github.com/filcuc/DOtherSide/build/lib"
../bin/nim_status_client
```
# Auto build on save (for the "cold" reload effect)
Finally, to get trigger this default build task when our files our saved, we need to enable a task to be run while `.nim` files are saved, and when `.qml` files are saved.
### Build on save
To build on save of our source files, first install the "Trigger Task on Save" VS Code extension to detect changes to our changable files, which will trigger a build/run. Once installed, update `settings.json` like so:
```json
"files.autoSave": "afterDelay",
"triggerTaskOnSave.tasks": {
"Run nim_status_client": ["ui/**/*", "src/*.nim"]
},
"triggerTaskOnSave.restart": true,
"triggerTaskOnSave.showStatusBarToggle": true
```

602
main.qml
View File

@ -1,602 +0,0 @@
import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import Qt.labs.platform 1.1
import "./imports"
ApplicationWindow {
id: applicationWindow
width: 1024
height: 768
title: "Nim Status Client"
visible: true
font.family: "Inter"
SystemTrayIcon {
visible: true
icon.source: "status-logo.png"
onActivated: {
applicationWindow.show()
applicationWindow.raise()
applicationWindow.requestActivate()
}
}
RowLayout {
id: rowLayout
width: parent.width
height: parent.height
anchors.fill: parent
// spacing: 50
TabBar {
id: tabBar
y: 0
width: 50
height: width *2 + spacing
Layout.preferredHeight: 0
currentIndex: 0
topPadding: 57
rightPadding: 19
leftPadding: 19
transformOrigin: Item.Top
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true
anchors.top: parent.top
spacing: 5
Layout.fillWidth: true
Layout.minimumWidth: 80
Layout.preferredWidth: 80
Layout.maximumWidth: 80
Layout.minimumHeight: 0
background: Rectangle {
color: "#00000000"
border.color: Theme.grey
}
TabButton {
id: chatBtn
x: 0
width: 40
height: 40
text: ""
padding: 0
transformOrigin: Item.Center
anchors.horizontalCenter: parent.horizontalCenter
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/messageActive.svg" : "img/message.svg"
}
}
TabButton {
id: walletBtn
width: 40
height: 40
text: ""
anchors.topMargin: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: chatBtn.top
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image1
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/walletActive.svg" : "img/wallet.svg"
}
}
TabButton {
id: browserBtn
width: 40
height: 40
text: ""
anchors.topMargin: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: walletBtn.top
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image2
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/compassActive.svg" : "img/compass.svg"
}
}
TabButton {
id: profileBtn
width: 40
height: 40
text: ""
anchors.topMargin: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: browserBtn.top
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image3
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/profileActive.svg" : "img/profile.svg"
}
}
}
StackLayout {
width: parent.width
Layout.fillWidth: true
currentIndex: tabBar.currentIndex
SplitView {
id: splitView
x: 9
y: 0
Layout.fillHeight: true
// anchors.fill: parent
// width: parent.width
Layout.leftMargin: 0
Layout.fillWidth: true
Layout.minimumWidth: 100
Layout.preferredWidth: 200
// Layout.preferredHeight: 100
Item {
id: element1
width: 300
height: parent.height
Layout.minimumWidth: 200
ColumnLayout {
anchors.rightMargin: 0
anchors.fill: parent
Item {
Layout.preferredHeight: 100
Layout.fillHeight: false
Layout.fillWidth: true
Text {
id: element
x: 772
text: qsTr("Chat")
anchors.top: parent.top
anchors.topMargin: 17
font.bold: true
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 17
}
Rectangle {
id: searchBox
height: 36
color: Theme.grey
anchors.top: parent.top
anchors.topMargin: 59
radius: 8
anchors.right: parent.right
anchors.rightMargin: 65
anchors.left: parent.left
anchors.leftMargin: Theme.padding
TextField {
id: searchText
placeholderText: qsTr("Search")
anchors.left: parent.left
anchors.leftMargin: 32
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 12
background: {
}
}
Image {
id: image4
anchors.left: parent.left
anchors.leftMargin: Theme.smallPadding
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: "img/search.svg"
}
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked : {
searchText.forceActiveFocus(Qt.MouseFocusReason)
}
}
}
Rectangle {
id: addChat
width: 36
height: 36
color: Theme.blue
radius: 50
anchors.right: parent.right
anchors.rightMargin: Theme.padding
anchors.top: parent.top
anchors.topMargin: 59
Text {
id: element3
color: "#ffffff"
text: qsTr("+")
anchors.verticalCenterOffset: -1
anchors.horizontalCenterOffset: 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
lineHeight: 1
fontSizeMode: Text.FixedSize
font.bold: true
font.pixelSize: 28
}
}
}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
Component {
id: chatViewDelegate
Rectangle {
id: wrapper
height: 64
color: ListView.isCurrentItem ? Theme.lightBlue : Theme.transparent
anchors.right: parent.right
anchors.rightMargin: Theme.padding
anchors.top: applicationWindow.top
anchors.topMargin: 0
anchors.left: parent.left
anchors.leftMargin: Theme.padding
radius: 8
MouseArea {
anchors.fill: parent
onClicked: listView.currentIndex = index
}
Rectangle {
id: contactImage
width: 40
color: Theme.darkGrey
anchors.left: parent.left
anchors.leftMargin: Theme.padding
anchors.top: parent.top
anchors.topMargin: 12
anchors.bottom: parent.bottom
anchors.bottomMargin: 12
radius: 50
}
Text {
id: contactInfo
text: "Name:" + name
font.weight: Font.Medium
font.pixelSize: 15
anchors.left: contactImage.right
anchors.leftMargin: Theme.padding
anchors.top: parent.top
anchors.topMargin: Theme.smallPadding
color: "black"
}
Text {
id: lastChatMessage
text: "Chatting blah blah..."
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.smallPadding
font.pixelSize: 15
anchors.left: contactImage.right
anchors.leftMargin: Theme.padding
color: Theme.darkGrey
}
Text {
id: contactTime
text: "12:22 AM"
anchors.right: parent.right
anchors.rightMargin: Theme.padding
anchors.top: parent.top
anchors.topMargin: Theme.smallPadding
font.pixelSize: 11
color: Theme.darkGrey
}
Rectangle {
id: contactNumberChatsCircle
width: 22
height: 22
radius: 50
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.smallPadding
anchors.right: parent.right
anchors.rightMargin: Theme.padding
color: Theme.blue
Text {
id: contactNumberChats
text: qsTr("1")
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "white"
}
}
}
}
ListView {
id: listView
anchors.topMargin: 24
anchors.fill: parent
model: chatsModel
delegate: chatViewDelegate
}
}
}
}
Item {
width: parent.width/2
height: parent.height
ColumnLayout {
anchors.rightMargin: 0
anchors.fill: parent
RowLayout {
id: chatContainer
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Rectangle {
id: chatBox
height: 140
color: "#00000000"
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillWidth: true
border.color: "#00000000"
Image {
id: chatImage
width: 30
height: 30
anchors.left: parent.left
anchors.leftMargin: 16
anchors.top: parent.top
anchors.topMargin: 16
fillMode: Image.PreserveAspectFit
source: "img/placeholder-profile.png"
}
TextEdit {
id: chatName
text: qsTr("Slushy Welltodo Woodborer")
anchors.top: parent.top
anchors.topMargin: 22
anchors.left: chatImage.right
anchors.leftMargin: 16
font.bold: true
font.pixelSize: 14
readOnly: true
selectByMouse: true
}
TextEdit {
id: chatText
text: qsTr("Im generally against putting too many rules on social interaction because it makes interaction anything but social, but technical specifics on how to get on board or participate in a team are I think generally useful, especially if they prevent maintainers from pasting the same response to every PR / issue.")
font.family: "Inter"
wrapMode: Text.WordWrap
anchors.right: parent.right
anchors.rightMargin: 60
anchors.left: chatName.left
anchors.leftMargin: 0
anchors.top: chatName.bottom
anchors.topMargin: 16
font.pixelSize: 14
readOnly: true
selectByMouse: true
}
TextEdit {
id: chatTime
color: Theme.darkGrey
font.family: "Inter"
text: qsTr("7:30 AM")
anchors.bottom: parent.bottom
anchors.bottomMargin: 16
anchors.right: parent.right
anchors.rightMargin: 16
font.pixelSize: 10
readOnly: true
selectByMouse: true
}
}
}
RowLayout {
id: separator
height: 16
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
anchors.top: chatContainer.bottom
anchors.topMargin: Theme.padding
Item {
id: separatorContent
width: 200
height: 16
Layout.fillHeight: false
Layout.fillWidth: true
Rectangle {
id: lineSeparator1
height: 1
color: "#00000000"
border.color: "#eef2f5"
anchors.top: parent.top
anchors.topMargin: 8
anchors.right: separatorText.left
anchors.rightMargin: 14
anchors.left: parent.left
anchors.leftMargin: 16
}
Text {
id: separatorText
color: Theme.darkGrey
text: qsTr("Yesterday")
font.pixelSize: 12
anchors.centerIn: parent
}
Rectangle {
id: lineSeparator2
height: 1
color: "#00000000"
anchors.right: parent.right
anchors.rightMargin: 16
anchors.left: separatorText.right
border.color: "#eef2f5"
anchors.top: parent.top
anchors.leftMargin: 14
anchors.topMargin: 8
}
}
}
RowLayout {
id: resultContainer
Layout.fillHeight: true
TextArea { id: callResult; Layout.fillWidth: true; text: logic.callResult; readOnly: true }
}
RowLayout {
id: chatInputContainer
height: 70
Layout.bottomMargin: 20
Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
transformOrigin: Item.Bottom
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
Item {
id: element2
width: 200
height: 70
Layout.fillWidth: true
Rectangle {
id: rectangle
color: "#00000000"
border.color: Theme.grey
anchors.fill: parent
Button {
id: chatSendBtn
x: 100
width: 30
height: 30
text: "\u2191"
font.bold: true
font.pointSize: 12
anchors.top: parent.top
anchors.topMargin: 20
anchors.right: parent.right
anchors.rightMargin: 16
onClicked: logic.onSend(txtData.text)
enabled: txtData.text !== ""
background: Rectangle {
color: parent.enabled ? Theme.blue : Theme.grey
radius: 50
}
}
TextField {
id: txtData
text: ""
leftPadding: 0
padding: 0
font.pixelSize: 14
placeholderText: qsTr("Type a message...")
anchors.right: chatSendBtn.left
anchors.rightMargin: 16
anchors.top: parent.top
anchors.topMargin: 24
anchors.left: parent.left
anchors.leftMargin: 24
background: {}
}
MouseArea {
id: mouseArea1
anchors.rightMargin: 50
anchors.fill: parent
onClicked : {
txtData.forceActiveFocus(Qt.MouseFocusReason)
}
}
}
}
}
}
}
}
ColumnLayout {
anchors.fill: parent
RowLayout {
Layout.fillHeight: true
TextArea { id: accountResult; Layout.fillWidth: true; text: logic.accountResult; readOnly: true }
}
}
Item {
}
}
}
}
/*##^##
Designer {
D{i:0;formeditorZoom:0.8999999761581421}D{i:61;anchors_height:100;anchors_width:100}
}
##^##*/

View File

@ -3,17 +3,15 @@ import applicationView
import chats
import state
import status
import libstatus
import json
proc mainProc() =
# From QT docs:
# For any GUI application using Qt, there is precisely one QApplication object,
# no matter whether the application has 0, 1, 2 or more windows at any given time.
# For non-QWidget based Qt applications, use QGuiApplication instead, as it does
# For any GUI application using Qt, there is precisely one QApplication object,
# no matter whether the application has 0, 1, 2 or more windows at any given time.
# For non-QWidget based Qt applications, use QGuiApplication instead, as it does
# not depend on the QtWidgets library. Use QCoreApplication for non GUI apps
var app = newQApplication()
defer: app.delete() # Defer will run this just before mainProc() function ends
defer: app.delete() # Defer will run this just before mainProc() function ends
var chatsModel = newChatsModel();
defer: chatsModel.delete
@ -32,7 +30,7 @@ proc mainProc() =
let logic = newApplicationView(app, status.callPrivateRPC)
defer: logic.delete
let logicVariant = newQVariant(logic)
defer: logicVariant.delete
@ -54,8 +52,8 @@ proc mainProc() =
engine.setRootContextProperty("logic", logicVariant)
engine.setRootContextProperty("chatsModel", chatsVariant)
engine.load("main.qml")
engine.load("../ui/main.qml")
# Qt main event loop is entered here
# The termination of the loop will be performed when exit() or quit() is called
app.exec()

View File

@ -39,50 +39,50 @@ proc subscribeToTest*() =
var result = ""
var payload = %* {
"jsonrpc": "2.0",
"jsonrpc": "2.0",
"id": 3,
"method": "wakuext_startMessenger",
"method": "wakuext_startMessenger",
"params": []
}
result = $libstatus.callPrivateRPC($payload)
payload = %* {
"jsonrpc": "2.0",
"jsonrpc": "2.0",
"id": 3,
"method": "wakuext_loadFilters",
"method": "wakuext_loadFilters",
"params": [
[{
"ChatID":"test",
"OneToOne":false
"ChatID": "test",
"OneToOne": false
}]
]
}
result = $libstatus.callPrivateRPC($payload)
payload = %* {
"jsonrpc": "2.0",
"jsonrpc": "2.0",
"id": 4,
"method": "wakuext_saveChat",
"method": "wakuext_saveChat",
"params": [
{
"lastClockValue":0,
"color":"#51d0f0",
"name":"test",
"lastMessage":nil,
"active":true,
"id":"test",
"unviewedMessagesCount":0,
"chatType":2,
"timestamp":1588940692659
"lastClockValue": 0,
"color": "#51d0f0",
"name": "test",
"lastMessage": nil,
"active": true,
"id": "test",
"unviewedMessagesCount": 0,
"chatType": 2,
"timestamp": 1588940692659
}
]
}
result = $libstatus.callPrivateRPC($payload)
payload = %* {
"jsonrpc": "2.0",
"jsonrpc": "2.0",
"id": 3,
"method": "wakuext_chatMessages",
"method": "wakuext_chatMessages",
"params": [
"test", nil, 20
]
@ -100,17 +100,18 @@ proc setupNewAccount*() =
# 1
result = $libstatus.initKeystore(keystoredir);
# 2
# 2
result = $libstatus.openAccounts(datadir);
# 3
let multiAccountConfig = %* {
"n": 5,
"mnemonicPhraseLength": 12,
"bip39Passphrase": "",
"bip39Passphrase": "",
"paths": ["m/43'/60'/1581'/0'/0", "m/44'/60'/0'/0/0"]
}
result = $libstatus.multiAccountGenerateAndDeriveAddresses($multiAccountConfig);
result = $libstatus.multiAccountGenerateAndDeriveAddresses(
$multiAccountConfig);
let generatedAddresses = result.parseJson
let account0 = generatedAddresses[0]
@ -118,7 +119,8 @@ proc setupNewAccount*() =
let password = "0x2cd9bf92c5e20b1b410f5ace94d963a96e89156fbe65b70365e8596b37f1f165" #qwerty
let multiAccount = %* {
"accountID": account0["id"].getStr,
"paths": ["m/44'/60'/0'/0", "m/43'/60'/1581'", "m/43'/60'/1581'/0'/0", "m/44'/60'/0'/0/0"],
"paths": ["m/44'/60'/0'/0", "m/43'/60'/1581'", "m/43'/60'/1581'/0'/0",
"m/44'/60'/0'/0/0"],
"password": password
}
result = $libstatus.multiAccountStoreDerivedAccounts($multiAccount);
@ -138,92 +140,103 @@ proc setupNewAccount*() =
"mnemonic": account0["mnemonic"].getStr,
"public-key": multiAccounts["m/43'/60'/1581'/0'/0"]["publicKey"].getStr,
"name": accountData["name"].getStr,
"address": account0["address"].getStr,
"address": account0["address"].getStr,
"eip1581-address": multiAccounts["m/43'/60'/1581'"]["address"].getStr,
"dapps-address": multiAccounts["m/44'/60'/0'/0/0"]["address"].getStr,
"wallet-root-address": multiAccounts["m/44'/60'/0'/0"]["address"].getStr,
"wallet-root-address": multiAccounts["m/44'/60'/0'/0"]["address"].getStr,
"preview-privacy?": true,
"signing-phrase": "dust gear boss",
"log-level": "INFO",
"latest-derived-path": 0,
"networks/networks": [
{
"id": "testnet_rpc",
"etherscan-link": "https://ropsten.etherscan.io/address/",
"name": "Ropsten with upstream RPC",
"config":
{
"id": "testnet_rpc",
"etherscan-link": "https://ropsten.etherscan.io/address/",
"name": "Ropsten with upstream RPC",
"config": {
"NetworkId": 3,
"DataDir": "/ethereum/testnet_rpc",
"UpstreamConfig": {
"Enabled": true,
"URL": "https://ropsten.infura.io/v3/f315575765b14720b32382a61a89341a",
},
"NetworkId": 3,
"DataDir": "/ethereum/testnet_rpc",
"UpstreamConfig":
{
"Enabled": true,
"URL": "https://ropsten.infura.io/v3/f315575765b14720b32382a61a89341a",
},
},
},
{
"id": "rinkeby_rpc",
"etherscan-link": "https://rinkeby.etherscan.io/address/",
"name": "Rinkeby with upstream RPC",
"config":
{
"id": "rinkeby_rpc",
"etherscan-link": "https://rinkeby.etherscan.io/address/",
"name": "Rinkeby with upstream RPC",
"config": {
"NetworkId": 4,
"DataDir": "/ethereum/rinkeby_rpc",
"UpstreamConfig": {
"Enabled": true,
"URL": "https://rinkeby.infura.io/v3/f315575765b14720b32382a61a89341a",
},
"NetworkId": 4,
"DataDir": "/ethereum/rinkeby_rpc",
"UpstreamConfig":
{
"Enabled": true,
"URL": "https://rinkeby.infura.io/v3/f315575765b14720b32382a61a89341a",
},
},
},
{
"id": "goerli_rpc",
"etherscan-link": "https://goerli.etherscan.io/address/",
"name": "Goerli with upstream RPC",
"config":
{
"id": "goerli_rpc",
"etherscan-link": "https://goerli.etherscan.io/address/",
"name": "Goerli with upstream RPC",
"config": {
"NetworkId": 5,
"DataDir": "/ethereum/goerli_rpc",
"UpstreamConfig": {
"Enabled": true,
"URL": "https://goerli.blockscout.com/",
},
"NetworkId": 5,
"DataDir": "/ethereum/goerli_rpc",
"UpstreamConfig":
{
"Enabled": true,
"URL": "https://goerli.blockscout.com/",
},
},
},
{
"id": "mainnet_rpc",
"etherscan-link": "https://etherscan.io/address/",
"name": "Mainnet with upstream RPC",
"config":
{
"id": "mainnet_rpc",
"etherscan-link": "https://etherscan.io/address/",
"name": "Mainnet with upstream RPC",
"config": {
"NetworkId": 1,
"DataDir": "/ethereum/mainnet_rpc",
"UpstreamConfig": {
"Enabled": true,
"URL": "https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a",
},
"NetworkId": 1,
"DataDir": "/ethereum/mainnet_rpc",
"UpstreamConfig":
{
"Enabled": true,
"URL": "https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a",
},
},
},
{
"id": "xdai_rpc",
"name": "xDai Chain",
"config":
{
"id": "xdai_rpc",
"name": "xDai Chain",
"config": {
"NetworkId": 100,
"DataDir": "/ethereum/xdai_rpc",
"UpstreamConfig": {
"Enabled": true,
"URL": "https://dai.poa.network"
},
"NetworkId": 100,
"DataDir": "/ethereum/xdai_rpc",
"UpstreamConfig":
{
"Enabled": true,
"URL": "https://dai.poa.network"
},
},
},
{
"id": "poa_rpc",
"name": "POA Network",
"config":
{
"id": "poa_rpc",
"name": "POA Network",
"config": {
"NetworkId": 99,
"DataDir": "/ethereum/poa_rpc",
"UpstreamConfig": {
"Enabled": true,
"URL": "https://core.poa.network"
},
"NetworkId": 99,
"DataDir": "/ethereum/poa_rpc",
"UpstreamConfig":
{
"Enabled": true,
"URL": "https://core.poa.network"
},
},
],
}],
"currency": "usd",
"photo-path": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmElEQVR4nOzX4QmAIBBA4Yp2aY52aox2ao6mqf+SoajwON73M0J4HBy6TEEYQmMIjSE0htCECVlbDziv+/n6fuzb3OP/UmEmYgiNITRNm+LPqO2UE2YihtAYQlN818ptoZzau1btOakwEzGExhCa5hdi7d2p1zZLhZmIITSG0PhCpDGExhANEmYihtAYQmMIjSE0bwAAAP//kHQdRIWYzToAAAAASUVORK5CYII=",
"waku-enabled": true,
@ -234,9 +247,9 @@ proc setupNewAccount*() =
"networks/current-network": "mainnet_rpc",
"installation-id": "5d6bc316-a97e-5b89-9541-ad01f8eb7397",
}
let configJSON = %* {
"BrowsersConfig": {
"BrowsersConfig": {
"Enabled": true
},
"ClusterConfig": {
@ -318,41 +331,42 @@ proc setupNewAccount*() =
"Enabled": true
}
}
let subaccountData = %* [
{
"public-key": multiAccounts["m/44'/60'/0'/0/0"]["publicKey"],
"address": multiAccounts["m/44'/60'/0'/0/0"]["address"],
"color":"#4360df",
"wallet":true,
"path":"m/44'/60'/0'/0/0",
"name":"Status account"
"color": "#4360df",
"wallet": true,
"path": "m/44'/60'/0'/0/0",
"name": "Status account"
},
{
"public-key": multiAccounts["m/43'/60'/1581'/0'/0"]["publicKey"],
"address": multiAccounts["m/43'/60'/1581'/0'/0"]["address"],
"name":"Delectable Overjoyed Nauplius",
"photo-path":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmElEQVR4nOzX4QmAIBBA4Yp2aY52aox2ao6mqf+SoajwON73M0J4HBy6TEEYQmMIjSE0htCECVlbDziv+/n6fuzb3OP/UmEmYgiNITRNm+LPqO2UE2YihtAYQlN818ptoZzau1btOakwEzGExhCa5hdi7d2p1zZLhZmIITSG0PhCpDGExhANEmYihtAYQmMIjSE0bwAAAP//kHQdRIWYzToAAAAASUVORK5CYII=",
"path":"m/43'/60'/1581'/0'/0",
"chat":true
"name": "Delectable Overjoyed Nauplius",
"photo-path": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmElEQVR4nOzX4QmAIBBA4Yp2aY52aox2ao6mqf+SoajwON73M0J4HBy6TEEYQmMIjSE0htCECVlbDziv+/n6fuzb3OP/UmEmYgiNITRNm+LPqO2UE2YihtAYQlN818ptoZzau1btOakwEzGExhCa5hdi7d2p1zZLhZmIITSG0PhCpDGExhANEmYihtAYQmMIjSE0bwAAAP//kHQdRIWYzToAAAAASUVORK5CYII=",
"path": "m/43'/60'/1581'/0'/0",
"chat": true
}
]
result = $libstatus.saveAccountAndLogin($accountData, password, $settingsJSON, $configJSON, $subaccountData)
result = $libstatus.saveAccountAndLogin($accountData, password, $settingsJSON,
$configJSON, $subaccountData)
let saveResult = result.parseJson
if saveResult["error"].getStr == "":
echo "Account saved succesfully"
proc callRPC*(inputJSON: string): string =
return $libstatus.callRPC(inputJSON)
return $libstatus.callRPC(inputJSON)
proc callPrivateRPC*(inputJSON: string): string =
return $libstatus.callPrivateRPC(inputJSON)
return $libstatus.callPrivateRPC(inputJSON)
proc addPeer*(peer: string): string =
return $libstatus.addPeer(peer)
return $libstatus.addPeer(peer)
# proc onMessage*(callback: proc(message: string)): void =
# $libstatus.setSignalEventCallback(callback)

387
ui/app/AppMain.qml Normal file
View File

@ -0,0 +1,387 @@
import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import Qt.labs.platform 1.1
import "../imports"
RowLayout {
id: rowLayout
width: parent.height
height: parent.width
anchors.fill: parent
// spacing: 50
TabBar {
id: tabBar
y: 0
width: 50
height: width *2 + spacing
Layout.preferredHeight: 0
currentIndex: 0
topPadding: 57
rightPadding: 19
leftPadding: 19
transformOrigin: Item.Top
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true
spacing: 5
Layout.fillWidth: true
Layout.minimumWidth: 80
Layout.preferredWidth: 80
Layout.maximumWidth: 80
Layout.minimumHeight: 0
background: Rectangle {
color: "#00000000"
border.color: Theme.grey
}
TabButton {
id: chatBtn
x: 0
width: 40
height: 40
text: ""
padding: 0
transformOrigin: Item.Center
anchors.horizontalCenter: parent.horizontalCenter
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/messageActive.svg" : "img/message.svg"
}
}
TabButton {
id: walletBtn
width: 40
height: 40
text: ""
anchors.topMargin: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: chatBtn.top
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image1
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/walletActive.svg" : "img/wallet.svg"
}
}
TabButton {
id: browserBtn
width: 40
height: 40
text: ""
anchors.topMargin: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: walletBtn.top
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image2
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/compassActive.svg" : "img/compass.svg"
}
}
TabButton {
id: profileBtn
width: 40
height: 40
text: ""
anchors.topMargin: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: browserBtn.top
background: Rectangle {
color: Theme.lightBlue
opacity: parent.checked ? 1 : 0
radius: 50
}
Image {
id: image3
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: parent.checked ? "img/profileActive.svg" : "img/profile.svg"
}
}
}
StackLayout {
anchors.left: tabBar.right
anchors.leftMargin: 0
anchors.right: parent.right
anchors.rightMargin: 0
Layout.fillWidth: true
currentIndex: tabBar.currentIndex
SplitView {
id: splitView
x: 0
y: 0
Layout.fillHeight: true
// anchors.fill: parent
// width: parent.width
Layout.leftMargin: 0
Layout.fillWidth: true
Item {
id: element1
width: 300
height: parent.height
Layout.minimumWidth: 200
ColumnLayout {
anchors.rightMargin: 0
anchors.fill: parent
Item {
Layout.preferredHeight: 100
Layout.fillHeight: false
Layout.fillWidth: true
Text {
id: element
x: 772
text: qsTr("Chat")
anchors.top: parent.top
anchors.topMargin: 17
font.bold: true
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 17
}
Rectangle {
id: searchBox
height: 36
color: Theme.grey
anchors.top: parent.top
anchors.topMargin: 59
radius: 8
anchors.right: parent.right
anchors.rightMargin: 65
anchors.left: parent.left
anchors.leftMargin: 16
TextField {
id: searchText
placeholderText: qsTr("Search")
anchors.left: parent.left
anchors.leftMargin: 32
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 12
background: Rectangle {
color: "#00000000"
}
}
Image {
id: image4
anchors.left: parent.left
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: "img/search.svg"
}
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked : {
searchText.forceActiveFocus(Qt.MouseFocusReason)
}
}
}
Rectangle {
id: addChat
width: 36
height: 36
color: Theme.blue
radius: 50
anchors.right: parent.right
anchors.rightMargin: 16
anchors.top: parent.top
anchors.topMargin: 59
Text {
id: element3
color: "#ffffff"
text: qsTr("+")
anchors.verticalCenterOffset: -1
anchors.horizontalCenterOffset: 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
lineHeight: 1
fontSizeMode: Text.FixedSize
font.bold: true
font.pixelSize: 28
}
}
}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
Component {
id: chatViewDelegate
Rectangle {
id: wrapper
height: 64
color: ListView.isCurrentItem ? Theme.lightBlue : Theme.transparent
anchors.right: parent.right
anchors.rightMargin: 16
anchors.top: applicationWindow.top
anchors.topMargin: 0
anchors.left: parent.left
anchors.leftMargin: 16
radius: 8
MouseArea {
anchors.fill: parent
onClicked: listView.currentIndex = index
}
Rectangle {
id: contactImage
width: 40
color: Theme.darkGrey
anchors.left: parent.left
anchors.leftMargin: 16
anchors.top: parent.top
anchors.topMargin: 12
anchors.bottom: parent.bottom
anchors.bottomMargin: 12
radius: 50
}
Text {
id: contactInfo
text: "Name:" + name
font.weight: Font.Medium
font.pixelSize: 15
anchors.left: contactImage.right
anchors.leftMargin: 16
anchors.top: parent.top
anchors.topMargin: 10
color: "black"
}
Text {
id: lastChatMessage
text: "Chatting blah blah..."
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
font.pixelSize: 15
anchors.left: contactImage.right
anchors.leftMargin: 16
color: Theme.darkGrey
}
Text {
id: contactTime
text: "12:22 AM"
anchors.right: parent.right
anchors.rightMargin: 16
anchors.top: parent.top
anchors.topMargin: 10
font.pixelSize: 11
color: Theme.darkGrey
}
Rectangle {
id: contactNumberChatsCircle
width: 22
height: 22
radius: 50
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
anchors.right: parent.right
anchors.rightMargin: 16
color: Theme.blue
Text {
id: contactNumberChats
text: qsTr("1")
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "white"
}
}
}
}
ListView {
id: listView
anchors.topMargin: 24
anchors.fill: parent
model: chatsModel
delegate: chatViewDelegate
}
}
}
}
ColumnLayout {
anchors.rightMargin: 0
RowLayout {
Layout.fillHeight: true
TextArea { id: callResult; Layout.fillWidth: true; text: logic.callResult; readOnly: true }
}
RowLayout {
Layout.bottomMargin: 20
Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
transformOrigin: Item.Bottom
Label { text: "data2" }
TextField { id: txtData; Layout.fillWidth: true; text: "" }
Button {
text: "Send"
onClicked: logic.onSend(txtData.text)
enabled: txtData.text !== ""
}
}
}
}
ColumnLayout {
RowLayout {
Layout.fillHeight: true
TextArea { id: accountResult; Layout.fillWidth: true; text: logic.accountResult; readOnly: true }
}
}
Item {
}
}
}
/*##^##
Designer {
D{i:0;height:770;width:1232}
}
##^##*/

View File

Before

Width:  |  Height:  |  Size: 680 B

After

Width:  |  Height:  |  Size: 680 B

View File

Before

Width:  |  Height:  |  Size: 655 B

After

Width:  |  Height:  |  Size: 655 B

View File

Before

Width:  |  Height:  |  Size: 869 B

After

Width:  |  Height:  |  Size: 869 B

View File

Before

Width:  |  Height:  |  Size: 883 B

After

Width:  |  Height:  |  Size: 883 B

View File

Before

Width:  |  Height:  |  Size: 622 B

After

Width:  |  Height:  |  Size: 622 B

View File

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 611 B

View File

Before

Width:  |  Height:  |  Size: 709 B

After

Width:  |  Height:  |  Size: 709 B

View File

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 657 B

View File

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 646 B

1
ui/app/qmldir Normal file
View File

@ -0,0 +1 @@
AppMain 1.0 AppMain.qml

64
ui/main.qml Normal file
View File

@ -0,0 +1,64 @@
import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import Qt.labs.platform 1.1
import "./onboarding" as Onboarding
import "./app" as App
ApplicationWindow {
id: applicationWindow
width: 1232
height: 770
title: "Nim Status Client"
visible: true
SystemTrayIcon {
visible: true
icon.source: "shared/img/status-logo.png"
menu: Menu {
MenuItem {
text: qsTr("Quit")
onTriggered: Qt.quit()
}
}
onActivated: {
applicationWindow.show()
applicationWindow.raise()
applicationWindow.requestActivate()
}
}
Rectangle {
id: rctAppBg
color: "#FFFFFF"
Layout.fillHeight: true
Layout.fillWidth: true
anchors.fill: parent
border.width: 0
Onboarding.Intro {
id: onboarding
visible: !app.visible
anchors.fill: parent
}
App.AppMain {
id: app
// TODO: Set this to a logic result determining when we need to show the onboarding screens
// Set to true to hide the onboarding screens manually
// Set to false to show the onboarding screens manually
visible: false // logic.accountResult !== ""
anchors.fill: parent
}
}
}
/*##^##
Designer {
D{i:9;anchors_height:40;anchors_width:40}
}
##^##*/

View File

@ -49,4 +49,32 @@ DISTFILES += \
Inter-ThinItalic.otf \
Inter-V.otf \
Theme.qml \
imports/qmldir
app/AppMain.qml \
app/img/compass.svg \
app/img/compassActive.svg \
app/img/message.svg \
app/img/messageActive.svg \
app/img/profile.svg \
app/img/profileActive.svg \
app/img/search.svg \
app/img/wallet.svg \
app/img/walletActive.svg \
app/qmldir \
imports/qmldir \
onboarding/Intro.qml \
onboarding/img/browser-dark@2x.jpg \
onboarding/img/browser-dark@3x.jpg \
onboarding/img/browser@2x.jpg \
onboarding/img/browser@3x.jpg \
onboarding/img/chat-dark@2x.jpg \
onboarding/img/chat-dark@3x.jpg \
onboarding/img/chat@2x.jpg \
onboarding/img/chat@3x.jpg \
onboarding/img/next.svg \
onboarding/img/wallet-dark@2x.jpg \
onboarding/img/wallet-dark@3x.jpg \
onboarding/img/wallet@2x.jpg \
onboarding/img/wallet@3x.jpg \
onboarding/qmldir \
shared/Image.qml \
shared/qmldir

350
ui/onboarding/Intro.qml Normal file
View File

@ -0,0 +1,350 @@
import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
RowLayout {
id: obLayout
anchors.fill: parent
Layout.fillWidth: true
Layout.fillHeight: true
Rectangle {
border.width: 0
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.fillHeight: true
Layout.fillWidth: true
SwipeView {
id: vwOnboarding
width: parent.width
height: parent.height
currentIndex: 0
interactive: false
anchors.fill: parent
Item {
id: itmSlide1
Image {
id: img1
anchors.horizontalCenter: parent.horizontalCenter
sourceSize.width: 414
sourceSize.height: 414
anchors.topMargin: 17
fillMode: Image.PreserveAspectFit
source: "img/chat@2x.jpg"
}
Text {
id: txtTitle1
text: qsTr("Truly private communication")
anchors.right: parent.right
anchors.rightMargin: 177
anchors.left: parent.left
anchors.leftMargin: 177
anchors.top: img1.bottom
anchors.topMargin: 44
font.letterSpacing: -0.2
font.weight: Font.Bold
lineHeight: 1
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
transformOrigin: Item.Center
font.bold: true
font.pixelSize: 22
font.kerning: true
}
Text {
id: txtDesc1
x: 772
color: "#939BA1"
text: qsTr("Chat over a peer-to-peer, encrypted network\n where messages can't be censored or hacked")
font.weight: Font.Normal
style: Text.Normal
anchors.horizontalCenterOffset: 0
anchors.top: txtTitle1.bottom
anchors.topMargin: 14
font.bold: true
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 15
}
Button {
id: btnNext1
width: 40
height: 40
anchors.top: txtDesc1.top
anchors.bottomMargin: -2
anchors.bottom: txtDesc1.bottom
anchors.topMargin: -2
anchors.left: txtDesc1.right
anchors.leftMargin: 32
onClicked: vwOnboarding.currentIndex++
background: Rectangle {
id: rctNext1
color: "#ECEFFC"
border.width: 0
radius: 50
Image {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
source: "img/next.svg"
}
}
}
}
Item {
id: itmSlide2
Image {
id: img2
anchors.horizontalCenter: parent.horizontalCenter
sourceSize.width: 414
sourceSize.height: 414
anchors.top: parent.top
anchors.topMargin: 17
fillMode: Image.PreserveAspectFit
source: "img/wallet@2x.jpg"
}
Text {
id: txtTitle2
text: qsTr("Secure crypto wallet")
anchors.right: parent.right
anchors.rightMargin: 177
anchors.left: parent.left
anchors.leftMargin: 177
anchors.top: img2.bottom
anchors.topMargin: 44
font.letterSpacing: -0.2
font.weight: Font.Bold
lineHeight: 1
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
transformOrigin: Item.Center
font.bold: true
font.pixelSize: 22
font.kerning: true
}
Button {
id: btnPrev2
width: 40
height: 40
anchors.top: txtDesc2.top
anchors.bottomMargin: -2
anchors.bottom: txtDesc2.bottom
anchors.topMargin: -2
anchors.right: txtDesc2.left
anchors.rightMargin: 32
onClicked: vwOnboarding.currentIndex--
background: Rectangle {
id: rctPrev2
color: "#ECEFFC"
border.width: 0
radius: 50
Image {
rotation: 180
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
source: "img/next.svg"
}
}
}
Text {
id: txtDesc2
x: 772
color: "#939BA1"
text: qsTr("Send and receive digital assets anywhere in the\nworld--no bank account required")
font.weight: Font.Normal
style: Text.Normal
anchors.horizontalCenterOffset: 0
anchors.top: txtTitle2.bottom
anchors.topMargin: 14
font.bold: true
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 15
}
Button {
id: btnNext2
width: 40
height: 40
anchors.top: txtDesc2.top
anchors.bottomMargin: -2
anchors.bottom: txtDesc2.bottom
anchors.topMargin: -2
anchors.left: txtDesc2.right
anchors.leftMargin: 32
onClicked: vwOnboarding.currentIndex++
background: Rectangle {
id: rctNext2
color: "#ECEFFC"
border.width: 0
radius: 50
Image {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
source: "img/next.svg"
}
}
}
}
Item {
id: itmSlide3
Image {
id: img3
anchors.horizontalCenter: parent.horizontalCenter
sourceSize.width: 414
sourceSize.height: 414
anchors.topMargin: 17
fillMode: Image.PreserveAspectFit
source: "img/browser@2x.jpg"
}
Text {
id: txtTitle3
text: qsTr("Decentralized apps")
anchors.right: parent.right
anchors.rightMargin: 177
anchors.left: parent.left
anchors.leftMargin: 177
anchors.top: img3.bottom
anchors.topMargin: 44
font.letterSpacing: -0.2
font.weight: Font.Bold
lineHeight: 1
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
transformOrigin: Item.Center
font.bold: true
font.pixelSize: 22
font.kerning: true
}
Button {
id: btnPrev3
width: 40
height: 40
anchors.top: txtDesc3.top
anchors.bottomMargin: -2
anchors.bottom: txtDesc3.bottom
anchors.topMargin: -2
anchors.right: txtDesc3.left
anchors.rightMargin: 32
onClicked: vwOnboarding.currentIndex--
background: Rectangle {
id: rctPrev3
color: "#ECEFFC"
border.width: 0
radius: 50
Image {
rotation: 180
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
source: "img/next.svg"
}
}
}
Text {
id: txtDesc3
x: 772
color: "#939BA1"
text: qsTr("Explore games, exchanges and social networks\nwhere you alone own your data")
font.weight: Font.Normal
style: Text.Normal
anchors.horizontalCenterOffset: 0
anchors.top: txtTitle3.bottom
anchors.topMargin: 14
font.bold: true
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 15
}
}
}
Rectangle {
id: rctPageIndicator
border.width: 0
anchors.bottom: vwOnboarding.bottom
anchors.bottomMargin: 191
anchors.top: vwOnboarding.top
anchors.topMargin: 567
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
PageIndicator {
id: pgOnboarding
anchors.horizontalCenter: parent.horizontalCenter
spacing: 5
padding: 0
topPadding: 0
bottomPadding: 0
rightPadding: 0
leftPadding: 0
font.pixelSize: 6
count: vwOnboarding.count
currentIndex: vwOnboarding.currentIndex
}
}
Button {
id: btnGetStarted
rightPadding: 32
leftPadding: 32
bottomPadding: 11
topPadding: 11
width: 146
height: 44
anchors.top: rctPageIndicator.bottom
anchors.topMargin: 87
anchors.horizontalCenter: parent.horizontalCenter
onClicked: app.visible = true
background: Rectangle {
color: "#ECEFFC"
radius: 8
}
Text {
id: txtGetStarted
color: "#4360DF"
text: qsTr("Get started")
font.weight: Font.DemiBold
font.pointSize: 15
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
}
Text {
id: txtPrivacyPolicy
x: 772
text: qsTr("Status does not collect, share or sell any personal data. By continuing you agree with the privacy policy.")
anchors.top: btnGetStarted.bottom
anchors.topMargin: 17
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 12
font.letterSpacing: 0.1
color: "#939BA1"
}
}
}
/*##^##
Designer {
D{i:0;autoSize:true;height:770;width:1232}
}
##^##*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
ui/onboarding/img/browser@2x.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
ui/onboarding/img/browser@3x.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
ui/onboarding/img/chat@2x.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
ui/onboarding/img/chat@3x.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@ -0,0 +1,3 @@
<svg width="9" height="16" viewBox="0 0 9 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.70719 8.71434L1.69578 15.7079C1.3074 16.0953 0.681196 16.0988 0.291074 15.7097C-0.0963472 15.3232 -0.0907033 14.6911 0.292809 14.3085L6.61881 7.99859L0.292809 1.68865C-0.0955705 1.30126 -0.0990483 0.676638 0.291074 0.287507C0.678495 -0.0989301 1.31227 -0.0933004 1.69578 0.289237L8.70719 7.28284C8.93181 7.50689 9.02769 7.81029 8.99313 8.10159C8.97295 8.32613 8.8772 8.54476 8.70719 8.71434Z" fill="#4360DF"/>
</svg>

After

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
ui/onboarding/img/wallet@2x.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
ui/onboarding/img/wallet@3x.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

1
ui/onboarding/qmldir Normal file
View File

@ -0,0 +1 @@
Intro 1.0 Intro.qml

10
ui/shared/Image.qml Normal file
View File

@ -0,0 +1,10 @@
Image {
source: {
if (Screen.PixelDensity < 40)
"image_low_dpi.png"
else if (Screen.PixelDensity > 300)
"image_high_dpi.png"
else
"image.png"
}
}

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

1
ui/shared/qmldir Normal file
View File

@ -0,0 +1 @@
Image 1.0 Image.qml