Desktop branch merged into develop (#5266)
* Desktop branch merged into develop * Fixed review notes by yenda
This commit is contained in:
parent
bdc7284308
commit
457f2a157a
|
@ -1 +1,2 @@
|
||||||
*.pbxproj -text
|
*.pbxproj -text
|
||||||
|
*.patch eol=lf
|
||||||
|
|
|
@ -108,3 +108,8 @@ fastlane/README.md
|
||||||
# emacs
|
# emacs
|
||||||
.dir-locals.el
|
.dir-locals.el
|
||||||
|
|
||||||
|
#ignore platform-specific files in the root since they are only symlinks to files in folders 'desktop_files' and 'mobile_files'
|
||||||
|
/VERSION
|
||||||
|
/package-lock.json
|
||||||
|
/package.json
|
||||||
|
/.re-natal
|
||||||
|
|
|
@ -9,6 +9,7 @@ def installJSDeps() {
|
||||||
def installed = false
|
def installed = false
|
||||||
while (!installed && attempt <= maxAttempts) {
|
while (!installed && attempt <= maxAttempts) {
|
||||||
println "#${attempt} attempt to install npm deps"
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh mobile'
|
||||||
sh 'npm install'
|
sh 'npm install'
|
||||||
installed = fileExists('node_modules/web3/index.js')
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
attemp = attempt + 1
|
attemp = attempt + 1
|
||||||
|
@ -72,7 +73,7 @@ timeout(90) {
|
||||||
hash = sh(returnStdout: true, script: "curl -vvv 'https://upload.diawi.com/status?token="+token+"&job="+job+"'|jq -r '.hash'").trim()
|
hash = sh(returnStdout: true, script: "curl -vvv 'https://upload.diawi.com/status?token="+token+"&job="+job+"'|jq -r '.hash'").trim()
|
||||||
}
|
}
|
||||||
apkUrl = 'https://i.diawi.com/' + hash
|
apkUrl = 'https://i.diawi.com/' + hash
|
||||||
|
|
||||||
sh ('echo ARTIFACT Android: ' + apkUrl)
|
sh ('echo ARTIFACT Android: ' + apkUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
env.LANG="en_US.UTF-8"
|
||||||
|
env.LANGUAGE="en_US.UTF-8"
|
||||||
|
env.LC_ALL="en_US.UTF-8"
|
||||||
|
|
||||||
|
def installJSDeps() {
|
||||||
|
def attempt = 1
|
||||||
|
def maxAttempts = 10
|
||||||
|
def installed = false
|
||||||
|
sh 'node -v'
|
||||||
|
sh 'npm -v'
|
||||||
|
while (!installed && attempt <= maxAttempts) {
|
||||||
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh desktop'
|
||||||
|
sh 'npm install --verbose'
|
||||||
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
|
attemp = attempt + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def doGitRebase() {
|
||||||
|
try {
|
||||||
|
sh 'git rebase origin/develop'
|
||||||
|
} catch (e) {
|
||||||
|
sh 'git rebase --abort'
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def cleanupBuild(packageFolder) {
|
||||||
|
sh 'rm -rf node_modules'
|
||||||
|
sh ( 'rm -rf ' + packageFolder )
|
||||||
|
sh 'rm -rf desktop/modules'
|
||||||
|
sh 'rm -rf desktop/node_modules'
|
||||||
|
}
|
||||||
|
|
||||||
|
parallel (
|
||||||
|
"MacOS parallel build stream" : {
|
||||||
|
timeout(90) {
|
||||||
|
node ('macos1') {
|
||||||
|
def apkUrl = ''
|
||||||
|
def ipaUrl = ''
|
||||||
|
def testPassed = true
|
||||||
|
def branch;
|
||||||
|
def scriptOutput = ''
|
||||||
|
def packageFolder = './StatusImPackage'
|
||||||
|
def scriptPath = sh(script: 'pwd -P', returnStdout: true).trim()
|
||||||
|
|
||||||
|
load "$HOME/env.groovy"
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
stage('Git & Dependencies') {
|
||||||
|
slackSend channel: '#jenkins-desktop', color: 'good', message: BRANCH_NAME + '(' + env.CHANGE_BRANCH + ') MacOS build started. ' + env.BUILD_URL
|
||||||
|
|
||||||
|
sh ('echo ' + scriptPath)
|
||||||
|
|
||||||
|
checkout scm
|
||||||
|
|
||||||
|
doGitRebase()
|
||||||
|
|
||||||
|
cleanupBuild(packageFolder)
|
||||||
|
sh 'cp .env.jenkins .env'
|
||||||
|
sh 'lein deps'
|
||||||
|
|
||||||
|
installJSDeps()
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build ClojureScript') {
|
||||||
|
sh 'rm -f index.desktop.js'
|
||||||
|
sh 'lein prod-build-desktop'
|
||||||
|
|
||||||
|
sh ( 'mkdir ' + packageFolder )
|
||||||
|
sh ( 'react-native bundle --entry-file index.desktop.js --bundle-output ' + packageFolder + '/StatusIm.jsbundle --dev false --platform desktop --assets-dest ' + packageFolder + '/assets' )
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build MacOS binaries') {
|
||||||
|
sh 'cd desktop && rm -rf CMakeFiles CMakeCache.txt cmake_install.cmake Makefile'
|
||||||
|
sh 'export PATH=/Users/administrator/qt/5.9.1/clang_64/bin:$PATH && cd desktop && cmake -DCMAKE_BUILD_TYPE=Release -DEXTERNAL_MODULES_DIR="node_modules/react-native-i18n/desktop;node_modules/react-native-config/desktop;node_modules/react-native-fs/desktop;node_modules/react-native-http-bridge/desktop;node_modules/react-native-webview-bridge/desktop;node_modules/react-native-keychain/desktop;node_modules/react-native-securerandom/desktop;modules/react-native-status/desktop"\
|
||||||
|
-DJS_BUNDLE_PATH="' + scriptPath + '/' + packageFolder + '/StatusIm.jsbundle" -DCMAKE_CXX_FLAGS:="-DBUILD_FOR_BUNDLE=1" . && make'
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Prepare and create MacOS Bundle') {
|
||||||
|
sh ('cd ' + packageFolder + ' && ../scripts/download-package-files.sh "StatusIm.app.zip" "1Vkb6MD3nsmT02Az6rRRZywQSwCz1ZN9V" && unzip ./StatusIm.app.zip')
|
||||||
|
sh ('cp -r ' + packageFolder + '/assets/share/assets ' + packageFolder +'/StatusIm.app/Contents/MacOs')
|
||||||
|
sh ('chmod +x ' + packageFolder + '/StatusIm.app/Contents/MacOs/ubuntu-server')
|
||||||
|
sh ('cp ./desktop/bin/StatusIm ' + packageFolder +'/StatusIm.app/Contents/MacOs')
|
||||||
|
|
||||||
|
sh ('export PATH=/Users/administrator/qt/5.9.1/clang_64/bin:$PATH && cd ' + packageFolder + ' && macdeployqt StatusIm.app -verbose=1 -dmg -qmldir="' + scriptPath + '/node_modules/react-native/ReactQt/runtime/src/qml/"')
|
||||||
|
|
||||||
|
sh 'rm -f StatusIm.app.zip'
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Archive built artifact') {
|
||||||
|
archiveArtifacts "StatusImPackage/*.dmg"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanupBuild(packageFolder)
|
||||||
|
slackSend channel: '#jenkins-desktop', color: 'good', message: BRANCH_NAME + '(' + env.CHANGE_BRANCH + ') MacOS build finished successfully. ' + env.BUILD_URL
|
||||||
|
} catch (e) {
|
||||||
|
cleanupBuild(packageFolder)
|
||||||
|
slackSend channel: '#jenkins-desktop', color: 'bad', message: BRANCH_NAME + ' failed to build on MacOS. ' + env.BUILD_URL
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Linux parallel build stream" : {
|
||||||
|
timeout(90) {
|
||||||
|
node ('linux1') {
|
||||||
|
def apkUrl = ''
|
||||||
|
def ipaUrl = ''
|
||||||
|
def testPassed = true
|
||||||
|
def branch;
|
||||||
|
def scriptOutput = ''
|
||||||
|
def packageFolder = './StatusImPackage'
|
||||||
|
def scriptPath = sh(script: 'pwd -P', returnStdout: true).trim()
|
||||||
|
|
||||||
|
sh ('echo ' + scriptPath)
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
stage('Git & Dependencies') {
|
||||||
|
slackSend channel: '#jenkins-desktop', color: 'good', message: BRANCH_NAME + '(' + env.CHANGE_BRANCH + ') Linux build started. ' + env.BUILD_URL
|
||||||
|
|
||||||
|
sh ('echo ' + scriptPath)
|
||||||
|
|
||||||
|
checkout scm
|
||||||
|
|
||||||
|
doGitRebase()
|
||||||
|
|
||||||
|
cleanupBuild(packageFolder)
|
||||||
|
sh 'cp .env.jenkins .env'
|
||||||
|
sh 'lein deps'
|
||||||
|
|
||||||
|
installJSDeps()
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build ClojureScript') {
|
||||||
|
sh 'rm -f index.desktop.js'
|
||||||
|
sh 'lein prod-build-desktop'
|
||||||
|
|
||||||
|
sh ( 'mkdir ' + packageFolder )
|
||||||
|
sh ( 'react-native bundle --entry-file index.desktop.js --bundle-output ' + packageFolder + '/StatusIm.jsbundle --dev false --platform desktop --assets-dest ' + packageFolder + '/assets' )
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build Linux binaries') {
|
||||||
|
sh 'cd desktop && rm -rf CMakeFiles CMakeCache.txt cmake_install.cmake Makefile'
|
||||||
|
sh 'export PATH=/home/maxr/Qt5.9.1/5.9.1/gcc_64/bin:/usr/local/go/bin:$PATH && cd desktop && cmake -DCMAKE_BUILD_TYPE=Release -DEXTERNAL_MODULES_DIR="node_modules/react-native-i18n/desktop;node_modules/react-native-config/desktop;node_modules/react-native-fs/desktop;node_modules/react-native-http-bridge/desktop;node_modules/react-native-webview-bridge/desktop;node_modules/react-native-keychain/desktop;node_modules/react-native-securerandom/desktop;modules/react-native-status/desktop"\
|
||||||
|
-DJS_BUNDLE_PATH="' + scriptPath + '/' + packageFolder + '/StatusIm.jsbundle" -DCMAKE_CXX_FLAGS:="-DBUILD_FOR_BUNDLE=1" . && make'
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Prepare and create Linux AppImage') {
|
||||||
|
sh ('rm -rf ' + packageFolder + '/StatusImAppImage')
|
||||||
|
sh ('cd ' + packageFolder + ' && cp /home/maxr/qttools/StatusImAppImage.zip ./ && unzip ./StatusImAppImage.zip')
|
||||||
|
|
||||||
|
sh ('rm -rf ' + packageFolder + '/AppDir && mkdir ' + packageFolder + '/AppDir')
|
||||||
|
sh ('cp -r ./deployment/linux/usr ' + packageFolder + '/AppDir')
|
||||||
|
sh ('cp ./deployment/linux/.env ' + packageFolder + '/AppDir')
|
||||||
|
sh ('cp ./desktop/bin/StatusIm ' + packageFolder+ '/AppDir/usr/bin')
|
||||||
|
|
||||||
|
sh ('cp -f /home/maxr/qttools/linuxdeployqt-continuous-x86_64.AppImage ./')
|
||||||
|
sh ('chmod a+x ./linuxdeployqt-continuous-x86_64.AppImage')
|
||||||
|
|
||||||
|
sh 'rm -f Application-x86_64.AppImage'
|
||||||
|
sh 'rm -f StatusIm-x86_64.AppImage'
|
||||||
|
|
||||||
|
sh 'ldd ' + packageFolder+ '/AppDir/usr/bin/StatusIm'
|
||||||
|
sh ('export PATH=/home/maxr/Qt5.9.1/5.9.1/gcc_64/bin:/usr/local/go/bin:$PATH && ./linuxdeployqt-continuous-x86_64.AppImage ' + packageFolder+ '/AppDir/usr/share/applications/StatusIm.desktop -verbose=3 -always-overwrite -no-strip -no-translations -bundle-non-qt-libs -qmake=/home/maxr/Qt5.9.1/5.9.1/gcc_64/bin/qmake -extra-plugins=imageformats/libqsvg.so -qmldir="' + scriptPath + '/node_modules/react-native"')
|
||||||
|
sh 'ldd ' + packageFolder+ '/AppDir/usr/bin/StatusIm'
|
||||||
|
|
||||||
|
sh ('cp -r ' + packageFolder + '/assets/share/assets ' + packageFolder +'/AppDir/usr/bin')
|
||||||
|
sh ('cp -rf ' + packageFolder + '/StatusImAppImage/* ' + packageFolder +'/AppDir/usr/bin')
|
||||||
|
sh ('rm -f ' + packageFolder +'/AppDir/usr/bin/StatusIm.AppImage')
|
||||||
|
|
||||||
|
sh ('export PATH=/home/maxr/Qt5.9.1/5.9.1/gcc_64/bin:/usr/local/go/bin:$PATH && ./linuxdeployqt-continuous-x86_64.AppImage ' + packageFolder+ '/AppDir/usr/share/applications/StatusIm.desktop -verbose=3 -appimage -qmake=/home/maxr/Qt5.9.1/5.9.1/gcc_64/bin/qmake')
|
||||||
|
sh 'ldd ' + packageFolder+ '/AppDir/usr/bin/StatusIm'
|
||||||
|
|
||||||
|
sh ('rm -rf ' + packageFolder +'/StatusIm.AppImage')
|
||||||
|
sh ('cp -f ./StatusIm-x86_64.AppImage ' + packageFolder + '/StatusIm.AppImage')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Archive built artifact') {
|
||||||
|
archiveArtifacts "StatusImPackage/*.AppImage"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanupBuild(packageFolder)
|
||||||
|
slackSend channel: '#jenkins-desktop', color: 'good', message: BRANCH_NAME + '(' + env.CHANGE_BRANCH + ') Linux build finished successfully. ' + env.BUILD_URL
|
||||||
|
} catch (e) {
|
||||||
|
cleanupBuild(packageFolder)
|
||||||
|
slackSend channel: '#jenkins-desktop', color: 'bad', message: BRANCH_NAME + ' failed to build on Linux. ' + env.BUILD_URL
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
|
@ -12,6 +12,7 @@ def installJSDeps() {
|
||||||
def installed = false
|
def installed = false
|
||||||
while (!installed && attempt <= maxAttempts) {
|
while (!installed && attempt <= maxAttempts) {
|
||||||
println "#${attempt} attempt to install npm deps"
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh mobile'
|
||||||
sh 'npm install'
|
sh 'npm install'
|
||||||
installed = fileExists('node_modules/web3/index.js')
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
attemp = attempt + 1
|
attemp = attempt + 1
|
||||||
|
|
|
@ -12,6 +12,7 @@ def installJSDeps() {
|
||||||
def installed = false
|
def installed = false
|
||||||
while (!installed && attempt <= maxAttempts) {
|
while (!installed && attempt <= maxAttempts) {
|
||||||
println "#${attempt} attempt to install npm deps"
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh mobile'
|
||||||
sh 'npm install'
|
sh 'npm install'
|
||||||
installed = fileExists('node_modules/web3/index.js')
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
attemp = attempt + 1
|
attemp = attempt + 1
|
||||||
|
|
|
@ -9,6 +9,7 @@ def installJSDeps() {
|
||||||
def installed = false
|
def installed = false
|
||||||
while (!installed && attempt <= maxAttempts) {
|
while (!installed && attempt <= maxAttempts) {
|
||||||
println "#${attempt} attempt to install npm deps"
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh mobile'
|
||||||
sh 'npm install'
|
sh 'npm install'
|
||||||
installed = fileExists('node_modules/web3/index.js')
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
attemp = attempt + 1
|
attemp = attempt + 1
|
||||||
|
|
|
@ -12,6 +12,7 @@ def installJSDeps() {
|
||||||
def installed = false
|
def installed = false
|
||||||
while (!installed && attempt <= maxAttempts) {
|
while (!installed && attempt <= maxAttempts) {
|
||||||
println "#${attempt} attempt to install npm deps"
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh mobile'
|
||||||
sh 'npm install'
|
sh 'npm install'
|
||||||
installed = fileExists('node_modules/web3/index.js')
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
attemp = attempt + 1
|
attemp = attempt + 1
|
||||||
|
|
|
@ -12,6 +12,7 @@ def installJSDeps() {
|
||||||
def installed = false
|
def installed = false
|
||||||
while (!installed && attempt <= maxAttempts) {
|
while (!installed && attempt <= maxAttempts) {
|
||||||
println "#${attempt} attempt to install npm deps"
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh mobile'
|
||||||
sh 'npm install'
|
sh 'npm install'
|
||||||
installed = fileExists('node_modules/web3/index.js')
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
attemp = attempt + 1
|
attemp = attempt + 1
|
||||||
|
|
|
@ -12,6 +12,7 @@ def installJSDeps() {
|
||||||
def installed = false
|
def installed = false
|
||||||
while (!installed && attempt <= maxAttempts) {
|
while (!installed && attempt <= maxAttempts) {
|
||||||
println "#${attempt} attempt to install npm deps"
|
println "#${attempt} attempt to install npm deps"
|
||||||
|
sh 'scripts/prepare-for-platform.sh mobile'
|
||||||
sh 'npm install'
|
sh 'npm install'
|
||||||
installed = fileExists('node_modules/web3/index.js')
|
installed = fileExists('node_modules/web3/index.js')
|
||||||
attemp = attempt + 1
|
attemp = attempt + 1
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -30,8 +30,10 @@ setup: ##@prepare Install all the requirements for status-react
|
||||||
./scripts/setup
|
./scripts/setup
|
||||||
|
|
||||||
prepare: ##@prepare Install dependencies and prepare workspace
|
prepare: ##@prepare Install dependencies and prepare workspace
|
||||||
|
scripts/prepare-for-platform.sh mobile
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
|
|
||||||
prepare-ios: prepare ##@prepare Install iOS specific dependencies
|
prepare-ios: prepare ##@prepare Install iOS specific dependencies
|
||||||
mvn -f modules/react-native-status/ios/RCTStatus dependency:unpack
|
mvn -f modules/react-native-status/ios/RCTStatus dependency:unpack
|
||||||
cd ios && pod install && cd ..
|
cd ios && pod install && cd ..
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
(def cljsbuild-config
|
(def cljsbuild-config
|
||||||
{:dev
|
{:dev
|
||||||
{:ios
|
{:ios
|
||||||
{:source-paths ["components/src" "react-native/src" "src"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src"]
|
||||||
:compiler {:output-to "target/ios/app.js"
|
:compiler {:output-to "target/ios/app.js"
|
||||||
:main "env.ios.main"
|
:main "env.ios.main"
|
||||||
:output-dir "target/ios"
|
:output-dir "target/ios"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
:optimizations :none}
|
:optimizations :none}
|
||||||
:warning-handlers '[status-im.utils.build/warning-handler]}
|
:warning-handlers '[status-im.utils.build/warning-handler]}
|
||||||
:android
|
:android
|
||||||
{:source-paths ["components/src" "react-native/src" "src"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src"]
|
||||||
:compiler {:output-to "target/android/app.js"
|
:compiler {:output-to "target/android/app.js"
|
||||||
:main "env.android.main"
|
:main "env.android.main"
|
||||||
:output-dir "target/android"
|
:output-dir "target/android"
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
:prod
|
:prod
|
||||||
{:ios
|
{:ios
|
||||||
{:source-paths ["components/src" "react-native/src" "src" "env/prod"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src" "env/prod"]
|
||||||
:compiler {:output-to "index.ios.js"
|
:compiler {:output-to "index.ios.js"
|
||||||
:output-dir "target/ios-prod"
|
:output-dir "target/ios-prod"
|
||||||
:static-fns true
|
:static-fns true
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
:language-in :ecmascript5}
|
:language-in :ecmascript5}
|
||||||
:warning-handlers '[status-im.utils.build/warning-handler]}
|
:warning-handlers '[status-im.utils.build/warning-handler]}
|
||||||
:android
|
:android
|
||||||
{:source-paths ["components/src" "react-native/src" "src" "env/prod"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src" "env/prod"]
|
||||||
:compiler {:output-to "index.android.js"
|
:compiler {:output-to "index.android.js"
|
||||||
:output-dir "target/android-prod"
|
:output-dir "target/android-prod"
|
||||||
:static-fns true
|
:static-fns true
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
(def view (get-class "View"))
|
(def view (get-class "View"))
|
||||||
(def safe-area-view (get-class "SafeAreaView"))
|
(def safe-area-view (get-class "SafeAreaView"))
|
||||||
|
|
||||||
(def status-bar (get-class "StatusBar"))
|
(def status-bar (get-class (if platform/desktop? "View" "StatusBar")))
|
||||||
|
|
||||||
(def scroll-view (get-class "ScrollView"))
|
(def scroll-view (get-class "ScrollView"))
|
||||||
(def web-view (get-class "WebView"))
|
(def web-view (get-class "WebView"))
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
TESTFAIRY_ENABLED=0
|
||||||
|
STUB_STATUS_GO=0
|
||||||
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
|
MAINNET_NETWORKS_ENABLED=1
|
||||||
|
OFFLINE_INBOX_ENABLED=1
|
||||||
|
OFFLINE_INBOX_MANY_ENABLED=1
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
LOG_LEVEL_STATUS_GO=info
|
||||||
|
JSC_ENABLED=1
|
||||||
|
QUEUE_MESSAGE_ENABLED=1
|
||||||
|
MANY_WHISPER_TOPICS_ENABLED=0
|
||||||
|
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||||
|
COMPILE_VIEWS_ENABLED=0
|
||||||
|
POW_TARGET=0.002
|
||||||
|
POW_TIME=1
|
||||||
|
MIXPANEL_TOKEN=3f2e1a8970f159aa2a3d5dc5d65eab38
|
||||||
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
|
TESTFAIRY_TOKEN=969f6c921cb435cea1d41d1ea3f5b247d6026d55
|
||||||
|
INSTABUG_TOKEN=758630ed52864cbad9c5eeeac596c60c
|
|
@ -0,0 +1,7 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=StatusIm
|
||||||
|
Comment=StatusIm Desktop
|
||||||
|
Exec=StatusIm
|
||||||
|
Icon=StatusIm
|
||||||
|
Categories=Network;
|
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
2
deps.edn
2
deps.edn
|
@ -1,4 +1,4 @@
|
||||||
{:paths ["components/src" "src" "react-native/src" "resources"]
|
{:paths ["components/src" "src" "react-native/src/cljsjs" "react-native/src/mobile" "resources"]
|
||||||
:deps {org.clojure/clojure {:mvn/version "1.9.0"}
|
:deps {org.clojure/clojure {:mvn/version "1.9.0"}
|
||||||
org.clojure/clojurescript {:mvn/version "1.10.238"}
|
org.clojure/clojurescript {:mvn/version "1.10.238"}
|
||||||
org.clojure/core.async {:mvn/version "0.4.474"}
|
org.clojure/core.async {:mvn/version "0.4.474"}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
# Copyright (C) 2016, Canonical Ltd.
|
||||||
|
# All rights reserved.
|
||||||
|
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.8.11)
|
||||||
|
|
||||||
|
set(APP_NAME StatusIm)
|
||||||
|
set(REACT_BUILD_STATIC_LIB ON)
|
||||||
|
|
||||||
|
message(STATUS "EXTERNAL_MODULES_DIR: ${EXTERNAL_MODULES_DIR}")
|
||||||
|
|
||||||
|
foreach(external_module ${EXTERNAL_MODULES_DIR})
|
||||||
|
message(STATUS "external_module: ${external_module}")
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../${external_module} ${CMAKE_CURRENT_BINARY_DIR}/${external_module})
|
||||||
|
endforeach(external_module)
|
||||||
|
|
||||||
|
# APPLICATION_MAIN_CPP_PATH contains absolute path to generated template copy of main.cpp for application executable
|
||||||
|
get_filename_component(APPLICATION_MAIN_CPP_PATH main.cpp ABSOLUTE)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../node_modules/react-native/React/Layout)
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../node_modules/react-native/ReactQt/runtime/src ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../node_modules/react-native/ReactQt/application/src ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set(RUN_SCRIPT_FILE_NAME "run-app.bat")
|
||||||
|
else()
|
||||||
|
set(RUN_SCRIPT_FILE_NAME "run-app.sh")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
${RUN_SCRIPT_FILE_NAME}.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/${RUN_SCRIPT_FILE_NAME}
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
@rem Copyright (c) 2017-present, Status Research and Development GmbH.
|
||||||
|
@rem All rights reserved.
|
||||||
|
@rem
|
||||||
|
@rem This source code is licensed under the BSD-style license found in the
|
||||||
|
@rem LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
@rem of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
@echo off
|
||||||
|
setlocal EnableDelayedExpansion
|
||||||
|
|
||||||
|
set "option="
|
||||||
|
for %%a in (%*) do (
|
||||||
|
if not defined option (
|
||||||
|
set arg=%%a
|
||||||
|
if "!arg:~0,1!" equ "-" set "option=!arg!"
|
||||||
|
) else (
|
||||||
|
set "option!option!=%%a"
|
||||||
|
set "option="
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
SET option
|
||||||
|
@echo on
|
||||||
|
|
||||||
|
echo "build.bat external modules paths: "%option-e%
|
||||||
|
echo "build.bat JS bundle path: "%option-j%
|
||||||
|
echo "build.bat cmake generator: "%option-g%
|
||||||
|
|
||||||
|
@rem Workaround
|
||||||
|
@rem rm -rf CMakeFiles CMakeCache.txt cmake_install.cmake Makefile
|
||||||
|
|
||||||
|
@rem Build project
|
||||||
|
echo %CD%
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Debug -G %option-g% -DEXTERNAL_MODULES_DIR=%option-e% -DJS_BUNDLE_PATH=%option-j% . && cmake --build .
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (C) 2016, Canonical Ltd.
|
||||||
|
# All rights reserved.
|
||||||
|
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
# XXX: Don't move this script
|
||||||
|
cd $(dirname $0)
|
||||||
|
|
||||||
|
while (( "$#" )); do
|
||||||
|
if [[ $1 == "-e" ]]; then
|
||||||
|
shift
|
||||||
|
ExternalModulesPaths="$1"
|
||||||
|
fi
|
||||||
|
if [[ $1 == "-j" ]]; then
|
||||||
|
shift
|
||||||
|
JsBundlePath="$1"
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "build.sh external modules paths: "$ExternalModulesPaths
|
||||||
|
echo "build.sh JS bundle path: "$JsBundlePath
|
||||||
|
|
||||||
|
# Workaround
|
||||||
|
rm -rf CMakeFiles CMakeCache.txt cmake_install.cmake Makefile
|
||||||
|
|
||||||
|
# Build project
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Debug -DEXTERNAL_MODULES_DIR="$ExternalModulesPaths" -DJS_BUNDLE_PATH="$JsBundlePath" . && make
|
|
@ -0,0 +1,284 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2016, Canonical Ltd.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// #define BUILD_FOR_BUNDLE
|
||||||
|
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
#include "attachedproperties.h"
|
||||||
|
#include "reactitem.h"
|
||||||
|
#include "rootview.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
#ifdef BUILD_FOR_BUNDLE
|
||||||
|
QStringList consoleOutputStrings;
|
||||||
|
bool ubuntuServerStarted = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: some way to change while running
|
||||||
|
class ReactNativeProperties : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool liveReload READ liveReload WRITE setLiveReload NOTIFY
|
||||||
|
liveReloadChanged)
|
||||||
|
Q_PROPERTY(QUrl codeLocation READ codeLocation WRITE setCodeLocation NOTIFY
|
||||||
|
codeLocationChanged)
|
||||||
|
Q_PROPERTY(QString pluginsPath READ pluginsPath WRITE setPluginsPath NOTIFY
|
||||||
|
pluginsPathChanged)
|
||||||
|
Q_PROPERTY(
|
||||||
|
QString executor READ executor WRITE setExecutor NOTIFY executorChanged)
|
||||||
|
public:
|
||||||
|
ReactNativeProperties(QObject *parent = 0) : QObject(parent) {
|
||||||
|
m_codeLocation = m_packagerTemplate.arg(m_packagerHost).arg(m_packagerPort);
|
||||||
|
}
|
||||||
|
bool liveReload() const { return m_liveReload; }
|
||||||
|
void setLiveReload(bool liveReload) {
|
||||||
|
if (m_liveReload == liveReload)
|
||||||
|
return;
|
||||||
|
m_liveReload = liveReload;
|
||||||
|
Q_EMIT liveReloadChanged();
|
||||||
|
}
|
||||||
|
QUrl codeLocation() const { return m_codeLocation; }
|
||||||
|
void setCodeLocation(const QUrl &codeLocation) {
|
||||||
|
if (m_codeLocation == codeLocation)
|
||||||
|
return;
|
||||||
|
m_codeLocation = codeLocation;
|
||||||
|
Q_EMIT codeLocationChanged();
|
||||||
|
}
|
||||||
|
QString pluginsPath() const { return m_pluginsPath; }
|
||||||
|
void setPluginsPath(const QString &pluginsPath) {
|
||||||
|
if (m_pluginsPath == pluginsPath)
|
||||||
|
return;
|
||||||
|
m_pluginsPath = pluginsPath;
|
||||||
|
Q_EMIT pluginsPathChanged();
|
||||||
|
}
|
||||||
|
QString executor() const { return m_executor; }
|
||||||
|
void setExecutor(const QString &executor) {
|
||||||
|
if (m_executor == executor)
|
||||||
|
return;
|
||||||
|
m_executor = executor;
|
||||||
|
Q_EMIT executorChanged();
|
||||||
|
}
|
||||||
|
QString packagerHost() const { return m_packagerHost; }
|
||||||
|
void setPackagerHost(const QString &packagerHost) {
|
||||||
|
if (m_packagerHost == packagerHost)
|
||||||
|
return;
|
||||||
|
m_packagerHost = packagerHost;
|
||||||
|
setCodeLocation(m_packagerTemplate.arg(m_packagerHost).arg(m_packagerPort));
|
||||||
|
}
|
||||||
|
QString packagerPort() const { return m_packagerPort; }
|
||||||
|
void setPackagerPort(const QString &packagerPort) {
|
||||||
|
if (m_packagerPort == packagerPort)
|
||||||
|
return;
|
||||||
|
m_packagerPort = packagerPort;
|
||||||
|
setCodeLocation(m_packagerTemplate.arg(m_packagerHost).arg(m_packagerPort));
|
||||||
|
}
|
||||||
|
void setLocalSource(const QString &source) {
|
||||||
|
if (m_localSource == source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// overrides packager*
|
||||||
|
if (source.startsWith("file:")) {
|
||||||
|
setCodeLocation(source);
|
||||||
|
} else {
|
||||||
|
QFileInfo fi(source);
|
||||||
|
if (!fi.exists()) {
|
||||||
|
qWarning() << "Attempt to set non-existent local source file";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCodeLocation(QUrl::fromLocalFile(fi.absoluteFilePath()));
|
||||||
|
setLiveReload(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Q_SIGNALS:
|
||||||
|
void liveReloadChanged();
|
||||||
|
void codeLocationChanged();
|
||||||
|
void pluginsPathChanged();
|
||||||
|
void executorChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_liveReload = false;
|
||||||
|
QString m_packagerHost = "localhost";
|
||||||
|
QString m_packagerPort = "8081";
|
||||||
|
QString m_localSource;
|
||||||
|
QString m_packagerTemplate =
|
||||||
|
"http://%1:%2/index.desktop.bundle?platform=desktop&dev=true";
|
||||||
|
QUrl m_codeLocation;
|
||||||
|
QString m_pluginsPath;
|
||||||
|
#ifdef BUILD_FOR_BUNDLE
|
||||||
|
QString m_executor = "RemoteServerConnection";
|
||||||
|
#else
|
||||||
|
QString m_executor = "LocalServerConnection";
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BUILD_FOR_BUNDLE
|
||||||
|
void runUbuntuServer();
|
||||||
|
void saveMessage(QtMsgType type, const QMessageLogContext &context,
|
||||||
|
const QString &msg);
|
||||||
|
|
||||||
|
void writeLogsToFile();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
|
Q_INIT_RESOURCE(react_resources);
|
||||||
|
|
||||||
|
#ifdef BUILD_FOR_BUNDLE
|
||||||
|
QString dataFolder = QDir::homePath() + "/Library/StatusIm/";
|
||||||
|
qInstallMessageHandler(saveMessage);
|
||||||
|
|
||||||
|
QDir dir(dataFolder + "ethereum/mainnet_rpc");
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkpath(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
runUbuntuServer();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QQuickView view;
|
||||||
|
ReactNativeProperties *rnp = new ReactNativeProperties(&view);
|
||||||
|
#ifdef BUILD_FOR_BUNDLE
|
||||||
|
rnp->setCodeLocation("file:" + QGuiApplication::applicationDirPath() +
|
||||||
|
"/assets");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
utilities::registerReactTypes();
|
||||||
|
|
||||||
|
QCommandLineParser p;
|
||||||
|
p.setApplicationDescription("React Native host application");
|
||||||
|
p.addHelpOption();
|
||||||
|
p.addOptions({
|
||||||
|
{{"R", "live-reload"}, "Enable live reload."},
|
||||||
|
{{"H", "host"}, "Set packager host address.", rnp->packagerHost()},
|
||||||
|
{{"P", "port"}, "Set packager port number.", rnp->packagerPort()},
|
||||||
|
{{"L", "local"}, "Set path to the local packaged source", "not set"},
|
||||||
|
{{"M", "plugins-path"}, "Set path to node modules", "./plugins"},
|
||||||
|
{{"E", "executor"}, "Set Javascript executor", rnp->executor()},
|
||||||
|
});
|
||||||
|
p.process(app);
|
||||||
|
rnp->setLiveReload(p.isSet("live-reload"));
|
||||||
|
if (p.isSet("host"))
|
||||||
|
rnp->setPackagerHost(p.value("host"));
|
||||||
|
if (p.isSet("port"))
|
||||||
|
rnp->setPackagerPort(p.value("port"));
|
||||||
|
if (p.isSet("local"))
|
||||||
|
rnp->setLocalSource(p.value("local"));
|
||||||
|
if (p.isSet("plugins-path"))
|
||||||
|
rnp->setPluginsPath(p.value("plugins-path"));
|
||||||
|
if (p.isSet("executor"))
|
||||||
|
rnp->setExecutor(p.value("executor"));
|
||||||
|
|
||||||
|
view.rootContext()->setContextProperty("ReactNativeProperties", rnp);
|
||||||
|
view.setSource(QUrl("qrc:///main.qml"));
|
||||||
|
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
|
view.show();
|
||||||
|
|
||||||
|
#ifdef BUILD_FOR_BUNDLE
|
||||||
|
QTimer t;
|
||||||
|
t.setInterval(500);
|
||||||
|
QObject::connect(&t, &QTimer::timeout, [=]() { writeLogsToFile(); });
|
||||||
|
t.start();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_FOR_BUNDLE
|
||||||
|
|
||||||
|
void writeLogsToFile() {
|
||||||
|
QFile logFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/StatusIm.log");
|
||||||
|
if (logFile.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
||||||
|
for (QString message : consoleOutputStrings) {
|
||||||
|
logFile.write(message.toStdString().c_str());
|
||||||
|
}
|
||||||
|
consoleOutputStrings.clear();
|
||||||
|
|
||||||
|
logFile.flush();
|
||||||
|
logFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void runUbuntuServer() {
|
||||||
|
QProcess *process = new QProcess();
|
||||||
|
process->setProgram(QGuiApplication::applicationDirPath() + "/ubuntu-server");
|
||||||
|
QObject::connect(process, &QProcess::errorOccurred,
|
||||||
|
[=](QProcess::ProcessError) {
|
||||||
|
qDebug() << "process name: " << process->program();
|
||||||
|
qDebug() << "process error: " << process->errorString();
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(process, &QProcess::readyReadStandardOutput, [=] {
|
||||||
|
qDebug() << "ubuntu-server std: "
|
||||||
|
<< process->readAllStandardOutput().trimmed();
|
||||||
|
});
|
||||||
|
QObject::connect(process, &QProcess::readyReadStandardError, [=] {
|
||||||
|
QString output = process->readAllStandardError().trimmed();
|
||||||
|
qDebug() << "ubuntu-server err: " << output;
|
||||||
|
if (output.contains("Server starting")) {
|
||||||
|
ubuntuServerStarted = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(QGuiApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||||
|
[=]() {
|
||||||
|
qDebug() << "Kill ubuntu server";
|
||||||
|
process->kill();
|
||||||
|
});
|
||||||
|
|
||||||
|
qDebug() << "starting ubuntu server...";
|
||||||
|
process->start();
|
||||||
|
qDebug() << "wait for started...";
|
||||||
|
|
||||||
|
while (!ubuntuServerStarted) {
|
||||||
|
QGuiApplication::processEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "waiting finished";
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveMessage(QtMsgType type, const QMessageLogContext &context,
|
||||||
|
const QString &msg) {
|
||||||
|
|
||||||
|
QByteArray localMsg = msg.toLocal8Bit();
|
||||||
|
QString message = localMsg + "\n";
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg:
|
||||||
|
consoleOutputStrings << "Debug: " << message << "\n";
|
||||||
|
break;
|
||||||
|
case QtInfoMsg:
|
||||||
|
consoleOutputStrings << "Info: " << message << "\n";
|
||||||
|
break;
|
||||||
|
case QtWarningMsg:
|
||||||
|
consoleOutputStrings << "Warning: " << message << "\n";
|
||||||
|
break;
|
||||||
|
case QtCriticalMsg:
|
||||||
|
consoleOutputStrings << "Critical: " << message << "\n";
|
||||||
|
break;
|
||||||
|
case QtFatalMsg:
|
||||||
|
|
||||||
|
consoleOutputStrings << "Fatal: " << message << "\n";
|
||||||
|
writeLogsToFile();
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "main.moc"
|
|
@ -0,0 +1,11 @@
|
||||||
|
@rem Copyright (c) 2017-present, Status Research and Development GmbH.
|
||||||
|
@rem All rights reserved.
|
||||||
|
@rem
|
||||||
|
@rem This source code is licensed under the BSD-style license found in the
|
||||||
|
@rem LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
@rem of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
|
||||||
|
@rem Run app locally
|
||||||
|
@CMAKE_BINARY_DIR@/bin/@APP_NAME@
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (C) 2016, Canonical Ltd.
|
||||||
|
# All rights reserved.
|
||||||
|
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
args=""
|
||||||
|
on_device=0
|
||||||
|
plugins_path=""
|
||||||
|
asset_path="share"
|
||||||
|
executor=""
|
||||||
|
|
||||||
|
react_host=`hostname -I`
|
||||||
|
|
||||||
|
# Parse args
|
||||||
|
for arg in "$@"
|
||||||
|
do
|
||||||
|
IFS="=" read -a parts <<< "$arg"
|
||||||
|
if [[ $parts == "--on-device" ]]; then
|
||||||
|
on_device=1
|
||||||
|
elif [[ $parts == "--plugins-path" ]]; then
|
||||||
|
plugins_path=${parts[1]}
|
||||||
|
args=$args" --plugins-path=./plugins"
|
||||||
|
elif [[ $parts == "--asset-path" ]]; then
|
||||||
|
asset_path=${parts[1]}
|
||||||
|
elif [[ $parts == "--executor" ]]; then
|
||||||
|
if [[ $on_device == 1 ]]; then
|
||||||
|
# Force net executor for now
|
||||||
|
executor="ReactNetExecutor"
|
||||||
|
else
|
||||||
|
executor=${parts[1]}
|
||||||
|
fi
|
||||||
|
args=$args" --executor=$executor"
|
||||||
|
else
|
||||||
|
args=$args" $parts"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Handle defaults
|
||||||
|
if [[ -z "$executor" ]]; then
|
||||||
|
if [[ $on_device == 1 ]]; then
|
||||||
|
executor="ReactNetExecutor"
|
||||||
|
args=$args" --executor=ReactNetExecutor"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The RN application selects pipe executor by default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For net case, try and run executor; it is probably OK if this fails - it's
|
||||||
|
# just running elsewhere
|
||||||
|
if [[ "$executor" == "ReactNetExecutor" ]]; then
|
||||||
|
(node @CMAKE_BINARY_DIR@/bin/ubuntu-server.js 2>&1 > /dev/null) &
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $on_device == 1 ]]; then
|
||||||
|
app_path="/home/phablet/@APP_NAME@"
|
||||||
|
|
||||||
|
# Push binaries
|
||||||
|
adb push @CMAKE_BINARY_DIR@/bin/@APP_NAME@ "$app_path/@APP_NAME@"
|
||||||
|
[ -d "$plugins_path" ] && adb push "$plugins_path" "$app_path/plugins/"
|
||||||
|
[ -d "$asset_path" ] && adb push "$asset_path" "$app_path/share/"
|
||||||
|
# adb reverse --no-rebind tcp:8081 tcp:808
|
||||||
|
|
||||||
|
# Run app on device
|
||||||
|
adb shell "cd $app_path && REACT_SERVER_HOST=$react_host ./@APP_NAME@ --host $react_host $args -- --desktop_file_hint=/usr/share/applications/webbrowser-app.desktop"
|
||||||
|
else
|
||||||
|
# Run app locally
|
||||||
|
@CMAKE_BINARY_DIR@/bin/@APP_NAME@ $args
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
"name": "StatusIm",
|
||||||
|
"interface": "reagent",
|
||||||
|
"platforms": {
|
||||||
|
"ios": {
|
||||||
|
"host": "localhost",
|
||||||
|
"modules": [
|
||||||
|
"react-native-image-resizer",
|
||||||
|
"react-native-camera",
|
||||||
|
"instabug-reactnative",
|
||||||
|
"nfc-react-native",
|
||||||
|
"react-native-background-timer",
|
||||||
|
"react-native-testfairy"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"android": {
|
||||||
|
"host": "10.0.2.2",
|
||||||
|
"modules": [
|
||||||
|
"react-native-image-resizer",
|
||||||
|
"react-native-camera",
|
||||||
|
"instabug-reactnative",
|
||||||
|
"nfc-react-native",
|
||||||
|
"react-native-background-timer",
|
||||||
|
"react-native-testfairy"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"desktop": {
|
||||||
|
"host": "localhost",
|
||||||
|
"modules": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
"realm",
|
||||||
|
"react-native-i18n",
|
||||||
|
"realm/react-native",
|
||||||
|
"dismissKeyboard",
|
||||||
|
"react-native-splash-screen",
|
||||||
|
"react-native-status",
|
||||||
|
"react-native-qrcode",
|
||||||
|
"identicon.js",
|
||||||
|
"react-native-fs",
|
||||||
|
"react-native-dialogs",
|
||||||
|
"react-native-image-crop-picker",
|
||||||
|
"react-native-securerandom",
|
||||||
|
"react-native-webview-bridge",
|
||||||
|
"react-native-fcm",
|
||||||
|
"homoglyph-finder",
|
||||||
|
"web3",
|
||||||
|
"chance",
|
||||||
|
"react-native-http-bridge",
|
||||||
|
"emojilib",
|
||||||
|
"react-native-config",
|
||||||
|
"react-native-svg",
|
||||||
|
"react-native-keychain",
|
||||||
|
"rn-snoopy",
|
||||||
|
"rn-snoopy/stream/bars",
|
||||||
|
"rn-snoopy/stream/filter",
|
||||||
|
"rn-snoopy/stream/buffer",
|
||||||
|
"react-native/Libraries/vendor/emitter/EventEmitter",
|
||||||
|
"react-native-fetch-polyfill"
|
||||||
|
],
|
||||||
|
"imageDirs": [
|
||||||
|
"resources/images",
|
||||||
|
"resources/icons"
|
||||||
|
],
|
||||||
|
"envRoots": {
|
||||||
|
"dev": "env/dev",
|
||||||
|
"prod": "env/prod"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
0.0.1
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"name": "StatusIm",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"start": "node node_modules/react-native/local-cli/cli.js start",
|
||||||
|
"prepare": "patch-package"
|
||||||
|
},
|
||||||
|
"desktopExternalModules": [
|
||||||
|
"node_modules/react-native-i18n/desktop",
|
||||||
|
"node_modules/react-native-config/desktop",
|
||||||
|
"node_modules/react-native-fs/desktop",
|
||||||
|
"node_modules/react-native-http-bridge/desktop",
|
||||||
|
"node_modules/react-native-webview-bridge/desktop",
|
||||||
|
"node_modules/react-native-keychain/desktop",
|
||||||
|
"node_modules/react-native-securerandom/desktop",
|
||||||
|
"modules/react-native-status/desktop"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"assert": "1.4.1",
|
||||||
|
"asyncstorage-down": "4.0.1",
|
||||||
|
"babel-core": "6.24.1",
|
||||||
|
"babel-generator": "6.24.1",
|
||||||
|
"babel-helper-builder-react-jsx": "6.18.0",
|
||||||
|
"babel-plugin-transform-es2015-block-scoping": "6.15.0",
|
||||||
|
"babel-preset-react-native": "4.0.0",
|
||||||
|
"babel-register": "6.18.0",
|
||||||
|
"bignumber.js": "github:status-im/bignumber.js#master",
|
||||||
|
"buffer": "3.6.0",
|
||||||
|
"chance": "1.0.12",
|
||||||
|
"create-react-class": "15.6.2",
|
||||||
|
"dns.js": "1.0.1",
|
||||||
|
"emojilib": "2.2.9",
|
||||||
|
"events": "1.1.1",
|
||||||
|
"homoglyph-finder": "1.1.1",
|
||||||
|
"identicon.js": "github:status-im/identicon.js",
|
||||||
|
"instabug-reactnative": "2.12.0",
|
||||||
|
"level-filesystem": "1.2.0",
|
||||||
|
"metro": "^0.30.2",
|
||||||
|
"nfc-react-native": "github:status-im/nfc-react-native",
|
||||||
|
"process": "0.11.10",
|
||||||
|
"prop-types": "15.6.0",
|
||||||
|
"punycode": "1.4.1",
|
||||||
|
"querystring-es3": "0.2.1",
|
||||||
|
"re-natal": "git+https://github.com/status-im/re-natal.git#master",
|
||||||
|
"react": "16.3.1",
|
||||||
|
"react-dom": "16.3.1",
|
||||||
|
"react-native": "git+https://github.com/status-im/react-native-desktop.git",
|
||||||
|
"react-native-background-timer": "2.0.0",
|
||||||
|
"react-native-camera": "0.10.0",
|
||||||
|
"react-native-config": "git+https://github.com/status-im/react-native-config.git",
|
||||||
|
"react-native-crypto": "2.1.1",
|
||||||
|
"react-native-dialogs": "0.0.20",
|
||||||
|
"react-native-fcm": "10.0.3",
|
||||||
|
"react-native-fetch-polyfill": "1.1.2",
|
||||||
|
"react-native-fs": "git+https://github.com/status-im/react-native-fs.git",
|
||||||
|
"react-native-http": "github:tradle/react-native-http#834492d",
|
||||||
|
"react-native-http-bridge": "git+https://github.com/status-im/react-native-http-bridge.git#desktop",
|
||||||
|
"react-native-i18n": "git+https://github.com/status-im/react-native-i18n.git#version_0.0.8_desktop",
|
||||||
|
"react-native-image-crop-picker": "0.18.1",
|
||||||
|
"react-native-image-resizer": "1.0.0",
|
||||||
|
"react-native-invertible-scroll-view": "1.1.0",
|
||||||
|
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git",
|
||||||
|
"react-native-level-fs": "3.0.0",
|
||||||
|
"react-native-os": "1.1.0",
|
||||||
|
"react-native-qrcode": "0.2.6",
|
||||||
|
"react-native-securerandom": "git+https://github.com/status-im/react-native-securerandom.git",
|
||||||
|
"react-native-splash-screen": "3.0.6",
|
||||||
|
"react-native-svg": "6.3.1",
|
||||||
|
"react-native-tcp": "3.3.0",
|
||||||
|
"react-native-testfairy": "2.10.0",
|
||||||
|
"react-native-udp": "2.2.1",
|
||||||
|
"react-native-webview-bridge": "github:status-im/react-native-webview-bridge#react-native-0.49-desktop",
|
||||||
|
"realm": "git+https://github.com/status-im/realm-js.git",
|
||||||
|
"rn-snoopy": "github:status-im/rn-snoopy",
|
||||||
|
"string_decoder": "0.10.31",
|
||||||
|
"url": "0.10.3",
|
||||||
|
"web3": "github:status-im/web3.js#feature/shhext"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"patch-package": "^5.1.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
# Prerequisites:
|
||||||
|
lein, node.js v.8 , cmake, Qt 5.9.1 (with QtWebEngine components installed), Qt's qmake available in PATH
|
||||||
|
|
||||||
|
Note: add qmake to PATH via
|
||||||
|
`export PATH=<QT_PATH>/clang_64/bin:$PATH`
|
||||||
|
|
||||||
|
Caveats:
|
||||||
|
- if npm hangs at some step, check the version. If it's 5.6.0, try downgrading to 5.5.1 via `npm install -g npm@5.5.1`
|
||||||
|
|
||||||
|
# To install react-native-cli with desktop commands support:
|
||||||
|
1. git clone https://github.com/status-im/react-native-desktop.git
|
||||||
|
2. cd react-native-desktop/react-native-cli
|
||||||
|
3. npm update
|
||||||
|
4. npm install -g
|
||||||
|
|
||||||
|
# To setup re-natal dev builds of status-react for Desktop:
|
||||||
|
1. git clone https://github.com/status-im/status-react.git
|
||||||
|
2. cd status-react
|
||||||
|
3. git checkout desktop
|
||||||
|
4. npm install
|
||||||
|
5. lein deps
|
||||||
|
6. ./re-natal use-figwheel
|
||||||
|
7. ./re-natal enable-source-maps
|
||||||
|
8. In separate terminal tab: `npm start` (note: it starts react-native packager )
|
||||||
|
9. In separate terminal tab: node ./ubuntu-server.js
|
||||||
|
10. In separate terminal tab: lein figwheel-repl desktop (note: wait until sources compiled)
|
||||||
|
11. In separate terminal tab: react-native run-desktop
|
||||||
|
|
||||||
|
# Editor setup
|
||||||
|
Running `lein figwheel-repl desktop` will run a REPL on port 7888 by default. Some additional steps might be needed to connect to it.
|
||||||
|
|
||||||
|
## emacs-cider
|
||||||
|
In order to get REPL working, use the below elisp code:
|
||||||
|
```
|
||||||
|
(defun custom-cider-jack-in ()
|
||||||
|
(interactive)
|
||||||
|
(let ((status-desktop-params "with-profile +figwheel repl"))
|
||||||
|
(set-variable 'cider-lein-parameters status-desktop-params)
|
||||||
|
(message "setting 'cider-lein-parameters")
|
||||||
|
(cider-jack-in)))
|
||||||
|
|
||||||
|
(defun start-figwheel-cljs-repl ()
|
||||||
|
(interactive)
|
||||||
|
(set-buffer "*cider-repl status-react*")
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert "(do (use 'figwheel-api)
|
||||||
|
(start [:desktop])
|
||||||
|
(start-cljs-repl))")
|
||||||
|
(cider-repl-return))
|
||||||
|
```
|
||||||
|
|
||||||
|
`custom-cider-jack-in` sets the correct profile for leiningen, and can be run as soon as emacs is open.
|
||||||
|
run `start-figwheel-cljs-repl` once you already have a cider repl session from the jack-in
|
||||||
|
|
||||||
|
## vim-fireplace
|
||||||
|
For some reason there is no `.nrepl-port` file in project root, so `vim-fireplace` will not be able to connect automatically. You can either:
|
||||||
|
- run `:Connect` and answer a couple of interactive prompts
|
||||||
|
- create `.nrepl-port` file manually and add a single line containing `7888` (or whatever port REPL is running on)
|
||||||
|
|
||||||
|
After Figwheel has connected to the app, run `:Piggieback (figwheel-sidecar.repl-api/repl-env)` inside Vim, and you should be all set.
|
|
@ -0,0 +1,136 @@
|
||||||
|
These are some common issues you may run into while setting up React Native Qt.
|
||||||
|
|
||||||
|
## Initial setup issues
|
||||||
|
|
||||||
|
### `npm install` hangs
|
||||||
|
Downgrade to version 5.5.1: `npm install -g npm@5.5.1`.
|
||||||
|
|
||||||
|
### `re-natal` missing
|
||||||
|
Create a link:
|
||||||
|
`ln -sf node_modules/re-natal/index.js re-natal`
|
||||||
|
|
||||||
|
|
||||||
|
### `react-native run desktop` complaining about missing `qmldir`:
|
||||||
|
```Command failed: ./build.sh -e "node_modules/react-native-i18n/desktop;node_modules/react-native-config/desktop;node_modules/react-native-fs/desktop;node_modules/react-native-http-bridge/desktop;node_modules/react-native-webview-bridge/desktop;modules/react-native-status/desktop"
|
||||||
|
Error copying directory from "/path-to-status-react/node_modules/react-native/ReactQt/runtime/src/qmldir" to "/path-to-status-react/desktop/lib/React".
|
||||||
|
make[2]: *** [lib/CMakeFiles/copy-qmldir] Error 1
|
||||||
|
make[1]: *** [lib/CMakeFiles/copy-qmldir.dir/all] Error 2
|
||||||
|
make: *** [all] Error 2
|
||||||
|
```
|
||||||
|
Can be solved by re-running `npm install react-native` which put the `ReactQt/runtime/src/qmldir` file back.
|
||||||
|
|
||||||
|
### Missing web3 package issue
|
||||||
|
|
||||||
|
After last upgrade of react-native-desktop to the v.0.53.3 of original react-native appeared some incompatibility between `react-native` and `web3` packages on npm install. Initially it installed usually fine, but after `react-native desktop` command execution `web3` package is get removed from `node_modules`. Manual install of web3 by `npm install web3` installs `web3` package, but removes `react-native` package. Workaround or solution?
|
||||||
|
|
||||||
|
### Go problem
|
||||||
|
```
|
||||||
|
panic: runloop has just unexpectedly stopped
|
||||||
|
|
||||||
|
goroutine 50 [running]:
|
||||||
|
github.com/status-im/status-go/vendor/github.com/rjeczalik/notify.init.0.func1()
|
||||||
|
/path-to-status-react/desktop/modules/react-native-status/desktop/StatusGo/src/github.com/status-im/status-go/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:69 +0x79
|
||||||
|
created by github.com/status-im/status-go/vendor/github.com/rjeczalik/notify.init.0
|
||||||
|
/path-to-status-react/desktop/modules/react-native-status/desktop/StatusGo/src/github.com/status-im/status-go/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:65 +0x4e
|
||||||
|
events.js:183
|
||||||
|
throw er; // Unhandled 'error' event
|
||||||
|
```
|
||||||
|
Related to https://github.com/rjeczalik/notify/issues/139. Solution: re-run.
|
||||||
|
|
||||||
|
## App issues
|
||||||
|
|
||||||
|
### Eth node crashing
|
||||||
|
`node ./ubuntu_server.js` log:
|
||||||
|
```
|
||||||
|
DEBUG [status-im.utils.handlers:36] - Handling re-frame event: :signal-event {"type":"node.crashed","event":{"error":"node is already running"}}
|
||||||
|
DEBUG [status-im.ui.screens.events:350] - :event-str {"type":"node.crashed","event":{"error":"node is already running"}}
|
||||||
|
DEBUG [status-im.utils.instabug:8] - Signal event: {"type":"node.crashed","event":{"error":"node is already running"}}
|
||||||
|
DEBUG [status-im.ui.screens.events:362] - Event node.crashed not handled
|
||||||
|
```
|
||||||
|
Solution: prevent starting Ethereum local node when there is an instance already running.
|
||||||
|
|
||||||
|
### Reload JS - blank screen
|
||||||
|
Console log for `react-native run-desktop` shows error 533.
|
||||||
|
Solution: reload again. Still, might hang at `Signing you in...` step (due to node attempted to be restarted). Re-run Figwheel and `react-native run-desktop`
|
||||||
|
|
||||||
|
### ReactButton.qml non-existent property "elide" error upon startup
|
||||||
|
```
|
||||||
|
qrc:/qml/ReactButton.qml:33: Error: Cannot assign to non-existent property "elide"
|
||||||
|
"Component for qrc:/qml/ReactWebView.qml is not loaded"
|
||||||
|
QQmlComponent: Component is not ready
|
||||||
|
"Unable to construct item from component qrc:/qml/ReactWebView.qml"
|
||||||
|
"Can't create QML item for componenet qrc:/qml/ReactWebView.qml"
|
||||||
|
"RCTWebViewView" has no view for inspecting!
|
||||||
|
```
|
||||||
|
Reload JS does not help, restarting Figwheel/react-native might not as well. Restarting Metro bundler solved it for me.
|
||||||
|
|
||||||
|
### After login when several contacts are available: realm errors
|
||||||
|
1. `attempting to create an object of type 'chat'...`
|
||||||
|
2. `attempting to create an object of type 'transport'...`
|
||||||
|
3. Error text containing only the public key.
|
||||||
|
The realm stack trace follows.
|
||||||
|
|
||||||
|
### Error: spawn gnome-terminal ENOENT
|
||||||
|
In node server log:
|
||||||
|
```
|
||||||
|
ignoring exception: Error: read ECONNRESET
|
||||||
|
```
|
||||||
|
In react-native log:
|
||||||
|
```
|
||||||
|
./run-app.sh: line 72: 56660 Segmentation fault: 11 /path-to-status-react/desktop/bin/StatusIm $args
|
||||||
|
events.js:183
|
||||||
|
throw er; // Unhandled 'error' event
|
||||||
|
^
|
||||||
|
|
||||||
|
Error: spawn gnome-terminal ENOENT
|
||||||
|
at _errnoException (util.js:992:11)
|
||||||
|
at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
|
||||||
|
at onErrorNT (internal/child_process.js:372:16)
|
||||||
|
at _combinedTickCallback (internal/process/next_tick.js:138:11)
|
||||||
|
at process._tickCallback (internal/process/next_tick.js:180:9)
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```
|
||||||
|
StatusIm(7924,0x70000c1cd000) malloc: *** error for object 0x7f8b1539bd10: incorrect checksum for freed object - object was probably modified after being freed.
|
||||||
|
*** set a breakpoint in malloc_error_break to debug
|
||||||
|
./run-app.sh: line 72: 7924 Abort trap: 6 /path-to-status-react/desktop/bin/StatusIm $args
|
||||||
|
events.js:183
|
||||||
|
throw er; // Unhandled 'error' event
|
||||||
|
^
|
||||||
|
|
||||||
|
Error: spawn gnome-terminal ENOENT
|
||||||
|
at _errnoException (util.js:992:11)
|
||||||
|
at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
|
||||||
|
at onErrorNT (internal/child_process.js:372:16)
|
||||||
|
at _combinedTickCallback (internal/process/next_tick.js:138:11)
|
||||||
|
at process._tickCallback (internal/process/next_tick.js:180:9)
|
||||||
|
```
|
||||||
|
|
||||||
|
### statusgo error during `react-native run-desktop`
|
||||||
|
|
||||||
|
```
|
||||||
|
Command failed: build(.)sh -e "node_modules/react-native-i18n/desktop;node_modules/react-native-config/desktop;node_modules/react-native-fs/desktop;node_modules/react-native-http-bridge/desktop;node_modules/react-native-webview-bridge/desktop;modules/react-native-status/desktop"
|
||||||
|
# github.com/status-im/status-go/vendor/github.com/ethereum/go-ethereum/crypto/bn256
|
||||||
|
../vendor/github.com/ethereum/go-ethereum/crypto/bn256/bn256_fast.go:26: syntax error: unexpected = in type declaration
|
||||||
|
../vendor/github.com/ethereum/go-ethereum/crypto/bn256/bn256_fast.go:30: syntax error: unexpected = in type declaration
|
||||||
|
# github.com/status-im/status-go/vendor/github.com/ethereum/go-ethereum/crypto/bn256
|
||||||
|
vendor/github.com/ethereum/go-ethereum/crypto/bn256/bn256_fast.go:26: syntax error: unexpected = in type declaration
|
||||||
|
vendor/github.com/ethereum/go-ethereum/crypto/bn256/bn256_fast.go:30: syntax error: unexpected = in type declaration
|
||||||
|
make[3]: *** [statusgo-library] Error 2
|
||||||
|
make[2]: *** [modules/react-native-status/desktop/StatusGo/src/github.com/status-im/src/StatusGo_ep-stamp/StatusGo_ep-configure] Error 2
|
||||||
|
make[1]: *** [modules/react-native-status/desktop/CMakeFiles/StatusGo_ep(.)dir/all] Error 2
|
||||||
|
make: *** [all] Error 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### inotify errors
|
||||||
|
|
||||||
|
upon running `npm start` on linux, watchman may indicate: "The user limit on the total number of inotify watches was reached"
|
||||||
|
|
||||||
|
This can be fixed by running the below command. Note, changes will only be as valid as the current terminal session.
|
||||||
|
|
||||||
|
```
|
||||||
|
echo 999999 | sudo tee -a /proc/sys/fs/inotify/max_user_watches && echo 999999 | sudo tee -a
|
||||||
|
/proc/sys/fs/inotify/max_queued_events && echo 999999 | sudo tee -a /proc/sys/fs/inotify/max_user_instances &&
|
||||||
|
watchman shutdown-server && sudo sysctl -p
|
||||||
|
```
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns env.config)
|
(ns env.config)
|
||||||
|
|
||||||
|
|
||||||
(def figwheel-urls {:android "ws://192.168.10.203:3449/figwheel-ws",
|
(def figwheel-urls {:android "ws://192.168.10.203:3449/figwheel-ws",
|
||||||
:ios "ws://localhost:3449/figwheel-ws"}
|
:ios "ws://localhost:3449/figwheel-ws",
|
||||||
)
|
:desktop "ws://localhost:3449/figwheel-ws"})
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
;; Do not delete, root-el is used by the figwheel-bridge.js
|
;; Do not delete, root-el is used by the figwheel-bridge.js
|
||||||
(def root-el (r/as-element [reloader]))
|
(def root-el (r/as-element [reloader]))
|
||||||
|
|
||||||
(figwheel/start {:websocket-url (:ios conf/figwheel-urls)
|
(figwheel/start {:websocket-url (:desktop conf/figwheel-urls)
|
||||||
:heads-up-display false
|
:heads-up-display false
|
||||||
:jsload-callback #(swap! cnt inc)})
|
:jsload-callback #(swap! cnt inc)})
|
||||||
|
|
||||||
(utils.handlers/add-pre-event-callback rr/pre-event-callback)
|
(utils.handlers/add-pre-event-callback rr/pre-event-callback)
|
||||||
|
|
||||||
(rr/enable-re-frisk-remote! {:host (env.utils/re-frisk-url (:ios conf/figwheel-urls))
|
(rr/enable-re-frisk-remote! {:host (env.utils/re-frisk-url (:desktop conf/figwheel-urls))
|
||||||
:on-init core/init})
|
:on-init core/init})
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
(defn system-options [builds-to-start]
|
(defn system-options [builds-to-start]
|
||||||
{:nrepl-port 7888
|
{:nrepl-port 7888
|
||||||
:builds [{:id :desktop
|
:builds [{:id :desktop
|
||||||
:source-paths ["react-native/src" "src" "env/dev"]
|
:source-paths ["react-native/src/cljsjs" "react-native/src/desktop" "src" "env/dev"]
|
||||||
:compiler {:output-to "target/ios/desktop.js"
|
:compiler {:output-to "target/desktop/app.js"
|
||||||
:main "env.desktop.main"
|
:main "env.desktop.main"
|
||||||
:output-dir "target/desktop"
|
:output-dir "target/desktop"
|
||||||
:npm-deps false
|
:npm-deps false
|
||||||
:optimizations :none}
|
:optimizations :none}
|
||||||
:figwheel true}
|
:figwheel true}
|
||||||
{:id :ios
|
{:id :ios
|
||||||
:source-paths ["react-native/src" "src" "env/dev"]
|
:source-paths ["react-native/src/cljsjs" "react-native/src/mobile" "src" "env/dev"]
|
||||||
:compiler {:output-to "target/ios/app.js"
|
:compiler {:output-to "target/ios/app.js"
|
||||||
:main "env.ios.main"
|
:main "env.ios.main"
|
||||||
:output-dir "target/ios"
|
:output-dir "target/ios"
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
:optimizations :none}
|
:optimizations :none}
|
||||||
:figwheel true}
|
:figwheel true}
|
||||||
{:id :android
|
{:id :android
|
||||||
:source-paths ["react-native/src" "src" "env/dev"]
|
:source-paths ["react-native/src/cljsjs" "react-native/src/mobile" "src" "env/dev"]
|
||||||
:compiler {:output-to "target/android/app.js"
|
:compiler {:output-to "target/android/app.js"
|
||||||
:main "env.android.main"
|
:main "env.android.main"
|
||||||
:output-dir "target/android"
|
:output-dir "target/android"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
(ns env.desktop.main
|
||||||
|
(:require [status-im.desktop.core :as core]))
|
||||||
|
|
||||||
|
(core/init)
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CLOSURE_UNCOMPILED_DEFINES = null;
|
var CLOSURE_UNCOMPILED_DEFINES = null;
|
||||||
var debugEnabled = false;
|
var debugEnabled = true;
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
basePath: "target/",
|
basePath: "target/",
|
||||||
|
@ -47,7 +47,7 @@ function formatCompileError(msg) {
|
||||||
return errorStr;
|
return errorStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is simply demonstrating that we can receive and react to
|
/* This is simply demonstrating that we can receive and react to
|
||||||
* arbitrary messages from Figwheel this will enable creating a nicer
|
* arbitrary messages from Figwheel this will enable creating a nicer
|
||||||
* feedback system in the Figwheel top level React component.
|
* feedback system in the Figwheel top level React component.
|
||||||
*/
|
*/
|
||||||
|
@ -103,27 +103,35 @@ var isChrome = function () {
|
||||||
return typeof importScripts === "function"
|
return typeof importScripts === "function"
|
||||||
};
|
};
|
||||||
|
|
||||||
function asyncImportScripts(url, success, error) {
|
async function getUrlText(url) {
|
||||||
logDebug('(asyncImportScripts) Importing: ' + url);
|
const text = await fetch(url).then(response => {
|
||||||
asyncImportChain =
|
if(!response.ok) {
|
||||||
asyncImportChain
|
throw new Error("Failed to Fetch: " + url + " - Perhaps your project was cleaned and you haven't recompiled?");
|
||||||
.then(function (v) {return fetch(url);})
|
}
|
||||||
.then(function (response) {
|
return response.text()
|
||||||
if(response.ok)
|
});
|
||||||
return response.text();
|
return text;
|
||||||
throw new Error("Failed to Fetch: " + url + " - Perhaps your project was cleaned and you haven't recompiled?")
|
}
|
||||||
})
|
|
||||||
.then(function (responseText) {
|
var ATTEMPTS_COUNT = 3;
|
||||||
evaluate(responseText);
|
async function asyncImportScripts(url, success, error) {
|
||||||
fireEvalListenters(url);
|
|
||||||
success();
|
var attempt = 0;
|
||||||
return true;
|
var text = await getUrlText(url);
|
||||||
})
|
|
||||||
.catch(function (e) {
|
while(attempt < ATTEMPTS_COUNT && text.length === 0)
|
||||||
console.error(e);
|
{
|
||||||
error();
|
text = await getUrlText(url);
|
||||||
return true;
|
++attempt;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if(!text || 0 === text.length) {
|
||||||
|
console.log("Can't fetch file: ", url)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
evaluate(text);
|
||||||
|
fireEvalListenters(url);
|
||||||
|
success();
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncImportScripts(url, success, error) {
|
function syncImportScripts(url, success, error) {
|
||||||
|
@ -147,7 +155,7 @@ function importJs(src, success, error) {
|
||||||
if (isChrome()) {
|
if (isChrome()) {
|
||||||
syncImportScripts(src, success, error);
|
syncImportScripts(src, success, error);
|
||||||
} else {
|
} else {
|
||||||
asyncImportScripts(src, success, error);
|
asyncImportChain = asyncImportChain.then(function (v) {return asyncImportScripts(src, success, error);})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,64 @@
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
find_package(Go REQUIRED)
|
||||||
|
|
||||||
|
set(REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_TYPE_NAMES ${REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_TYPE_NAMES}
|
||||||
|
\"RCTStatus\" PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_SRC ${REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_SRC}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/rctstatus.cpp PARENT_SCOPE)
|
||||||
|
|
||||||
|
include(${CMAKE_ROOT}/Modules/ExternalProject.cmake)
|
||||||
|
|
||||||
|
if (WIN32 AND NOT CUSTOM_STATUSGO_BUILD_DIR_PATH)
|
||||||
|
set(CUSTOM_STATUSGO_BUILD_DIR_PATH "C:/srd-build/StatusGo")
|
||||||
|
endif()
|
||||||
|
if (CUSTOM_STATUSGO_BUILD_DIR_PATH)
|
||||||
|
set(StatusGo_ROOT ${CUSTOM_STATUSGO_BUILD_DIR_PATH})
|
||||||
|
else()
|
||||||
|
set(StatusGo_ROOT "${CMAKE_CURRENT_BINARY_DIR}/StatusGo")
|
||||||
|
endif()
|
||||||
|
set(StatusGo_PREFIX "${StatusGo_ROOT}/src/github.com/status-im")
|
||||||
|
set(StatusGo_SOURCE_DIR "${StatusGo_PREFIX}/status-go")
|
||||||
|
set(StatusGo_INCLUDE_DIR "${StatusGo_SOURCE_DIR}/build/bin")
|
||||||
|
set(StatusGo_STATIC_LIB
|
||||||
|
"${StatusGo_SOURCE_DIR}/build/bin/${CMAKE_STATIC_LIBRARY_PREFIX}status${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
|
||||||
|
include_directories(${StatusGo_INCLUDE_DIR})
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set(CONFIGURE_SCRIPT build-status-go.bat)
|
||||||
|
else()
|
||||||
|
set(CONFIGURE_SCRIPT build-status-go.sh)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ExternalProject_Add(StatusGo_ep
|
||||||
|
PREFIX ${StatusGo_PREFIX}
|
||||||
|
SOURCE_DIR ${StatusGo_SOURCE_DIR}
|
||||||
|
GIT_REPOSITORY https://github.com/status-im/status-go.git
|
||||||
|
GIT_TAG origin/develop
|
||||||
|
BUILD_BYPRODUCTS ${StatusGo_STATIC_LIB}
|
||||||
|
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/${CONFIGURE_SCRIPT} ${GO_ROOT_PATH} ${StatusGo_ROOT} ${StatusGo_SOURCE_DIR}
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
)
|
||||||
|
|
||||||
|
set(REACT_NATIVE_DESKTOP_EXTERNAL_PROJECT_DEPS ${REACT_NATIVE_DESKTOP_EXTERNAL_PROJECT_DEPS} StatusGo_ep PARENT_SCOPE)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
set(STATUSGO_DEPS_LIBS "-framework Foundation"
|
||||||
|
"-framework CoreServices"
|
||||||
|
"-framework IOKit"
|
||||||
|
"-framework Security" pthread)
|
||||||
|
elseif (WIN32)
|
||||||
|
set(STATUSGO_DEPS_LIBS -lWinMM -lWS2_32 -lsetupapi)
|
||||||
|
else()
|
||||||
|
set(STATUSGO_DEPS_LIBS pthread)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_LIBS ${REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_LIBS}
|
||||||
|
${StatusGo_STATIC_LIB} ${STATUSGO_DEPS_LIBS} PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_INCLUDE_DIRS ${REACT_NATIVE_DESKTOP_EXTERNAL_MODULES_INCLUDE_DIRS}
|
||||||
|
${StatusGo_INCLUDE_DIR} PARENT_SCOPE)
|
|
@ -0,0 +1,35 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
# The module defines the following variables:
|
||||||
|
# GO_FOUND - true if the Go was found
|
||||||
|
# GO_EXECUTABLE - path to the executable
|
||||||
|
# GO_VERSION - Go version number
|
||||||
|
# GO_PLATFORM - i.e. linux
|
||||||
|
# GO_ARCH - i.e. amd64
|
||||||
|
# Example usage:
|
||||||
|
# find_package(Go 1.2 REQUIRED)
|
||||||
|
|
||||||
|
|
||||||
|
find_program(GO_EXECUTABLE go PATHS ENV GOROOT GOPATH GOBIN PATH_SUFFIXES bin)
|
||||||
|
if (GO_EXECUTABLE)
|
||||||
|
get_filename_component(GO_ROOT_PATH ${GO_EXECUTABLE} REALPATH)
|
||||||
|
get_filename_component(GO_ROOT_PATH ${GO_ROOT_PATH}/../.. REALPATH)
|
||||||
|
message(STATUS "GO_ROOT_PATH is set to: ${GO_ROOT_PATH}")
|
||||||
|
execute_process(COMMAND ${GO_EXECUTABLE} version OUTPUT_VARIABLE GO_VERSION_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if(GO_VERSION_OUTPUT MATCHES "go([0-9]+\\.[0-9]+\\.?[0-9]*)[a-zA-Z0-9]* ([^/]+)/(.*)")
|
||||||
|
set(GO_VERSION ${CMAKE_MATCH_1})
|
||||||
|
set(GO_PLATFORM ${CMAKE_MATCH_2})
|
||||||
|
set(GO_ARCH ${CMAKE_MATCH_3})
|
||||||
|
elseif(GO_VERSION_OUTPUT MATCHES "go version devel .* ([^/]+)/(.*)$")
|
||||||
|
set(GO_VERSION "99-devel")
|
||||||
|
set(GO_PLATFORM ${CMAKE_MATCH_1})
|
||||||
|
set(GO_ARCH ${CMAKE_MATCH_2})
|
||||||
|
message("WARNING: Development version of Go being used, can't determine compatibility.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
mark_as_advanced(GO_EXECUTABLE)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(Go REQUIRED_VARS GO_EXECUTABLE GO_VERSION GO_PLATFORM GO_ARCH VERSION_VAR GO_VERSION)
|
|
@ -0,0 +1,8 @@
|
||||||
|
set GOROOT=%1
|
||||||
|
set GOPATH=%2
|
||||||
|
set PATH=%GOROOT%/bin;%GOROOT%;%GOPATH%;%PATH%
|
||||||
|
|
||||||
|
cd %3/lib
|
||||||
|
go get .
|
||||||
|
cd ..
|
||||||
|
mingw32-make statusgo-library
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export GOROOT=$1
|
||||||
|
export GOPATH=$2
|
||||||
|
export PATH=$GOROOT/bin:$GOROOT:$GOPATH:$PATH
|
||||||
|
|
||||||
|
cd $3/lib
|
||||||
|
go get ./
|
||||||
|
cd ..
|
||||||
|
make statusgo-library
|
|
@ -0,0 +1,286 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2017-present, Status Research and Development GmbH.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rctstatus.h"
|
||||||
|
#include "bridge.h"
|
||||||
|
#include "eventdispatcher.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QVariantMap>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
#include "libstatus.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct RegisterQMLMetaType {
|
||||||
|
RegisterQMLMetaType() {
|
||||||
|
qRegisterMetaType<RCTStatus*>();
|
||||||
|
}
|
||||||
|
} registerMetaType;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class RCTStatusPrivate {
|
||||||
|
public:
|
||||||
|
static Bridge* bridge;
|
||||||
|
static RCTStatus* rctStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
Bridge* RCTStatusPrivate::bridge = nullptr;
|
||||||
|
RCTStatus* RCTStatusPrivate::rctStatus = nullptr;
|
||||||
|
|
||||||
|
RCTStatus::RCTStatus(QObject* parent) : QObject(parent), d_ptr(new RCTStatusPrivate) {
|
||||||
|
RCTStatusPrivate::rctStatus = this;
|
||||||
|
SetSignalEventCallback((void*)&RCTStatus::jailSignalEventCallback);
|
||||||
|
connect(this, &RCTStatus::jailSignalEvent, this, &RCTStatus::onJailSignalEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
RCTStatus::~RCTStatus() {}
|
||||||
|
|
||||||
|
void RCTStatus::setBridge(Bridge* bridge) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
d->bridge = bridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RCTStatus::moduleName() {
|
||||||
|
return "Status";
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ModuleMethod*> RCTStatus::methodsToExport() {
|
||||||
|
return QList<ModuleMethod*>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap RCTStatus::constantsToExport() {
|
||||||
|
return QVariantMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::initJail(QString js, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::initJail with param js:" << " and callback id: " << callbackId;
|
||||||
|
|
||||||
|
InitJail(js.toUtf8().data());
|
||||||
|
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{ "{\"result\":\"\"}" });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::parseJail(QString chatId, QString js, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::parseJail with param chatId: " << chatId << " js:" << " and callback id: " << callbackId;
|
||||||
|
|
||||||
|
const char* result = Parse(chatId.toUtf8().data(), js.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::parseJail parseJail result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::callJail(QString chatId, QString path, QString params, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::callJail with param chatId: " << chatId << " path: " << path << " params: " << params << " and callback id: " << callbackId;
|
||||||
|
|
||||||
|
const char* result = Call(chatId.toUtf8().data(), path.toUtf8().data(), params.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::callJail callJail result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::getDeviceUUID(double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::getDeviceUUID";
|
||||||
|
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{"com.status.StatusIm"});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::startNode(QString configString) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::startNode with param configString:" << configString;
|
||||||
|
|
||||||
|
QJsonParseError jsonError;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(configString.toUtf8(), &jsonError);
|
||||||
|
if (jsonError.error != QJsonParseError::NoError){
|
||||||
|
qDebug() << jsonError.errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << " RCTStatus::startNode configString: " << jsonDoc.toVariant().toMap();
|
||||||
|
QVariantMap configJSON = jsonDoc.toVariant().toMap();
|
||||||
|
|
||||||
|
QString newKeystoreUrl = "keystore";
|
||||||
|
|
||||||
|
int networkId = configJSON["NetworkId"].toInt();
|
||||||
|
QString dataDir = configJSON["DataDir"].toString();
|
||||||
|
|
||||||
|
QString networkDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/" + dataDir;
|
||||||
|
QDir dir(networkDir);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkpath(".");
|
||||||
|
}
|
||||||
|
qDebug()<<"RCTStatus::startNode networkDir: "<<networkDir;
|
||||||
|
|
||||||
|
|
||||||
|
char *configChars = GenerateConfig(networkDir.toUtf8().data(), networkId);
|
||||||
|
qDebug() << "RCTStatus::startNode GenerateConfig result: " << configChars;
|
||||||
|
|
||||||
|
jsonDoc = QJsonDocument::fromJson(QString(configChars).toUtf8(), &jsonError);
|
||||||
|
if (jsonError.error != QJsonParseError::NoError){
|
||||||
|
qDebug() << jsonError.errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << " RCTStatus::startNode GenerateConfig configString: " << jsonDoc.toVariant().toMap();
|
||||||
|
QVariantMap generatedConfig = jsonDoc.toVariant().toMap();
|
||||||
|
generatedConfig["KeyStoreDir"] = newKeystoreUrl;
|
||||||
|
generatedConfig["LogEnabled"] = true;
|
||||||
|
generatedConfig["LogFile"] = networkDir + "/geth.log";
|
||||||
|
//generatedConfig["LogLevel"] = "DEBUG";
|
||||||
|
|
||||||
|
const char* result = StartNode(QString(QJsonDocument::fromVariant(generatedConfig).toJson(QJsonDocument::Compact)).toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::startNode StartNode result: " << result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::shouldMoveToInternalStorage(double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::shouldMoveToInternalStorage with param callbackId: " << callbackId;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::moveToInternalStorage(double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::moveToInternalStorage with param callbackId: " << callbackId;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{ "{\"result\":\"\"}" });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::stopNode() {
|
||||||
|
qDebug() << "call of RCTStatus::stopNode";
|
||||||
|
const char* result = StopNode();
|
||||||
|
qDebug() << "RCTStatus::stopNode StopNode result: " << result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::createAccount(QString password, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::createAccount with param callbackId: " << callbackId;
|
||||||
|
const char* result = CreateAccount(password.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::createAccount CreateAccount result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::notifyUsers(QString token, QString payloadJSON, QString tokensJSON, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::notifyUsers with param callbackId: " << callbackId;
|
||||||
|
const char* result = NotifyUsers(token.toUtf8().data(), payloadJSON.toUtf8().data(), tokensJSON.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::notifyUsers Notify result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::addPeer(QString enode, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::addPeer with param callbackId: " << callbackId;
|
||||||
|
const char* result = AddPeer(enode.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::addPeer AddPeer result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::recoverAccount(QString passphrase, QString password, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::recoverAccount with param callbackId: " << callbackId;
|
||||||
|
const char* result = RecoverAccount(password.toUtf8().data(), passphrase.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::recoverAccount RecoverAccount result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::login(QString address, QString password, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::login with param callbackId: " << callbackId;
|
||||||
|
const char* result = Login(address.toUtf8().data(), password.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::login Login result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::approveSignRequests(QString hashes, QString password, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::approveSignRequests with param callbackId: " << callbackId;
|
||||||
|
const char* result = ApproveSignRequests(hashes.toUtf8().data(), password.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::approveSignRequests CompleteTransactions result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::discardSignRequest(QString id) {
|
||||||
|
qDebug() << "call of RCTStatus::discardSignRequest with id: " << id;
|
||||||
|
DiscardSignRequest(id.toUtf8().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::setAdjustResize() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::setAdjustPan() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::setSoftInputMode(int i) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::clearCookies() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::clearStorageAPIs() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RCTStatus::sendWeb3Request(QString payload, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::sendWeb3Request with param callbackId: " << callbackId;
|
||||||
|
const char* result = CallRPC(payload.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::sendWeb3Request CallRPC result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::sendWeb3PrivateRequest(QString payload, double callbackId) {
|
||||||
|
Q_D(RCTStatus);
|
||||||
|
qDebug() << "call of RCTStatus::sendWeb3PrivateRequest with param callbackId: " << callbackId;
|
||||||
|
const char* result = CallPrivateRPC(payload.toUtf8().data());
|
||||||
|
qDebug() << "RCTStatus::sendWeb3PrivateRequest CallPrivateRPC result: " << result;
|
||||||
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::closeApplication() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RCTStatus::JSCEnabled() {
|
||||||
|
qDebug() << "call of RCTStatus::JSCEnabled";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::jailSignalEventCallback(const char* signal) {
|
||||||
|
qDebug() << "call of RCTStatus::jailSignalEventCallback ... signal: " << signal;
|
||||||
|
RCTStatusPrivate::rctStatus->emitSignalEvent(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::emitSignalEvent(const char* signal) {
|
||||||
|
qDebug() << "call of RCTStatus::emitSignalEvent ... signal: " << signal;
|
||||||
|
Q_EMIT jailSignalEvent(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTStatus::onJailSignalEvent(const char* signal) {
|
||||||
|
qDebug() << "call of RCTStatus::onJailSignalEvent ... signal: " << signal;
|
||||||
|
RCTStatusPrivate::bridge->eventDispatcher()->sendDeviceEvent("gethEvent", QVariantMap{{"jsonEvent", signal}});
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2017-present, Status Research and Development GmbH.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RCTSTATUS_H
|
||||||
|
#define RCTSTATUS_H
|
||||||
|
|
||||||
|
#include "moduleinterface.h"
|
||||||
|
|
||||||
|
#include <QVariantMap>
|
||||||
|
|
||||||
|
class RCTStatusPrivate;
|
||||||
|
class RCTStatus : public QObject, public ModuleInterface {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(ModuleInterface)
|
||||||
|
|
||||||
|
Q_DECLARE_PRIVATE(RCTStatus)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE RCTStatus(QObject* parent = 0);
|
||||||
|
~RCTStatus();
|
||||||
|
|
||||||
|
void setBridge(Bridge* bridge) override;
|
||||||
|
|
||||||
|
QString moduleName() override;
|
||||||
|
QList<ModuleMethod*> methodsToExport() override;
|
||||||
|
QVariantMap constantsToExport() override;
|
||||||
|
|
||||||
|
Q_INVOKABLE void initJail(QString js, double callbackId);
|
||||||
|
Q_INVOKABLE void parseJail(QString chatId, QString js, double callbackId);
|
||||||
|
Q_INVOKABLE void callJail(QString chatId, QString path, QString params, double callbackId);
|
||||||
|
Q_INVOKABLE void startNode(QString configString);
|
||||||
|
Q_INVOKABLE void shouldMoveToInternalStorage(double callbackId);
|
||||||
|
Q_INVOKABLE void moveToInternalStorage(double callbackId);
|
||||||
|
Q_INVOKABLE void stopNode();
|
||||||
|
Q_INVOKABLE void createAccount(QString password, double callbackId);
|
||||||
|
Q_INVOKABLE void notifyUsers(QString token, QString payloadJSON, QString tokensJSON, double callbackId);
|
||||||
|
Q_INVOKABLE void addPeer(QString enode, double callbackId);
|
||||||
|
Q_INVOKABLE void recoverAccount(QString passphrase, QString password, double callbackId);
|
||||||
|
Q_INVOKABLE void login(QString address, QString password, double callbackId);
|
||||||
|
Q_INVOKABLE void approveSignRequests(QString hashes, QString password, double callbackId);
|
||||||
|
Q_INVOKABLE void discardSignRequest(QString id);
|
||||||
|
|
||||||
|
Q_INVOKABLE void setAdjustResize();
|
||||||
|
Q_INVOKABLE void setAdjustPan();
|
||||||
|
Q_INVOKABLE void setSoftInputMode(int i);
|
||||||
|
|
||||||
|
Q_INVOKABLE void clearCookies();
|
||||||
|
Q_INVOKABLE void clearStorageAPIs();
|
||||||
|
Q_INVOKABLE void sendWeb3Request(QString payload, double callbackId);
|
||||||
|
Q_INVOKABLE void sendWeb3PrivateRequest(QString payload, double callbackId);
|
||||||
|
Q_INVOKABLE void closeApplication();
|
||||||
|
Q_INVOKABLE void getDeviceUUID(double callbackId);
|
||||||
|
|
||||||
|
Q_INVOKABLE static bool JSCEnabled();
|
||||||
|
Q_INVOKABLE static void jailSignalEventCallback(const char* signal);
|
||||||
|
|
||||||
|
void emitSignalEvent(const char* signal);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void jailSignalEvent(const char* signal);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onJailSignalEvent(const char* signal);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<RCTStatusPrivate> d_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RCTSTATUS_H
|
|
@ -0,0 +1,23 @@
|
||||||
|
patch-package
|
||||||
|
--- a/node_modules/metro/src/JSTransformer/index.js
|
||||||
|
+++ b/node_modules/metro/src/JSTransformer/index.js
|
||||||
|
@@ -151,6 +151,8 @@ module.exports = class Transformer {
|
||||||
|
/^--heap[_-]growing[_-]percent=[0-9]+$/.test(arg) ||
|
||||||
|
/^--max[_-]old[_-]space[_-]size=[0-9]+$/.test(arg));
|
||||||
|
|
||||||
|
+ execArgv.push("--max-old-space-size=8192");
|
||||||
|
+
|
||||||
|
const env = _extends({},
|
||||||
|
process.env, {
|
||||||
|
// Force color to print syntax highlighted code frames.
|
||||||
|
--- a/node_modules/metro/src/defaults.js
|
||||||
|
+++ b/node_modules/metro/src/defaults.js
|
||||||
|
@@ -45,7 +45,7 @@ exports.sourceExts = ['js', 'json'];
|
||||||
|
|
||||||
|
exports.moduleSystem = require.resolve('./lib/polyfills/require.js');
|
||||||
|
|
||||||
|
-exports.platforms = ['ios', 'android', 'windows', 'web'];
|
||||||
|
+exports.platforms = ['ios', 'android', 'windows', 'web', 'desktop'];
|
||||||
|
|
||||||
|
exports.providesModuleNodeModules = ['react-native', 'react-native-windows'];
|
||||||
|
|
31
project.clj
31
project.clj
|
@ -22,13 +22,17 @@
|
||||||
:aliases {"prod-build" ^{:doc "Recompile code with prod profile."}
|
:aliases {"prod-build" ^{:doc "Recompile code with prod profile."}
|
||||||
["do" "clean"
|
["do" "clean"
|
||||||
["with-profile" "prod" "cljsbuild" "once" "ios"]
|
["with-profile" "prod" "cljsbuild" "once" "ios"]
|
||||||
["with-profile" "prod" "cljsbuild" "once" "android"]]
|
["with-profile" "prod" "cljsbuild" "once" "android"]
|
||||||
|
["with-profile" "prod" "cljsbuild" "once" "desktop"]]
|
||||||
"prod-build-android" ^{:doc "Recompile code for Android with prod profile."}
|
"prod-build-android" ^{:doc "Recompile code for Android with prod profile."}
|
||||||
["do" "clean"
|
["do" "clean"
|
||||||
["with-profile" "prod" "cljsbuild" "once" "android"]]
|
["with-profile" "prod" "cljsbuild" "once" "android"]]
|
||||||
"prod-build-ios" ^{:doc "Recompile code for iOS with prod profile."}
|
"prod-build-ios" ^{:doc "Recompile code for iOS with prod profile."}
|
||||||
["do" "clean"
|
["do" "clean"
|
||||||
["with-profile" "prod" "cljsbuild" "once" "ios"]]
|
["with-profile" "prod" "cljsbuild" "once" "ios"]]
|
||||||
|
"prod-build-desktop" ^{:doc "Recompile code for desktop with prod profile."}
|
||||||
|
["do" "clean"
|
||||||
|
["with-profile" "prod" "cljsbuild" "once" "desktop"]]
|
||||||
"figwheel-repl" ["with-profile" "+figwheel" "run" "-m" "clojure.main" "env/dev/run.clj"]
|
"figwheel-repl" ["with-profile" "+figwheel" "run" "-m" "clojure.main" "env/dev/run.clj"]
|
||||||
"test-cljs" ["with-profile" "test" "doo" "node" "test" "once"]
|
"test-cljs" ["with-profile" "test" "doo" "node" "test" "once"]
|
||||||
"test-protocol" ["with-profile" "test" "doo" "node" "protocol" "once"]
|
"test-protocol" ["with-profile" "test" "doo" "node" "protocol" "once"]
|
||||||
|
@ -36,20 +40,20 @@
|
||||||
:profiles {:dev {:dependencies [[com.cemerick/piggieback "0.2.2"]]
|
:profiles {:dev {:dependencies [[com.cemerick/piggieback "0.2.2"]]
|
||||||
:cljsbuild {:builds
|
:cljsbuild {:builds
|
||||||
{:ios
|
{:ios
|
||||||
{:source-paths ["components/src" "react-native/src" "src"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src"]
|
||||||
:compiler {:output-to "target/ios/app.js"
|
:compiler {:output-to "target/ios/app.js"
|
||||||
:main "env.ios.main"
|
:main "env.ios.main"
|
||||||
:output-dir "target/ios"
|
:output-dir "target/ios"
|
||||||
:optimizations :none}}
|
:optimizations :none}}
|
||||||
:android
|
:android
|
||||||
{:source-paths ["components/src" "react-native/src" "src"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src"]
|
||||||
:compiler {:output-to "target/android/app.js"
|
:compiler {:output-to "target/android/app.js"
|
||||||
:main "env.android.main"
|
:main "env.android.main"
|
||||||
:output-dir "target/android"
|
:output-dir "target/android"
|
||||||
:optimizations :none}
|
:optimizations :none}
|
||||||
:warning-handlers [status-im.utils.build/warning-handler]}
|
:warning-handlers [status-im.utils.build/warning-handler]}
|
||||||
:desktop
|
:desktop
|
||||||
{:source-paths ["components/src" "react-native/src" "src"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/desktop" "src"]
|
||||||
:compiler {:output-to "target/desktop/app.js"
|
:compiler {:output-to "target/desktop/app.js"
|
||||||
:main "env.desktop.main"
|
:main "env.desktop.main"
|
||||||
:output-dir "target/desktop"
|
:output-dir "target/desktop"
|
||||||
|
@ -62,7 +66,7 @@
|
||||||
[re-frisk-sidecar "0.5.7"]
|
[re-frisk-sidecar "0.5.7"]
|
||||||
[day8.re-frame/tracing "0.5.0"]
|
[day8.re-frame/tracing "0.5.0"]
|
||||||
[hawk "0.2.11"]]
|
[hawk "0.2.11"]]
|
||||||
:source-paths ["src" "env/dev" "react-native/src" "components/src"]}]
|
:source-paths ["src" "env/dev" "react-native/src/cljsjs" "components/src"]}]
|
||||||
:test {:dependencies [[day8.re-frame/test "0.1.5"]]
|
:test {:dependencies [[day8.re-frame/test "0.1.5"]]
|
||||||
:plugins [[lein-doo "0.1.9"]]
|
:plugins [[lein-doo "0.1.9"]]
|
||||||
:cljsbuild {:builds
|
:cljsbuild {:builds
|
||||||
|
@ -91,7 +95,7 @@
|
||||||
:target :nodejs}}]}}
|
:target :nodejs}}]}}
|
||||||
:prod {:cljsbuild {:builds
|
:prod {:cljsbuild {:builds
|
||||||
{:ios
|
{:ios
|
||||||
{:source-paths ["components/src" "react-native/src" "src" "env/prod"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src" "env/prod"]
|
||||||
:compiler {:output-to "index.ios.js"
|
:compiler {:output-to "index.ios.js"
|
||||||
:main "env.ios.main"
|
:main "env.ios.main"
|
||||||
:output-dir "target/ios-prod"
|
:output-dir "target/ios-prod"
|
||||||
|
@ -104,7 +108,7 @@
|
||||||
:language-in :ecmascript5}
|
:language-in :ecmascript5}
|
||||||
:warning-handlers [status-im.utils.build/warning-handler]}
|
:warning-handlers [status-im.utils.build/warning-handler]}
|
||||||
:android
|
:android
|
||||||
{:source-paths ["components/src" "react-native/src" "src" "env/prod"]
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src" "env/prod"]
|
||||||
:compiler {:output-to "index.android.js"
|
:compiler {:output-to "index.android.js"
|
||||||
:main "env.android.main"
|
:main "env.android.main"
|
||||||
:output-dir "target/android-prod"
|
:output-dir "target/android-prod"
|
||||||
|
@ -115,4 +119,17 @@
|
||||||
:parallel-build false
|
:parallel-build false
|
||||||
:elide-asserts true
|
:elide-asserts true
|
||||||
:language-in :ecmascript5}
|
:language-in :ecmascript5}
|
||||||
|
:warning-handlers [status-im.utils.build/warning-handler]}
|
||||||
|
:desktop
|
||||||
|
{:source-paths ["components/src" "react-native/src/cljsjs" "react-native/src/desktop" "src" "env/prod"]
|
||||||
|
:compiler {:output-to "index.desktop.js"
|
||||||
|
:main "env.desktop.main"
|
||||||
|
:output-dir "target/desktop-prod"
|
||||||
|
:static-fns true
|
||||||
|
:optimize-constants true
|
||||||
|
:optimizations :simple
|
||||||
|
:closure-defines {"goog.DEBUG" false}
|
||||||
|
:parallel-build false
|
||||||
|
:elide-asserts true
|
||||||
|
:language-in :ecmascript5}
|
||||||
:warning-handlers [status-im.utils.build/warning-handler]}}}}})
|
:warning-handlers [status-im.utils.build/warning-handler]}}}}})
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
(ns status-im.react-native.js-dependencies)
|
||||||
|
|
||||||
|
(def config (js/require "react-native-config"))
|
||||||
|
(def fs (js/require "react-native-fs"))
|
||||||
|
(def http-bridge (js/require "react-native-http-bridge"))
|
||||||
|
(def keychain (js/require "react-native-keychain"))
|
||||||
|
(def qr-code (js/require "react-native-qrcode"))
|
||||||
|
(def react-native (js/require "react-native"))
|
||||||
|
(def realm (js/require "realm"))
|
||||||
|
(def webview-bridge (js/require "react-native-webview-bridge"))
|
||||||
|
(def secure-random (.-generateSecureRandom (js/require "react-native-securerandom")))
|
||||||
|
(def EventEmmiter (js/require "react-native/Libraries/vendor/emitter/EventEmitter"))
|
||||||
|
(def fetch (.-default (js/require "react-native-fetch-polyfill")))
|
||||||
|
(def i18n (js/require "react-native-i18n"))
|
||||||
|
(def camera #js {:constants {:Aspect "Portrait"}})
|
||||||
|
(def dialogs #js {})
|
||||||
|
(def dismiss-keyboard #js {})
|
||||||
|
(def image-crop-picker #js {})
|
||||||
|
(def image-resizer #js {})
|
||||||
|
(def instabug #js {:IBGLog ( fn [])})
|
||||||
|
(def nfc #js {})
|
||||||
|
(def svg #js {})
|
||||||
|
(def react-native-fcm #js {:default #js {:getFCMToken (fn [])
|
||||||
|
:requestPermissions (fn [])}})
|
||||||
|
(def snoopy #js {})
|
||||||
|
(def snoopy-filter #js {})
|
||||||
|
(def snoopy-bars #js {})
|
||||||
|
(def snoopy-buffer #js {})
|
||||||
|
(def background-timer #js {:setTimeout (fn [])})
|
||||||
|
(def testfairy #js {})
|
||||||
|
|
|
@ -1,31 +1,29 @@
|
||||||
(ns status-im.react-native.js-dependencies)
|
(ns status-im.react-native.js-dependencies)
|
||||||
|
|
||||||
(def camera (js/require "react-native-camera"))
|
|
||||||
(def config (js/require "react-native-config"))
|
(def config (js/require "react-native-config"))
|
||||||
(def dialogs (js/require "react-native-dialogs"))
|
|
||||||
(def dismiss-keyboard (js/require "dismissKeyboard"))
|
|
||||||
(def fs (js/require "react-native-fs"))
|
(def fs (js/require "react-native-fs"))
|
||||||
(def http-bridge (js/require "react-native-http-bridge"))
|
(def http-bridge (js/require "react-native-http-bridge"))
|
||||||
;; i18n is now exported in default object of the module
|
|
||||||
;; https://github.com/AlexanderZaytsev/react-native-i18n/blob/master/index.js
|
|
||||||
(def i18n (.-default (js/require "react-native-i18n")))
|
|
||||||
(def image-crop-picker (js/require "react-native-image-crop-picker"))
|
|
||||||
(def image-resizer (js/require "react-native-image-resizer"))
|
|
||||||
(def instabug (js/require "instabug-reactnative"))
|
|
||||||
(def keychain (js/require "react-native-keychain"))
|
(def keychain (js/require "react-native-keychain"))
|
||||||
(def nfc (js/require "nfc-react-native"))
|
|
||||||
(def qr-code (js/require "react-native-qrcode"))
|
(def qr-code (js/require "react-native-qrcode"))
|
||||||
(def react-native (js/require "react-native"))
|
(def react-native (js/require "react-native"))
|
||||||
(def realm (js/require "realm"))
|
(def realm (js/require "realm"))
|
||||||
(def webview-bridge (js/require "react-native-webview-bridge"))
|
(def webview-bridge (js/require "react-native-webview-bridge"))
|
||||||
|
(def secure-random (.-generateSecureRandom (js/require "react-native-securerandom")))
|
||||||
|
(def EventEmmiter (js/require "react-native/Libraries/vendor/emitter/EventEmitter"))
|
||||||
|
(def fetch (.-default (js/require "react-native-fetch-polyfill")))
|
||||||
|
(def i18n (.-default (js/require "react-native-i18n")))
|
||||||
|
(def camera (js/require "react-native-camera"))
|
||||||
|
(def dialogs (js/require "react-native-dialogs"))
|
||||||
|
(def dismiss-keyboard (js/require "dismissKeyboard"))
|
||||||
|
(def image-crop-picker (js/require "react-native-image-crop-picker"))
|
||||||
|
(def image-resizer (js/require "react-native-image-resizer"))
|
||||||
|
(def instabug (js/require "instabug-reactnative"))
|
||||||
|
(def nfc (js/require "nfc-react-native"))
|
||||||
(def svg (js/require "react-native-svg"))
|
(def svg (js/require "react-native-svg"))
|
||||||
(def react-native-fcm (js/require "react-native-fcm"))
|
(def react-native-fcm (js/require "react-native-fcm"))
|
||||||
(def secure-random (.-generateSecureRandom (js/require "react-native-securerandom")))
|
|
||||||
(def snoopy (js/require "rn-snoopy"))
|
(def snoopy (js/require "rn-snoopy"))
|
||||||
(def snoopy-filter (js/require "rn-snoopy/stream/filter"))
|
(def snoopy-filter (js/require "rn-snoopy/stream/filter"))
|
||||||
(def snoopy-bars (js/require "rn-snoopy/stream/bars"))
|
(def snoopy-bars (js/require "rn-snoopy/stream/bars"))
|
||||||
(def snoopy-buffer (js/require "rn-snoopy/stream/buffer"))
|
(def snoopy-buffer (js/require "rn-snoopy/stream/buffer"))
|
||||||
(def EventEmmiter (js/require "react-native/Libraries/vendor/emitter/EventEmitter"))
|
|
||||||
(def background-timer (.-default (js/require "react-native-background-timer")))
|
(def background-timer (.-default (js/require "react-native-background-timer")))
|
||||||
(def fetch (.-default (js/require "react-native-fetch-polyfill")))
|
|
||||||
(def testfairy (js/require "react-native-testfairy"))
|
(def testfairy (js/require "react-native-testfairy"))
|
|
@ -0,0 +1,89 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
|
||||||
|
STATUSREACTPATH="$SCRIPTPATH/.."
|
||||||
|
WORKFOLDER="$SCRIPTPATH/../mac_bundle"
|
||||||
|
MACDEPLOYQT=""
|
||||||
|
|
||||||
|
#if no arguments passed, inform user about possible ones (one for making script interactive, one for path to macdeployqt)
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
echo -e "${RED}You need to specify path to macdeployqt binary as an argument${NC}"
|
||||||
|
echo "Example: scripts/create-desktop-mac-bundle.sh /usr/bin/macdeployqt"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
MACDEPLOYQT=$1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if gdrive installed
|
||||||
|
command -v gdrive >/dev/null 2>&1 || { echo -e "${RED}gdrive tool need to be installed. (brew install gdrive). Aborting.${NC}" >&2; exit 1; }
|
||||||
|
|
||||||
|
|
||||||
|
# inform user that define should be changed in "desktop/main.cpp"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}In desktop/main.cpp file please uncomment #define BULID_FOR_BUNDLE line.${NC}"
|
||||||
|
read -p "When ready, plese press enter to continue"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
# create directory for all work related to bundling
|
||||||
|
mkdir -p $WORKFOLDER
|
||||||
|
echo -e "${GREEN}Work folder created: $WORKFOLDER${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# from index.desktop.js create javascript bundle and resources folder
|
||||||
|
echo "Generating StatusIm.bundle and assets folder..."
|
||||||
|
react-native bundle --entry-file index.desktop.js --bundle-output $WORKFOLDER/StatusIm.jsbundle --dev false --platform desktop --assets-dest $WORKFOLDER/assets
|
||||||
|
echo -e "${GREEN}Generating done.${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# show path to javascript bundle and line that should be added to package.json
|
||||||
|
echo -e "${YELLOW}Please add the following line to package.json:${NC}"
|
||||||
|
echo "\"desktopJSBundlePath\": \"$WORKFOLDER/StatusIm.jsbundle\""
|
||||||
|
echo ""
|
||||||
|
read -p "When ready, plese press enter to continue"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
# build desktop app
|
||||||
|
echo "Building StatusIm desktop..."
|
||||||
|
react-native build-desktop
|
||||||
|
echo -e "${GREEN}Building done.${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
# download prepared package with mac bundle files (it contains qt libraries, icon)
|
||||||
|
echo "Downloading skeleton of mac bundle..."
|
||||||
|
echo -e "${YELLOW}First time gdrive can ask you for permissions to google drive${NC}"
|
||||||
|
gdrive download --path $WORKFOLDER 1fJbW9FzGGPvYkuJcSH5mCAcGdnyUeDSY
|
||||||
|
echo -e "${GREEN}Downloading done.${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
# Unpacking downloaded archive
|
||||||
|
echo "Unpacking bundle skeleton"
|
||||||
|
unzip $WORKFOLDER/StatusIm.app.zip -d $WORKFOLDER
|
||||||
|
chmod +x $WORKFOLDER/StatusIm.app/Contents/MacOs/ubuntu-server
|
||||||
|
echo -e "${GREEN}Unzipping done.${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
# copy binary and resources to mac bundle
|
||||||
|
echo "Copying resources and binary..."
|
||||||
|
cp -r $WORKFOLDER/assets/share/assets $WORKFOLDER/StatusIm.app/Contents/MacOs
|
||||||
|
cp $STATUSREACTPATH/desktop/bin/StatusIm $WORKFOLDER/StatusIm.app/Contents/MacOs
|
||||||
|
echo -e "${GREEN}Copying done.${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
# invoke macdeployqt to create StatusIm.dmg
|
||||||
|
echo "Creating bundle dmg..."
|
||||||
|
$MACDEPLOYQT $WORKFOLDER/StatusIm.app -verbose=3 -qmldir="$STATUSREACTPATH/node_modules/react-native/ReactQt/application/src/" -qmldir="$STATUSREACTPATH/node_modules/react-native/ReactQt/runtime/src/qml/" -dmg
|
||||||
|
echo -e "${GREEN}Bundle ready!${NC}"
|
||||||
|
echo ""
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
filename=$1
|
||||||
|
#fileid="1yPTGcPe5DZd3ubzAgUBp3aAQRAOK9eKQ"
|
||||||
|
fileid=$2
|
||||||
|
rm -rf ./cookie
|
||||||
|
curl -c ./cookie -s -L "https://drive.google.com/uc?export=download&id=${fileid}" > /dev/null
|
||||||
|
curl -Lb ./cookie "https://drive.google.com/uc?export=download&confirm=`awk '/download/ {print $NF}' ./cookie`&id=${fileid}" -o ${filename}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
PLATFORM=""
|
||||||
|
PLATFORM_FOLDER=""
|
||||||
|
|
||||||
|
#if no arguments passed, inform user about possible ones
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
echo -e "${GREEN}This script should be invoked with platform argument: 'mobile' or 'desktop'${NC}"
|
||||||
|
echo "When called it links"
|
||||||
|
# echo "If invoked with 'mobile' argument it will make a copying: "
|
||||||
|
# echo "package.json.mobile -> package.json"
|
||||||
|
# echo "etc.."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
PLATFORM=$1
|
||||||
|
PLATFORM_FOLDER="${PLATFORM}_files"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "Removing node_modules"
|
||||||
|
rm -rf node_modules
|
||||||
|
|
||||||
|
echo "Creating link: package.json -> ${PLATFORM_FOLDER}/package.json "
|
||||||
|
ln -sf ${PLATFORM_FOLDER}/package.json package.json
|
||||||
|
|
||||||
|
echo "Creating link: package-lock.json -> ${PLATFORM_FOLDER}/package-lock.json"
|
||||||
|
ln -sf ${PLATFORM_FOLDER}/package-lock.json package-lock.json
|
||||||
|
|
||||||
|
echo "Creating link: VERSION -> ${PLATFORM_FOLDER}/VERSION"
|
||||||
|
ln -sf ${PLATFORM_FOLDER}/VERSION VERSION
|
||||||
|
|
||||||
|
if [ "${PLATFORM}" == "mobile" ]
|
||||||
|
then
|
||||||
|
echo -e "Removing .re-natal symlink from root"
|
||||||
|
rm -rf .re-natal
|
||||||
|
else
|
||||||
|
echo "Creating link: .re-natal -> ${PLATFORM_FOLDER}/.re-natal"
|
||||||
|
ln -sf ${PLATFORM_FOLDER}/.re-natal .re-natal
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo -e "${GREEN}Finished!${NC}"
|
|
@ -11,10 +11,7 @@
|
||||||
|
|
||||||
(defn app-root []
|
(defn app-root []
|
||||||
(reagent/create-class
|
(reagent/create-class
|
||||||
{:component-will-mount
|
{:reagent-render views/main}))
|
||||||
(fn []
|
|
||||||
(.hide react/splash-screen))
|
|
||||||
:reagent-render views/main}))
|
|
||||||
|
|
||||||
(defn init []
|
(defn init []
|
||||||
(core/init app-root))
|
(core/init app-root))
|
|
@ -17,7 +17,7 @@
|
||||||
;; if StatusModule is not initialized better to store
|
;; if StatusModule is not initialized better to store
|
||||||
;; calls and make them only when StatusModule is ready
|
;; calls and make them only when StatusModule is ready
|
||||||
;; this flag helps to handle this
|
;; this flag helps to handle this
|
||||||
(defonce module-initialized? (atom (or p/ios? js/goog.DEBUG)))
|
(defonce module-initialized? (atom (or p/ios? js/goog.DEBUG p/desktop?)))
|
||||||
|
|
||||||
;; array of calls to StatusModule
|
;; array of calls to StatusModule
|
||||||
(defonce calls (atom []))
|
(defonce calls (atom []))
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
:active-unknown "Unknown"
|
:active-unknown "Unknown"
|
||||||
:available "Available"
|
:available "Available"
|
||||||
:no-messages "No messages"
|
:no-messages "No messages"
|
||||||
|
:no-messages-yet "No messages yet"
|
||||||
:suggestions-requests "Requests"
|
:suggestions-requests "Requests"
|
||||||
:suggestions-commands "Commands"
|
:suggestions-commands "Commands"
|
||||||
:faucet-success "Faucet request has been received"
|
:faucet-success "Faucet request has been received"
|
||||||
|
@ -187,6 +188,7 @@
|
||||||
|
|
||||||
;;sharing
|
;;sharing
|
||||||
:sharing-copy-to-clipboard "Copy to clipboard"
|
:sharing-copy-to-clipboard "Copy to clipboard"
|
||||||
|
:sharing-copied-to-clipboard "Copied to clipboard"
|
||||||
:sharing-share "Share..."
|
:sharing-share "Share..."
|
||||||
:sharing-cancel "Cancel"
|
:sharing-cancel "Cancel"
|
||||||
|
|
||||||
|
@ -220,6 +222,7 @@
|
||||||
;;chats
|
;;chats
|
||||||
:new "New"
|
:new "New"
|
||||||
:new-chat "New chat"
|
:new-chat "New chat"
|
||||||
|
:start-chat "Start chat"
|
||||||
:start-new-chat "Start new chat"
|
:start-new-chat "Start new chat"
|
||||||
:start-group-chat "Start group chat"
|
:start-group-chat "Start group chat"
|
||||||
:invite-friends "Invite friends"
|
:invite-friends "Invite friends"
|
||||||
|
@ -232,6 +235,7 @@
|
||||||
:delete-group-chat-confirmation "Are you sure you want to delete this group chat?"
|
:delete-group-chat-confirmation "Are you sure you want to delete this group chat?"
|
||||||
:new-group-chat "New group chat"
|
:new-group-chat "New group chat"
|
||||||
:new-public-group-chat "Join public chat"
|
:new-public-group-chat "Join public chat"
|
||||||
|
:selected-for-you "Selected for you"
|
||||||
:public-chat "Public chat"
|
:public-chat "Public chat"
|
||||||
:edit-chats "Edit chats"
|
:edit-chats "Edit chats"
|
||||||
:search-chats "Search chats"
|
:search-chats "Search chats"
|
||||||
|
@ -281,8 +285,10 @@
|
||||||
:search-contacts "Search contacts"
|
:search-contacts "Search contacts"
|
||||||
:contacts-group-new-chat "Start new chat"
|
:contacts-group-new-chat "Start new chat"
|
||||||
:choose-from-contacts "Choose from contacts"
|
:choose-from-contacts "Choose from contacts"
|
||||||
|
:or-choose-a-contact "Or choose a contact"
|
||||||
:no-contacts "No contacts yet"
|
:no-contacts "No contacts yet"
|
||||||
:show-qr "Show QR code"
|
:show-qr "Show QR code"
|
||||||
|
:copy-qr "Copy code"
|
||||||
:qr-code-public-key-hint "Share this code to \nstart chatting"
|
:qr-code-public-key-hint "Share this code to \nstart chatting"
|
||||||
:enter-address "Enter address"
|
:enter-address "Enter address"
|
||||||
:enter-contact-code "Enter contact code"
|
:enter-contact-code "Enter contact code"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require [clojure.string :as string]))
|
(:require [clojure.string :as string]))
|
||||||
|
|
||||||
(def white "#ffffff")
|
(def white "#ffffff")
|
||||||
|
(def transparent "transparent")
|
||||||
(def white-light-transparent "rgba(255, 255, 255, 0.1)") ;; Used as icon background color for a dark foreground
|
(def white-light-transparent "rgba(255, 255, 255, 0.1)") ;; Used as icon background color for a dark foreground
|
||||||
(def white-transparent "rgba(255, 255, 255, 0.2)") ;; Used as icon color on dark background
|
(def white-transparent "rgba(255, 255, 255, 0.2)") ;; Used as icon color on dark background
|
||||||
(def white-lighter-transparent "rgba(255, 255, 255, 0.6)") ;; Used for input placeholder color
|
(def white-lighter-transparent "rgba(255, 255, 255, 0.6)") ;; Used for input placeholder color
|
||||||
|
@ -28,6 +29,8 @@
|
||||||
(def cyan "#7adcfb") ;; Used by wallet transaction filtering icon
|
(def cyan "#7adcfb") ;; Used by wallet transaction filtering icon
|
||||||
(def photo-border-color "#ccd3d6")
|
(def photo-border-color "#ccd3d6")
|
||||||
(def green "#44d058") ;; icon for successful inboud transaction
|
(def green "#44d058") ;; icon for successful inboud transaction
|
||||||
|
(def tooltip-green-text "#66bf50") ;; fading tooltip text color
|
||||||
|
(def tooltip-green "#e9f6e6") ;; fading tooltip background color
|
||||||
|
|
||||||
(def chat-colors ["#fa6565"
|
(def chat-colors ["#fa6565"
|
||||||
"#7cda00"
|
"#7cda00"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
(ns status-im.ui.components.desktop.tabs
|
(ns status-im.ui.components.desktop.tabs
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.ui.components.icons.vector-icons :as icons]
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.screens.main-tabs.styles :as tabs.styles])
|
[status-im.ui.screens.main-tabs.styles :as tabs.styles])
|
||||||
(:require-macros [status-im.utils.views :as views]))
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
@ -26,7 +28,7 @@
|
||||||
[react/view {:style tabs.styles/tab-container}
|
[react/view {:style tabs.styles/tab-container}
|
||||||
(let [icon (if active? icon-active icon-inactive)]
|
(let [icon (if active? icon-active icon-inactive)]
|
||||||
[react/view
|
[react/view
|
||||||
[icons/icon icon {:color (:color (tabs.styles/tab-icon active?))}]])
|
[icons/icon icon {:style {:tint-color (if active? colors/blue colors/gray-icon)}}]])
|
||||||
[react/view
|
[react/view
|
||||||
[react/text {:style (tabs.styles/tab-title active?)}
|
[react/text {:style (tabs.styles/tab-title active?)}
|
||||||
title]]]))
|
title]]]))
|
||||||
|
@ -36,13 +38,15 @@
|
||||||
(defn tab [index content view-id active?]
|
(defn tab [index content view-id active?]
|
||||||
[react/touchable-highlight {:style (merge tabs.styles/tab-container {:flex 1})
|
[react/touchable-highlight {:style (merge tabs.styles/tab-container {:flex 1})
|
||||||
:disabled active?
|
:disabled active?
|
||||||
:on-press #(re-frame/dispatch [:set-in [:desktop/desktop :tab-view-id] view-id])}
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [:navigate-to :home])
|
||||||
|
(re-frame/dispatch [:set-in [:desktop/desktop :tab-view-id] view-id]))}
|
||||||
[react/view
|
[react/view
|
||||||
[content active?]]])
|
[content active?]]])
|
||||||
|
|
||||||
(views/defview main-tabs []
|
(views/defview main-tabs []
|
||||||
(views/letsubs [current-tab [:get :left-view-id]]
|
(views/letsubs [current-tab [:get-in [:desktop/desktop :tab-view-id]]]
|
||||||
[react/view
|
[react/view
|
||||||
[react/view {:style tabs.styles/tabs-container}
|
[react/view {:style tabs.styles/tabs-container}
|
||||||
(for [[index {:keys [content view-id]}] tabs-list-indexed]
|
(for [[index {:keys [content view-id]}] tabs-list-indexed]
|
||||||
^{:key index} [tab index content view-id (= current-tab view-id)])]]))
|
^{:key index} [tab index content view-id (= current-tab view-id)])]]))
|
||||||
|
|
|
@ -2,121 +2,198 @@
|
||||||
(:require-macros [status-im.ui.components.svg :as components.svg])
|
(:require-macros [status-im.ui.components.svg :as components.svg])
|
||||||
(:require [goog.object :as object]
|
(:require [goog.object :as object]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.ui.components.styles :as styles]
|
[status-im.ui.components.styles :as styles]
|
||||||
[status-im.ui.components.react :as react]
|
|
||||||
[status-im.react-native.js-dependencies :as js-dependencies])
|
[status-im.react-native.js-dependencies :as js-dependencies])
|
||||||
(:refer-clojure :exclude [use]))
|
(:refer-clojure :exclude [use]))
|
||||||
|
|
||||||
(defn get-property [name]
|
(when-not platform/desktop?
|
||||||
(object/get js-dependencies/svg name))
|
(defn get-property [name]
|
||||||
|
(object/get js-dependencies/svg name))
|
||||||
|
|
||||||
(defn adapt-class [class]
|
(defn adapt-class [class]
|
||||||
(when class
|
(when class
|
||||||
(reagent/adapt-react-class class)))
|
(reagent/adapt-react-class class)))
|
||||||
|
|
||||||
(defn get-class [name]
|
(defn get-class [name]
|
||||||
(adapt-class (get-property name)))
|
(adapt-class (get-property name)))
|
||||||
|
|
||||||
(def svg (get-class "Svg"))
|
(def svg (get-class "Svg"))
|
||||||
(def g (get-class "G"))
|
(def g (get-class "G"))
|
||||||
(def rect (get-class "Rect"))
|
(def rect (get-class "Rect"))
|
||||||
(def path (get-class "Path"))
|
(def path (get-class "Path"))
|
||||||
(def use (get-class "Use"))
|
(def use (get-class "Use"))
|
||||||
(def defs (get-class "Defs"))
|
(def defs (get-class "Defs"))
|
||||||
(def circle (get-class "Circle"))
|
(def circle (get-class "Circle")))
|
||||||
|
|
||||||
(def icons {:icons/discover (components.svg/slurp-svg "./resources/icons/bottom/discover_gray.svg")
|
(if platform/desktop?
|
||||||
:icons/contacts (components.svg/slurp-svg "./resources/icons/bottom/contacts_gray.svg")
|
(def icons {:icons/discover (js/require "./resources/icons/bottom/discover_gray.svg")
|
||||||
:icons/home (components.svg/slurp-svg "./resources/icons/bottom/home_gray.svg")
|
:icons/contacts (js/require "./resources/icons/bottom/contacts_gray.svg")
|
||||||
:icons/home-active (components.svg/slurp-svg "./resources/icons/bottom/home_blue.svg")
|
:icons/home (js/require "./resources/icons/bottom/home_gray.svg")
|
||||||
:icons/profile (components.svg/slurp-svg "./resources/icons/bottom/profile_gray.svg")
|
:icons/home-active (js/require "./resources/icons/bottom/home_blue.svg")
|
||||||
:icons/profile-active (components.svg/slurp-svg "./resources/icons/bottom/profile_blue.svg")
|
:icons/profile (js/require "./resources/icons/bottom/profile_gray.svg")
|
||||||
:icons/wallet (components.svg/slurp-svg "./resources/icons/bottom/wallet_gray.svg")
|
:icons/profile-active (js/require "./resources/icons/bottom/profile_blue.svg")
|
||||||
:icons/wallet-active (components.svg/slurp-svg "./resources/icons/bottom/wallet_active.svg")
|
:icons/wallet (js/require "./resources/icons/bottom/wallet_gray.svg")
|
||||||
:icons/speaker (components.svg/slurp-svg "./resources/icons/speaker.svg")
|
:icons/wallet-active (js/require "./resources/icons/bottom/wallet_active.svg")
|
||||||
:icons/speaker-off (components.svg/slurp-svg "./resources/icons/speaker_off.svg")
|
:icons/speaker (js/require "./resources/icons/speaker.svg")
|
||||||
:icons/transaction-history (components.svg/slurp-svg "./resources/icons/transaction_history.svg")
|
:icons/speaker-off (js/require "./resources/icons/speaker_off.svg")
|
||||||
:icons/add (components.svg/slurp-svg "./resources/icons/add.svg")
|
:icons/transaction-history (js/require "./resources/icons/transaction_history.svg")
|
||||||
:icons/add-contact (components.svg/slurp-svg "./resources/icons/add_contact.svg")
|
:icons/add (js/require "./resources/icons/add.svg")
|
||||||
:icons/add-wallet (components.svg/slurp-svg "./resources/icons/add_wallet.svg")
|
:icons/add-contact (js/require "./resources/icons/add_contact.svg")
|
||||||
:icons/address (components.svg/slurp-svg "./resources/icons/address.svg")
|
:icons/add-wallet (js/require "./resources/icons/add_wallet.svg")
|
||||||
:icons/arrow-left (components.svg/slurp-svg "./resources/icons/arrow_left.svg")
|
:icons/address (js/require "./resources/icons/address.svg")
|
||||||
:icons/arrow-right (components.svg/slurp-svg "./resources/icons/arrow_right.svg")
|
:icons/arrow-left (js/require "./resources/icons/arrow_left.svg")
|
||||||
:icons/flash-active (components.svg/slurp-svg "./resources/icons/flash_active.svg")
|
:icons/arrow-right (js/require "./resources/icons/arrow_right.svg")
|
||||||
:icons/flash-inactive (components.svg/slurp-svg "./resources/icons/flash_inactive.svg")
|
:icons/flash-active (js/require "./resources/icons/flash_active.svg")
|
||||||
:icons/attach (components.svg/slurp-svg "./resources/icons/attach.svg")
|
:icons/flash-inactive (js/require "./resources/icons/flash_inactive.svg")
|
||||||
:icons/browse (components.svg/slurp-svg "./resources/icons/browse.svg")
|
:icons/attach (js/require "./resources/icons/attach.svg")
|
||||||
:icons/close (components.svg/slurp-svg "./resources/icons/close.svg")
|
:icons/browse (js/require "./resources/icons/browse.svg")
|
||||||
:icons/copy-from (components.svg/slurp-svg "./resources/icons/copy_from.svg")
|
:icons/close (js/require "./resources/icons/close.svg")
|
||||||
:icons/delete (components.svg/slurp-svg "./resources/icons/delete.svg")
|
:icons/copy-from (js/require "./resources/icons/copy_from.svg")
|
||||||
:icons/dots-horizontal (components.svg/slurp-svg "./resources/icons/dots_horizontal.svg")
|
:icons/delete (js/require "./resources/icons/delete.svg")
|
||||||
:icons/dots-vertical (components.svg/slurp-svg "./resources/icons/dots_vertical.svg")
|
:icons/dots-horizontal (js/require "./resources/icons/dots_horizontal.svg")
|
||||||
:icons/exclamation-mark (components.svg/slurp-svg "./resources/icons/exclamation_mark.svg")
|
:icons/dots-vertical (js/require "./resources/icons/dots_vertical.svg")
|
||||||
:icons/filter (components.svg/slurp-svg "./resources/icons/filter.svg")
|
:icons/exclamation-mark (js/require "./resources/icons/exclamation_mark.svg")
|
||||||
:icons/fullscreen (components.svg/slurp-svg "./resources/icons/fullscreen.svg")
|
:icons/filter (js/require "./resources/icons/filter.svg")
|
||||||
:icons/group-big (components.svg/slurp-svg "./resources/icons/group_big.svg")
|
:icons/fullscreen (js/require "./resources/icons/fullscreen.svg")
|
||||||
:icons/group-chat (components.svg/slurp-svg "./resources/icons/group_chat.svg")
|
:icons/group-big (js/require "./resources/icons/group_big.svg")
|
||||||
:icons/chats (components.svg/slurp-svg "./resources/icons/chats.svg")
|
:icons/group-chat (js/require "./resources/icons/group_chat.svg")
|
||||||
:icons/hamburger (components.svg/slurp-svg "./resources/icons/hamburger.svg")
|
:icons/chats (js/require "./resources/icons/chats.svg")
|
||||||
:icons/hidden (components.svg/slurp-svg "./resources/icons/hidden.svg")
|
:icons/hamburger (js/require "./resources/icons/hamburger.svg")
|
||||||
:icons/in-contacts (components.svg/slurp-svg "./resources/icons/in_contacts.svg")
|
:icons/hidden (js/require "./resources/icons/hidden.svg")
|
||||||
:icons/lock (components.svg/slurp-svg "./resources/icons/lock.svg")
|
:icons/in-contacts (js/require "./resources/icons/in_contacts.svg")
|
||||||
:icons/mic (components.svg/slurp-svg "./resources/icons/mic.svg")
|
:icons/lock (js/require "./resources/icons/lock.svg")
|
||||||
:icons/ok (components.svg/slurp-svg "./resources/icons/ok.svg")
|
:icons/mic (js/require "./resources/icons/mic.svg")
|
||||||
:icons/public (components.svg/slurp-svg "./resources/icons/public.svg")
|
:icons/ok (js/require "./resources/icons/ok.svg")
|
||||||
:icons/public-chat (components.svg/slurp-svg "./resources/icons/public_chat.svg")
|
:icons/public (js/require "./resources/icons/public.svg")
|
||||||
:icons/qr (components.svg/slurp-svg "./resources/icons/QR.svg")
|
:icons/public-chat (js/require "./resources/icons/public_chat.svg")
|
||||||
:icons/input-commands (components.svg/slurp-svg "./resources/icons/input_commands.svg")
|
:icons/qr (js/require "./resources/icons/QR.svg")
|
||||||
:icons/input-send (components.svg/slurp-svg "./resources/icons/input_send.svg")
|
:icons/input-commands (js/require "./resources/icons/input_commands.svg")
|
||||||
:icons/back (components.svg/slurp-svg "./resources/icons/back.svg")
|
:icons/input-send (js/require "./resources/icons/input_send.svg")
|
||||||
:icons/forward (components.svg/slurp-svg "./resources/icons/forward.svg")
|
:icons/back (js/require "./resources/icons/back.svg")
|
||||||
:icons/dropdown-up (components.svg/slurp-svg "./resources/icons/dropdown_up.svg")
|
:icons/forward (js/require "./resources/icons/forward.svg")
|
||||||
:icons/up (components.svg/slurp-svg "./resources/icons/up.svg")
|
:icons/dropdown-up (js/require "./resources/icons/dropdown_up.svg")
|
||||||
:icons/down (components.svg/slurp-svg "./resources/icons/down.svg")
|
:icons/up (js/require "./resources/icons/up.svg")
|
||||||
:icons/grab (components.svg/slurp-svg "./resources/icons/grab.svg")
|
:icons/down (js/require "./resources/icons/down.svg")
|
||||||
:icons/share (components.svg/slurp-svg "./resources/icons/share.svg")
|
:icons/grab (js/require "./resources/icons/grab.svg")
|
||||||
:icons/tooltip-triangle (components.svg/slurp-svg "./resources/icons/tooltip-triangle.svg")
|
:icons/share (js/require "./resources/icons/share.svg")
|
||||||
:icons/open (components.svg/slurp-svg "./resources/icons/open.svg")
|
:icons/tooltip-triangle (js/require "./resources/icons/tooltip-triangle.svg")
|
||||||
:icons/network (components.svg/slurp-svg "./resources/icons/network.svg")
|
:icons/open (js/require "./resources/icons/open.svg")
|
||||||
:icons/wnode (components.svg/slurp-svg "./resources/icons/wnode.svg")
|
:icons/network (js/require "./resources/icons/network.svg")
|
||||||
:icons/refresh (components.svg/slurp-svg "./resources/icons/refresh.svg")
|
:icons/wnode (js/require "./resources/icons/wnode.svg")
|
||||||
:icons/newchat (components.svg/slurp-svg "./resources/icons/newchat.svg")
|
:icons/refresh (js/require "./resources/icons/refresh.svg")
|
||||||
:icons/logo (components.svg/slurp-svg "./resources/icons/logo.svg")
|
:icons/newchat (js/require "./resources/icons/newchat.svg")
|
||||||
:icons/camera (components.svg/slurp-svg "./resources/icons/camera.svg")
|
:icons/logo (js/require "./resources/icons/logo.svg")
|
||||||
:icons/check (components.svg/slurp-svg "./resources/icons/check.svg")
|
:icons/camera (js/require "./resources/icons/camera.svg")
|
||||||
:icons/dots (components.svg/slurp-svg "./resources/icons/dots.svg")
|
:icons/check (js/require "./resources/icons/check.svg")
|
||||||
:icons/warning (components.svg/slurp-svg "./resources/icons/warning.svg")})
|
:icons/dots (js/require "./resources/icons/dots.svg")
|
||||||
|
:icons/warning (js/require "./resources/icons/warning.svg")})
|
||||||
|
(def icons {:icons/discover (components.svg/slurp-svg "./resources/icons/bottom/discover_gray.svg")
|
||||||
|
:icons/contacts (components.svg/slurp-svg "./resources/icons/bottom/contacts_gray.svg")
|
||||||
|
:icons/home (components.svg/slurp-svg "./resources/icons/bottom/home_gray.svg")
|
||||||
|
:icons/home-active (components.svg/slurp-svg "./resources/icons/bottom/home_blue.svg")
|
||||||
|
:icons/profile (components.svg/slurp-svg "./resources/icons/bottom/profile_gray.svg")
|
||||||
|
:icons/profile-active (components.svg/slurp-svg "./resources/icons/bottom/profile_blue.svg")
|
||||||
|
:icons/wallet (components.svg/slurp-svg "./resources/icons/bottom/wallet_gray.svg")
|
||||||
|
:icons/wallet-active (components.svg/slurp-svg "./resources/icons/bottom/wallet_active.svg")
|
||||||
|
:icons/speaker (components.svg/slurp-svg "./resources/icons/speaker.svg")
|
||||||
|
:icons/speaker-off (components.svg/slurp-svg "./resources/icons/speaker_off.svg")
|
||||||
|
:icons/transaction-history (components.svg/slurp-svg "./resources/icons/transaction_history.svg")
|
||||||
|
:icons/add (components.svg/slurp-svg "./resources/icons/add.svg")
|
||||||
|
:icons/add-contact (components.svg/slurp-svg "./resources/icons/add_contact.svg")
|
||||||
|
:icons/add-wallet (components.svg/slurp-svg "./resources/icons/add_wallet.svg")
|
||||||
|
:icons/address (components.svg/slurp-svg "./resources/icons/address.svg")
|
||||||
|
:icons/arrow-left (components.svg/slurp-svg "./resources/icons/arrow_left.svg")
|
||||||
|
:icons/arrow-right (components.svg/slurp-svg "./resources/icons/arrow_right.svg")
|
||||||
|
:icons/flash-active (components.svg/slurp-svg "./resources/icons/flash_active.svg")
|
||||||
|
:icons/flash-inactive (components.svg/slurp-svg "./resources/icons/flash_inactive.svg")
|
||||||
|
:icons/attach (components.svg/slurp-svg "./resources/icons/attach.svg")
|
||||||
|
:icons/browse (components.svg/slurp-svg "./resources/icons/browse.svg")
|
||||||
|
:icons/close (components.svg/slurp-svg "./resources/icons/close.svg")
|
||||||
|
:icons/copy-from (components.svg/slurp-svg "./resources/icons/copy_from.svg")
|
||||||
|
:icons/delete (components.svg/slurp-svg "./resources/icons/delete.svg")
|
||||||
|
:icons/dots-horizontal (components.svg/slurp-svg "./resources/icons/dots_horizontal.svg")
|
||||||
|
:icons/dots-vertical (components.svg/slurp-svg "./resources/icons/dots_vertical.svg")
|
||||||
|
:icons/exclamation-mark (components.svg/slurp-svg "./resources/icons/exclamation_mark.svg")
|
||||||
|
:icons/filter (components.svg/slurp-svg "./resources/icons/filter.svg")
|
||||||
|
:icons/fullscreen (components.svg/slurp-svg "./resources/icons/fullscreen.svg")
|
||||||
|
:icons/group-big (components.svg/slurp-svg "./resources/icons/group_big.svg")
|
||||||
|
:icons/group-chat (components.svg/slurp-svg "./resources/icons/group_chat.svg")
|
||||||
|
:icons/chats (components.svg/slurp-svg "./resources/icons/chats.svg")
|
||||||
|
:icons/hamburger (components.svg/slurp-svg "./resources/icons/hamburger.svg")
|
||||||
|
:icons/hidden (components.svg/slurp-svg "./resources/icons/hidden.svg")
|
||||||
|
:icons/in-contacts (components.svg/slurp-svg "./resources/icons/in_contacts.svg")
|
||||||
|
:icons/lock (components.svg/slurp-svg "./resources/icons/lock.svg")
|
||||||
|
:icons/mic (components.svg/slurp-svg "./resources/icons/mic.svg")
|
||||||
|
:icons/ok (components.svg/slurp-svg "./resources/icons/ok.svg")
|
||||||
|
:icons/public (components.svg/slurp-svg "./resources/icons/public.svg")
|
||||||
|
:icons/public-chat (components.svg/slurp-svg "./resources/icons/public_chat.svg")
|
||||||
|
:icons/qr (components.svg/slurp-svg "./resources/icons/QR.svg")
|
||||||
|
:icons/input-commands (components.svg/slurp-svg "./resources/icons/input_commands.svg")
|
||||||
|
:icons/input-send (components.svg/slurp-svg "./resources/icons/input_send.svg")
|
||||||
|
:icons/back (components.svg/slurp-svg "./resources/icons/back.svg")
|
||||||
|
:icons/forward (components.svg/slurp-svg "./resources/icons/forward.svg")
|
||||||
|
:icons/dropdown-up (components.svg/slurp-svg "./resources/icons/dropdown_up.svg")
|
||||||
|
:icons/up (components.svg/slurp-svg "./resources/icons/up.svg")
|
||||||
|
:icons/down (components.svg/slurp-svg "./resources/icons/down.svg")
|
||||||
|
:icons/grab (components.svg/slurp-svg "./resources/icons/grab.svg")
|
||||||
|
:icons/share (components.svg/slurp-svg "./resources/icons/share.svg")
|
||||||
|
:icons/tooltip-triangle (components.svg/slurp-svg "./resources/icons/tooltip-triangle.svg")
|
||||||
|
:icons/open (components.svg/slurp-svg "./resources/icons/open.svg")
|
||||||
|
:icons/network (components.svg/slurp-svg "./resources/icons/network.svg")
|
||||||
|
:icons/wnode (components.svg/slurp-svg "./resources/icons/wnode.svg")
|
||||||
|
:icons/refresh (components.svg/slurp-svg "./resources/icons/refresh.svg")
|
||||||
|
:icons/newchat (components.svg/slurp-svg "./resources/icons/newchat.svg")
|
||||||
|
:icons/logo (components.svg/slurp-svg "./resources/icons/logo.svg")
|
||||||
|
:icons/camera (components.svg/slurp-svg "./resources/icons/camera.svg")
|
||||||
|
:icons/check (components.svg/slurp-svg "./resources/icons/check.svg")
|
||||||
|
:icons/dots (components.svg/slurp-svg "./resources/icons/dots.svg")
|
||||||
|
:icons/warning (components.svg/slurp-svg "./resources/icons/warning.svg")}))
|
||||||
|
|
||||||
(defn normalize-property-name [n]
|
(defn normalize-property-name [n]
|
||||||
(if (= n :icons/options)
|
(if (= n :icons/options)
|
||||||
(if platform/ios? :icons/dots-horizontal :icons/dots-vertical)
|
(if platform/ios? :icons/dots-horizontal :icons/dots-vertical)
|
||||||
n))
|
n))
|
||||||
|
|
||||||
(defn icon
|
(if platform/desktop?
|
||||||
([name] (icon name nil))
|
(do (def default-viewbox {:width 24 :height 24})
|
||||||
([name {:keys [color container-style style accessibility-label width height]
|
|
||||||
:or {accessibility-label :icon}}]
|
(defn icon
|
||||||
^{:key name}
|
([name] (icon name nil))
|
||||||
[react/view {:style container-style
|
([name {:keys [color container-style style accessibility-label width height]
|
||||||
:accessibility-label accessibility-label}
|
:or {accessibility-label :icon}}]
|
||||||
(if-let [icon-fn (get icons (normalize-property-name name))]
|
(let [icon-style (if width
|
||||||
(let [icon-vec (icon-fn
|
(assoc default-viewbox :width width :height height)
|
||||||
(cond
|
default-viewbox)]
|
||||||
(keyword? color)
|
[react/view {:style container-style
|
||||||
(case color
|
:accessibility-label accessibility-label}
|
||||||
:dark styles/icon-dark-color
|
[react/image {:source (get icons (normalize-property-name name))
|
||||||
:gray styles/icon-gray-color
|
:style (merge icon-style style)}]]))))
|
||||||
:blue styles/color-light-blue
|
(do (defn icon
|
||||||
:active styles/color-blue4
|
([name] (icon name nil))
|
||||||
:white styles/color-white
|
([name {:keys [color container-style style accessibility-label width height]
|
||||||
:red styles/icon-red-color
|
:or {accessibility-label :icon}}]
|
||||||
styles/icon-dark-color)
|
^{:key name}
|
||||||
(string? color)
|
[react/view {:style container-style
|
||||||
color
|
:accessibility-label accessibility-label}
|
||||||
:else
|
(if-let [icon-fn (get icons (normalize-property-name name))]
|
||||||
styles/icon-dark-color))]
|
(let [icon-vec (icon-fn
|
||||||
(if width
|
(cond
|
||||||
(update icon-vec 1 assoc :width width :height height)
|
(keyword? color)
|
||||||
icon-vec))
|
(case color
|
||||||
(throw (js/Error. (str "Unknown icon: " name))))]))
|
:dark styles/icon-dark-color
|
||||||
|
:gray styles/icon-gray-color
|
||||||
|
:blue styles/color-light-blue
|
||||||
|
:active styles/color-blue4
|
||||||
|
:white styles/color-white
|
||||||
|
:red styles/icon-red-color
|
||||||
|
styles/icon-dark-color)
|
||||||
|
(string? color)
|
||||||
|
color
|
||||||
|
:else
|
||||||
|
styles/icon-dark-color))]
|
||||||
|
(if width
|
||||||
|
(update icon-vec 1 assoc :width width :height height)
|
||||||
|
icon-vec))
|
||||||
|
(throw (js/Error. (str "Unknown icon: " name))))]))))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.ui.components.text-input.styles
|
(ns status-im.ui.components.text-input.styles
|
||||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||||
(:require [status-im.ui.components.colors :as colors]))
|
(:require [status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.utils.platform :as p]))
|
||||||
|
|
||||||
(def label
|
(def label
|
||||||
{:font-size 14
|
{:font-size 14
|
||||||
|
@ -15,11 +16,12 @@
|
||||||
:border-radius 8
|
:border-radius 8
|
||||||
:background-color colors/gray-lighter})
|
:background-color colors/gray-lighter})
|
||||||
|
|
||||||
(def input
|
(defstyle input
|
||||||
{:font-size 15
|
{:font-size 15
|
||||||
:letter-spacing -0.2
|
:letter-spacing -0.2
|
||||||
:color colors/black
|
:color colors/black
|
||||||
:padding 0})
|
:padding 0
|
||||||
|
:desktop {:height 52}})
|
||||||
|
|
||||||
(defn error [label?]
|
(defn error [label?]
|
||||||
{:bottom-value (if label? -20 0)
|
{:bottom-value (if label? -20 0)
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
(ns status-im.ui.screens.add-new.new-public-chat.subs
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.ui.screens.add-new.new-public-chat.db :as db]
|
||||||
|
[cljs.spec.alpha :as spec]))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:new-topic-error-message
|
||||||
|
:<- [:get :public-group-topic]
|
||||||
|
(fn [topic]
|
||||||
|
(when-not (spec/valid? ::db/topic topic)
|
||||||
|
(i18n/label :topic-name-error))))
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
;; initial state of app-db
|
;; initial state of app-db
|
||||||
(def app-db {:current-public-key nil
|
(def app-db {:current-public-key nil
|
||||||
:status-module-initialized? (or platform/ios? js/goog.DEBUG)
|
:status-module-initialized? (or platform/ios? js/goog.DEBUG platform/desktop?)
|
||||||
:keyboard-height 0
|
:keyboard-height 0
|
||||||
:tab-bar-visible? true
|
:tab-bar-visible? true
|
||||||
:navigation-stack '()
|
:navigation-stack '()
|
||||||
|
@ -51,6 +51,7 @@
|
||||||
:chat/cooldown-enabled? false
|
:chat/cooldown-enabled? false
|
||||||
:chat/last-outgoing-message-sent-at 0
|
:chat/last-outgoing-message-sent-at 0
|
||||||
:chat/spam-messages-frequency 0
|
:chat/spam-messages-frequency 0
|
||||||
|
:tooltips {}
|
||||||
:desktop/desktop {:tab-view-id :home}
|
:desktop/desktop {:tab-view-id :home}
|
||||||
:dimensions/window (dimensions/window)})
|
:dimensions/window (dimensions/window)})
|
||||||
|
|
||||||
|
@ -128,6 +129,7 @@
|
||||||
:navigation.screen-params/collectibles-list])))
|
:navigation.screen-params/collectibles-list])))
|
||||||
|
|
||||||
(spec/def :desktop/desktop (spec/nilable any?))
|
(spec/def :desktop/desktop (spec/nilable any?))
|
||||||
|
(spec/def ::tooltips (spec/nilable any?))
|
||||||
|
|
||||||
;;;;NETWORK
|
;;;;NETWORK
|
||||||
|
|
||||||
|
@ -216,6 +218,7 @@
|
||||||
::modal
|
::modal
|
||||||
::was-modal?
|
::was-modal?
|
||||||
::rpc-url
|
::rpc-url
|
||||||
|
::tooltips
|
||||||
::web3
|
::web3
|
||||||
::web3-node-version
|
::web3-node-version
|
||||||
::webview-bridge
|
::webview-bridge
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
(ns status-im.ui.screens.desktop.main.add-new.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(def new-contact-view
|
||||||
|
{:flex 1
|
||||||
|
:background-color colors/white
|
||||||
|
:margin-left 24
|
||||||
|
:margin-right 37})
|
||||||
|
|
||||||
|
(def new-contact-title
|
||||||
|
{:height 64
|
||||||
|
:align-items :flex-start
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def new-contact-title-text
|
||||||
|
{:font-size 20
|
||||||
|
:color :black
|
||||||
|
:font-weight "600"})
|
||||||
|
|
||||||
|
(def new-contact-subtitle
|
||||||
|
{:font-size 14})
|
||||||
|
|
||||||
|
(def new-contact-separator
|
||||||
|
{:height 1
|
||||||
|
:background-color colors/gray-light})
|
||||||
|
|
||||||
|
(def add-contact-edit-view
|
||||||
|
{:height 45
|
||||||
|
:margin-bottom 32
|
||||||
|
:background-color colors/white
|
||||||
|
:border-radius 12
|
||||||
|
:flex-direction :row
|
||||||
|
:margin-top 16})
|
||||||
|
|
||||||
|
(def add-contact-input
|
||||||
|
{:font-size 14
|
||||||
|
:background-color colors/gray-lighter
|
||||||
|
:margin-right 12
|
||||||
|
:border-radius 8})
|
||||||
|
|
||||||
|
(defn add-contact-button [error?]
|
||||||
|
{:width 140
|
||||||
|
:height 45
|
||||||
|
:border-radius 8
|
||||||
|
:background-color (if error? colors/gray-lighter colors/blue)
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(defn add-contact-button-text [error?]
|
||||||
|
{:font-size 16
|
||||||
|
:color (if error? colors/gray colors/white)})
|
||||||
|
|
||||||
|
(def suggested-contact-view
|
||||||
|
{:flex-direction "row"
|
||||||
|
:align-items :center
|
||||||
|
:margin-bottom 16})
|
||||||
|
|
||||||
|
(def suggested-contacts
|
||||||
|
{:margin-top 12})
|
||||||
|
|
||||||
|
(def suggested-contact-image
|
||||||
|
{:width 46
|
||||||
|
:height 46
|
||||||
|
:border-radius 46
|
||||||
|
:margin-right 16})
|
||||||
|
|
||||||
|
(def suggested-topic-image
|
||||||
|
(merge suggested-contact-image
|
||||||
|
{:background-color colors/blue
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center}))
|
||||||
|
|
||||||
|
(def suggested-topic-text
|
||||||
|
{:font-size 25.6
|
||||||
|
:color colors/white})
|
|
@ -1,47 +1,97 @@
|
||||||
(ns status-im.ui.screens.desktop.main.add-new.views
|
(ns status-im.ui.screens.desktop.main.add-new.views
|
||||||
(:require-macros [status-im.utils.views :as views])
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [status-im.ui.components.icons.vector-icons :as icons]
|
(:require [status-im.ui.components.icons.vector-icons :as icons]
|
||||||
|
[status-im.ui.screens.add-new.new-public-chat.view :as public-chat]
|
||||||
|
[status-im.ui.components.list.views :as list]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.ui.screens.desktop.main.add-new.styles :as styles]
|
||||||
|
[status-im.ui.screens.add-new.new-public-chat.view :refer [default-public-chats]]
|
||||||
|
[status-im.ui.screens.add-new.new-public-chat.db :as public-chat-db]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
[status-im.ui.components.react :as react]))
|
[status-im.ui.components.react :as react]))
|
||||||
|
|
||||||
(views/defview new-contact []
|
(views/defview new-contact []
|
||||||
(views/letsubs [new-contact-identity [:get :contacts/new-identity]
|
(views/letsubs [new-contact-identity [:get :contacts/new-identity]
|
||||||
topic [:get :public-group-topic]]
|
contacts [:all-added-people-contacts]
|
||||||
[react/view {:style {:flex 1 :background-color "#eef2f5"}}
|
chat-error [:new-contact-error-message]
|
||||||
^{:key "newcontact"}
|
topic [:get :public-group-topic]
|
||||||
[react/view {:style {:height 64 :align-items :center :padding-horizontal 11 :justify-content :center}}
|
topic-error [:new-topic-error-message]
|
||||||
[react/text {:style {:font-size 16 :color :black :font-weight "600"}}
|
account [:get-current-account]
|
||||||
"Add new contact"]]
|
topic-input-ref (atom nil)]
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
|
[react/scroll-view
|
||||||
[react/view {:style {:height 90 :margin-horizontal 16 :margin-bottom 16 :background-color :white :border-radius 12}}
|
[react/view {:style styles/new-contact-view}
|
||||||
;:box-shadow "0 0.5px 4.5px 0 rgba(0, 0, 0, 0.04)"}}
|
^{:key "newcontact"}
|
||||||
[react/view {:style {:flex-direction :row :margin-horizontal 16 :margin-top 16}}
|
[react/view {:style styles/new-contact-title}
|
||||||
|
[react/text {:style styles/new-contact-title-text}
|
||||||
|
(i18n/label :new-chat)]]
|
||||||
|
[react/text {:style styles/new-contact-subtitle} (i18n/label :contact-code)]
|
||||||
|
[react/view {:style styles/new-contact-separator}]
|
||||||
|
[react/view {:style styles/add-contact-edit-view}
|
||||||
|
[react/text-input {:placeholder "0x..."
|
||||||
|
:flex 1
|
||||||
|
:style styles/add-contact-input
|
||||||
|
:on-change (fn [e]
|
||||||
|
(let [native-event (.-nativeEvent e)
|
||||||
|
text (.-text native-event)]
|
||||||
|
(re-frame/dispatch [:set :contacts/new-identity text])))}]
|
||||||
|
[react/touchable-highlight {:disabled chat-error :on-press #(when-not chat-error (re-frame/dispatch [:add-contact-handler new-contact-identity]))}
|
||||||
|
[react/view
|
||||||
|
{:style (styles/add-contact-button chat-error)}
|
||||||
|
[react/text
|
||||||
|
{:style (styles/add-contact-button-text chat-error)}
|
||||||
|
(i18n/label :start-chat)]]]]
|
||||||
|
^{:key "choosecontact"}
|
||||||
|
[react/view
|
||||||
|
(when (seq contacts) [react/text {:style styles/new-contact-subtitle} (i18n/label :or-choose-a-contact)])
|
||||||
|
[react/view {:style styles/suggested-contacts}
|
||||||
|
(doall
|
||||||
|
(for [c contacts]
|
||||||
|
^{:key (:whisper-identity c)}
|
||||||
|
[react/touchable-highlight {:on-press #(do
|
||||||
|
(re-frame/dispatch [:set :contacts/new-identity (:whisper-identity c)])
|
||||||
|
(re-frame/dispatch [:add-contact-handler (:whisper-identity c)]))}
|
||||||
|
[react/view {:style styles/suggested-contact-view}
|
||||||
|
[react/image {:style styles/suggested-contact-image
|
||||||
|
:source {:uri (:photo-path c)}}]
|
||||||
|
[react/text {:style styles/new-contact-subtitle} (:name c)]]]))]]
|
||||||
|
^{:key "publicchat"}
|
||||||
|
[react/view {:style styles/new-contact-title}
|
||||||
|
[react/text {:style styles/new-contact-title-text}
|
||||||
|
(i18n/label :new-public-group-chat)]]
|
||||||
|
[react/text {:style styles/new-contact-subtitle} (i18n/label :public-group-topic)]
|
||||||
|
[react/view {:style styles/new-contact-separator}]
|
||||||
|
[react/view {:style styles/add-contact-edit-view}
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
[react/text-input {:placeholder "Contact key"
|
[react/text-input {:flex 1
|
||||||
|
:ref #(when (and (nil? @topic-input-ref) %)
|
||||||
|
(.setNativeProps % (js-obj "text" "#"))
|
||||||
|
(reset! topic-input-ref %))
|
||||||
|
:style styles/add-contact-input
|
||||||
:on-change (fn [e]
|
:on-change (fn [e]
|
||||||
(let [native-event (.-nativeEvent e)
|
(let [native-event (.-nativeEvent e)
|
||||||
text (.-text native-event)]
|
text (.-text native-event)
|
||||||
(re-frame/dispatch [:set :contacts/new-identity text])))}]]
|
[_ before after] (first (re-seq #"(.*)\#(.*)" text))]
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:add-contact-handler new-contact-identity])}
|
(.setNativeProps @topic-input-ref (js-obj "text" (str "#" before after)))
|
||||||
[react/view {:style {:margin-left 16 :width 30 :height 30 :border-radius 15 :background-color "#eef2f5" :align-items :center
|
(re-frame/dispatch [:set :public-group-topic (subs text 1)])))}]]
|
||||||
:justify-content :center}}
|
[react/touchable-highlight {:disabled topic-error
|
||||||
[icons/icon :icons/ok]]]]]
|
:on-press #(when-not topic-error
|
||||||
^{:key "publicchat"}
|
(do
|
||||||
[react/view {:style {:height 64 :align-items :center :padding-horizontal 11 :justify-content :center}}
|
(re-frame/dispatch [:set :public-group-topic nil])
|
||||||
[react/text {:style {:font-size 16 :color :black :font-weight "600"}}
|
(re-frame/dispatch [:create-new-public-chat topic])))}
|
||||||
"Join to public chat"]]
|
[react/view {:style (styles/add-contact-button topic-error)}
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
|
[react/text {:style (styles/add-contact-button-text topic-error)}
|
||||||
[react/view {:style {:height 90 :margin-horizontal 16 :margin-bottom 16 :background-color :white :border-radius 12}}
|
(i18n/label :new-public-group-chat)]]]]
|
||||||
;:box-shadow "0 0.5px 4.5px 0 rgba(0, 0, 0, 0.04)"}}
|
[react/text {:style styles/new-contact-subtitle} (i18n/label :selected-for-you)]
|
||||||
[react/view {:style {:flex-direction :row :margin-horizontal 16 :margin-top 16}}
|
[react/view {:style styles/suggested-contacts}
|
||||||
[react/text "#"]
|
(doall
|
||||||
[react/view {:style {:flex 1}}
|
(for [topic public-chat/default-public-chats]
|
||||||
[react/text-input {:placeholder "topic"
|
^{:key topic}
|
||||||
:on-change (fn [e]
|
[react/touchable-highlight {:on-press #(do
|
||||||
(let [native-event (.-nativeEvent e)
|
(re-frame/dispatch [:set :public-group-topic nil])
|
||||||
text (.-text native-event)]
|
(re-frame/dispatch [:create-new-public-chat topic]))}
|
||||||
(re-frame/dispatch [:set :public-group-topic text])))}]]
|
[react/view {:style styles/suggested-contact-view}
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:create-new-public-chat topic])}
|
[react/view {:style styles/suggested-topic-image}
|
||||||
[react/view {:style {:margin-left 16 :width 30 :height 30 :border-radius 15 :background-color "#eef2f5" :align-items :center
|
[react/text {:style styles/suggested-topic-text} (string/capitalize (first topic))]]
|
||||||
:justify-content :center}}
|
[react/text {:style styles/new-contact-subtitle} topic]]]))]]]))
|
||||||
[icons/icon :icons/ok]]]]]]))
|
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
(ns status-im.ui.screens.desktop.main.chat.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(defn message-box [{:keys [outgoing] :as message}]
|
||||||
|
(let [align (if outgoing :flex-end :flex-start)
|
||||||
|
color (if outgoing colors/hawkes-blue colors/white)]
|
||||||
|
{:align-self align
|
||||||
|
:background-color color
|
||||||
|
:border-radius 8
|
||||||
|
:padding-left 12
|
||||||
|
:padding-right 12
|
||||||
|
:padding-top 10
|
||||||
|
:padding-bottom 10
|
||||||
|
:max-width 340}))
|
||||||
|
|
||||||
|
(defn message-row [{:keys [outgoing first-in-group?] :as message}]
|
||||||
|
(let [padding-horizontal (if outgoing :padding-right :padding-left)
|
||||||
|
padding-top-value (if first-in-group? 16 8)]
|
||||||
|
{padding-horizontal 24
|
||||||
|
:padding-top padding-top-value}))
|
||||||
|
|
||||||
|
(def message-row-column
|
||||||
|
{:flex-direction :column})
|
||||||
|
|
||||||
|
(defn message-timestamp-placeholder []
|
||||||
|
{:color colors/transparent
|
||||||
|
:font-size 10
|
||||||
|
:align-self :flex-end
|
||||||
|
:opacity 0.5
|
||||||
|
:text-align :right
|
||||||
|
:text-align-vertical :center
|
||||||
|
:width 60})
|
||||||
|
|
||||||
|
(defn message-timestamp []
|
||||||
|
(merge (message-timestamp-placeholder)
|
||||||
|
{:color colors/gray
|
||||||
|
:position :absolute
|
||||||
|
:bottom 0
|
||||||
|
:right -5}))
|
||||||
|
|
||||||
|
(def author
|
||||||
|
{:color colors/gray
|
||||||
|
:font-size 12
|
||||||
|
:margin-left 48
|
||||||
|
:margin-bottom 4})
|
||||||
|
|
||||||
|
(def chat-box
|
||||||
|
{:height 68
|
||||||
|
:background-color :white
|
||||||
|
:border-radius 12
|
||||||
|
:margin-horizontal 24
|
||||||
|
:padding-vertical 15})
|
||||||
|
|
||||||
|
(def chat-box-inner
|
||||||
|
{:flex-direction :row
|
||||||
|
:flex 1})
|
||||||
|
|
||||||
|
(def chat-text-input
|
||||||
|
{:flex 1})
|
||||||
|
|
||||||
|
(def messages-view
|
||||||
|
{:flex 1
|
||||||
|
:background-color colors/gray-lighter})
|
||||||
|
|
||||||
|
(def messages-scrollview-inner
|
||||||
|
{:padding-vertical 46})
|
||||||
|
|
||||||
|
(def photo-style
|
||||||
|
{:borderRadius 20
|
||||||
|
:width 40
|
||||||
|
:height 40
|
||||||
|
:margin-right 8})
|
||||||
|
|
||||||
|
(def toolbar-chat-view
|
||||||
|
{:align-items :center
|
||||||
|
:padding 11
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def toolbar-chat-name
|
||||||
|
{:font-size 16
|
||||||
|
:color :black
|
||||||
|
:font-weight "600"})
|
||||||
|
|
||||||
|
(def add-contact
|
||||||
|
{:background-color :white
|
||||||
|
:border-radius 6
|
||||||
|
:margin-top 3
|
||||||
|
:padding 4})
|
||||||
|
|
||||||
|
(def add-contact-text
|
||||||
|
{:font-size 14
|
||||||
|
:color colors/gray})
|
||||||
|
|
||||||
|
(def message-text
|
||||||
|
{:font-size 14})
|
||||||
|
|
||||||
|
(def message-wrapper
|
||||||
|
{:flex-direction :row
|
||||||
|
:flex-wrap :wrap})
|
||||||
|
|
||||||
|
(def not-first-in-group-wrapper
|
||||||
|
{:flex-direction :row})
|
||||||
|
|
||||||
|
(def send-icon
|
||||||
|
{:margin-left 16
|
||||||
|
:width 30
|
||||||
|
:height 30
|
||||||
|
:border-radius 15
|
||||||
|
:background-color colors/gray-lighter
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center
|
||||||
|
:transform [{:rotate "90deg"}]})
|
||||||
|
|
||||||
|
(def chat-view
|
||||||
|
{:flex 1
|
||||||
|
:background-color :white})
|
|
@ -5,12 +5,16 @@
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[status-im.chat.styles.message.message :as message.style]
|
[status-im.chat.styles.message.message :as message.style]
|
||||||
[status-im.utils.gfycat.core :as gfycat.core]
|
[status-im.utils.gfycat.core :as gfycat.core]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
[status-im.utils.gfycat.core :as gfycat]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.utils.identicon :as identicon]
|
[status-im.utils.identicon :as identicon]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.datetime :as time]
|
||||||
[status-im.ui.components.styles :as styles]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.react :as react]))
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.chat.views.message.datemark :as message.datemark]
|
||||||
|
[status-im.ui.screens.desktop.main.chat.styles :as styles]
|
||||||
|
[status-im.i18n :as i18n]))
|
||||||
|
|
||||||
(views/defview toolbar-chat-view []
|
(views/defview toolbar-chat-view []
|
||||||
(views/letsubs [{:keys [chat-id name public-key public? group-chat]} [:get-current-chat]
|
(views/letsubs [{:keys [chat-id name public-key public? group-chat]} [:get-current-chat]
|
||||||
|
@ -20,43 +24,33 @@
|
||||||
(if (string/blank? name)
|
(if (string/blank? name)
|
||||||
(gfycat.core/generate-gfy public-key)
|
(gfycat.core/generate-gfy public-key)
|
||||||
(or name
|
(or name
|
||||||
"Chat name")))]
|
(i18n/label :t/chat-name))))]
|
||||||
[react/view {:style {:align-items :center :padding 11 :justify-content :center}}
|
[react/view {:style styles/toolbar-chat-view}
|
||||||
[react/view {:style {:flex-direction :row}}
|
[react/view {:style {:flex-direction :row}}
|
||||||
(when public?
|
(when public?
|
||||||
[icons/icon :icons/public-chat])
|
[icons/icon :icons/public-chat])
|
||||||
(when (and group-chat (not public?))
|
(when (and group-chat (not public?))
|
||||||
[icons/icon :icons/group-chat])
|
[icons/icon :icons/group-chat])
|
||||||
[react/text {:style {:font-size 16 :color :black :font-weight "600"}}
|
[react/text {:style styles/toolbar-chat-name}
|
||||||
chat-name]]
|
chat-name]]
|
||||||
(when pending?
|
(when pending?
|
||||||
[react/touchable-highlight
|
[react/touchable-highlight
|
||||||
{:on-press #(re-frame/dispatch [:add-pending-contact chat-id])}
|
{:on-press #(re-frame/dispatch [:add-pending-contact chat-id])}
|
||||||
[react/view {:style {:background-color :white :border-radius 6 :margin-top 3 :padding 4}} ;style/add-contact
|
[react/view {:style styles/add-contact} ;style/add-contact
|
||||||
[react/text {:style {:font-size 14 :color "#939ba1"}}
|
[react/text {:style styles/add-contact-text}
|
||||||
"Add to contacts"]]])])))
|
(i18n/label :t/add-to-contacts)]]])])))
|
||||||
|
|
||||||
(views/defview message-author-name [{:keys [outgoing from] :as message}]
|
(views/defview message-author-name [{:keys [outgoing from] :as message}]
|
||||||
(views/letsubs [current-account [:get-current-account]
|
(views/letsubs [current-account [:get-current-account]
|
||||||
incoming-name [:get-contact-name-by-identity from]]
|
incoming-name [:get-contact-name-by-identity from]]
|
||||||
(if outgoing
|
(let [name (or incoming-name (gfycat/generate-gfy from))]
|
||||||
[react/text {:style message.style/author} (:name current-account)]
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-contact-dialog from name (boolean incoming-name)])}
|
||||||
(let [name (or incoming-name (gfycat/generate-gfy from))]
|
[react/text {:style styles/author} name]])))
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-contact-dialog from name (boolean incoming-name)])}
|
|
||||||
[react/text {:style message.style/author} name]]))))
|
|
||||||
|
|
||||||
(def photo-style
|
|
||||||
{:borderRadius 15
|
|
||||||
:width 30
|
|
||||||
:height 30})
|
|
||||||
|
|
||||||
(views/defview member-photo [from]
|
(views/defview member-photo [from]
|
||||||
(views/letsubs [photo-path nil];[:photo-path from]]
|
[react/view
|
||||||
[react/view
|
[react/image {:source {:uri (identicon/identicon from)}
|
||||||
[react/image {:source {:uri (if (string/blank? photo-path)
|
:style styles/photo-style}]])
|
||||||
(identicon/identicon from)
|
|
||||||
photo-path)}
|
|
||||||
:style photo-style}]]))
|
|
||||||
|
|
||||||
(views/defview my-photo [from]
|
(views/defview my-photo [from]
|
||||||
(views/letsubs [account [:get-current-account]]
|
(views/letsubs [account [:get-current-account]]
|
||||||
|
@ -65,16 +59,42 @@
|
||||||
[react/image {:source {:uri (if (string/blank? photo-path)
|
[react/image {:source {:uri (if (string/blank? photo-path)
|
||||||
(identicon/identicon from)
|
(identicon/identicon from)
|
||||||
photo-path)}
|
photo-path)}
|
||||||
:style photo-style}]])))
|
:style styles/photo-style}]])))
|
||||||
|
|
||||||
(defn message [text me? {:keys [outgoing message-id chat-id message-status user-statuses timestamp
|
(views/defview message-with-timestamp [text {:keys [timestamp] :as message} style]
|
||||||
from current-public-key content-type group-chat type value] :as message}]
|
[react/view {:style style}
|
||||||
|
[react/view {:style styles/message-wrapper}
|
||||||
|
[react/text {:style styles/message-text
|
||||||
|
:selectable true}
|
||||||
|
text]
|
||||||
|
[react/text {:style (styles/message-timestamp-placeholder)}
|
||||||
|
(time/timestamp->time timestamp)]
|
||||||
|
[react/text {:style (styles/message-timestamp)}
|
||||||
|
(time/timestamp->time timestamp)]]])
|
||||||
|
|
||||||
|
(views/defview text-only-message [text message]
|
||||||
|
[react/view {:style (styles/message-row message)}
|
||||||
|
[message-with-timestamp text message (styles/message-box message)]])
|
||||||
|
|
||||||
|
(views/defview photo-placeholder []
|
||||||
|
[react/view {:style styles/photo-style}])
|
||||||
|
|
||||||
|
(views/defview message-with-name-and-avatar [text {:keys [from first-in-group? last-in-group?] :as message}]
|
||||||
|
[react/view {:style (styles/message-row message)}
|
||||||
|
[react/view {:style styles/message-row-column}
|
||||||
|
(when first-in-group?
|
||||||
|
[message-author-name message])
|
||||||
|
[react/view {:style styles/not-first-in-group-wrapper}
|
||||||
|
(if last-in-group?
|
||||||
|
[member-photo from]
|
||||||
|
[photo-placeholder])
|
||||||
|
[message-with-timestamp text message (styles/message-box message)]]]])
|
||||||
|
|
||||||
|
(defn message [text me? {:keys [message-id chat-id message-status user-statuses from
|
||||||
|
current-public-key content-type group-chat outgoing type value] :as message}]
|
||||||
(if (= type :datemark)
|
(if (= type :datemark)
|
||||||
^{:key (str "datemark" message-id)}
|
^{:key (str "datemark" message-id)}
|
||||||
[react/view {:style {:margin-vertical 20}}
|
[message.datemark/chat-datemark value]
|
||||||
[react/text
|
|
||||||
(string/capitalize (last (string/split value #"-")))]
|
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec"}}]]
|
|
||||||
(when (= content-type constants/text-content-type)
|
(when (= content-type constants/text-content-type)
|
||||||
(reagent.core/create-class
|
(reagent.core/create-class
|
||||||
{:component-did-mount
|
{:component-did-mount
|
||||||
|
@ -89,19 +109,9 @@
|
||||||
:reagent-render
|
:reagent-render
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "message" message-id)}
|
^{:key (str "message" message-id)}
|
||||||
[react/view {:style {:flex-direction :row :flex 1 :margin-vertical 12}}
|
(if (and group-chat (not outgoing))
|
||||||
(if outgoing
|
[message-with-name-and-avatar text message]
|
||||||
[my-photo from]
|
[text-only-message text message]))}))))
|
||||||
[member-photo from])
|
|
||||||
[react/view {:style {:padding-horizontal 12 :background-color :white :border-radius 8 :flex 1}}
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
[message-author-name message]
|
|
||||||
[react/view {:style {:flex 1}}]
|
|
||||||
[react/text {:style {:color styles/color-gray4 :font-size 12}} (time/timestamp->time timestamp)]]
|
|
||||||
;;TODO use https://github.com/status-im/status-react/pull/3299
|
|
||||||
;;[rn-hl/hyperlink {:linkStyle {:color "#2980b9"} :on-press #(re-frame/dispatch [:show-link-dialog %1])}
|
|
||||||
[react/text
|
|
||||||
text]]])}))))
|
|
||||||
|
|
||||||
(views/defview messages-view [{:keys [chat-id group-chat]}]
|
(views/defview messages-view [{:keys [chat-id group-chat]}]
|
||||||
(views/letsubs [chat-id* (atom nil)
|
(views/letsubs [chat-id* (atom nil)
|
||||||
|
@ -113,7 +123,7 @@
|
||||||
(js/setTimeout #(when scroll-ref (.scrollToEnd @scroll-ref)) 400))
|
(js/setTimeout #(when scroll-ref (.scrollToEnd @scroll-ref)) 400))
|
||||||
messages (re-frame/subscribe [:get-current-chat-messages-stream])
|
messages (re-frame/subscribe [:get-current-chat-messages-stream])
|
||||||
current-public-key (re-frame/subscribe [:get-current-public-key])]
|
current-public-key (re-frame/subscribe [:get-current-public-key])]
|
||||||
[react/view {:style {:flex 1 :background-color :white :margin-horizontal 16}}
|
[react/view {:style styles/messages-view}
|
||||||
[react/scroll-view {:scrollEventThrottle 16
|
[react/scroll-view {:scrollEventThrottle 16
|
||||||
:on-scroll (fn [e]
|
:on-scroll (fn [e]
|
||||||
(let [ne (.-nativeEvent e)
|
(let [ne (.-nativeEvent e)
|
||||||
|
@ -122,52 +132,48 @@
|
||||||
(when @scroll-timer (js/clearTimeout @scroll-timer))
|
(when @scroll-timer (js/clearTimeout @scroll-timer))
|
||||||
(reset! scroll-timer (js/setTimeout #(re-frame/dispatch [:load-more-messages]) 300)))
|
(reset! scroll-timer (js/setTimeout #(re-frame/dispatch [:load-more-messages]) 300)))
|
||||||
(reset! scroll-height (+ y (.-height (.-layoutMeasurement ne))))))
|
(reset! scroll-height (+ y (.-height (.-layoutMeasurement ne))))))
|
||||||
:on-content-size-change #(when (or (not @scroll-height) (< (- %2 @scroll-height) 500))
|
:on-content-size-change #(.scrollToEnd @scroll-ref)
|
||||||
(.scrollToEnd @scroll-ref))
|
|
||||||
:ref #(reset! scroll-ref %)}
|
:ref #(reset! scroll-ref %)}
|
||||||
[react/view {:style {:padding-vertical 60}}
|
[react/view {:style styles/messages-scrollview-inner}
|
||||||
(doall
|
(doall
|
||||||
(for [[index {:keys [from content message-id] :as message-obj}] (map-indexed vector (reverse @messages))]
|
(for [[index {:keys [from content message-id type value] :as message-obj}] (map-indexed vector (reverse @messages))]
|
||||||
^{:key (str message index)}
|
^{:key (or message-id (str type value))}
|
||||||
[message content (= from @current-public-key) (assoc message-obj :group-chat group-chat)]))]]])))
|
[message content (= from @current-public-key) (assoc message-obj :group-chat group-chat)]))]]])))
|
||||||
|
|
||||||
(views/defview chat-text-input []
|
(views/defview chat-text-input []
|
||||||
(views/letsubs [{:keys [input-text]} [:get-current-chat]
|
(views/letsubs [inp-ref (atom nil)]
|
||||||
inp-ref (atom nil)]
|
[react/view {:style styles/chat-box}
|
||||||
[react/view {:style {:height 90 :margin-horizontal 16 :background-color :white :border-radius 12}}
|
[react/view {:style styles/chat-box-inner}
|
||||||
[react/view {:style {:flex-direction :row :margin-horizontal 16 :margin-top 16 :flex 1 :margin-bottom 16}}
|
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
[react/text-input {:default-value (or input-text "")
|
[react/text-input {:placeholder (i18n/label :t/type-a-message)
|
||||||
:placeholder "Type a message..."
|
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
:multiline true
|
:multiline true
|
||||||
:blur-on-submit true
|
:blur-on-submit true
|
||||||
:style {:flex 1}
|
:style styles/chat-text-input
|
||||||
:ref #(reset! inp-ref %)
|
:ref #(reset! inp-ref %)
|
||||||
:on-key-press (fn [e]
|
:on-key-press (fn [e]
|
||||||
(let [native-event (.-nativeEvent e)
|
(let [native-event (.-nativeEvent e)
|
||||||
key (.-key native-event)]
|
key (.-key native-event)
|
||||||
(when (= key "Enter")
|
modifiers (js->clj (.-modifiers native-event))
|
||||||
(js/setTimeout #(do
|
should-send (and (= key "Enter") (not (contains? (set modifiers) "shift")))]
|
||||||
(.clear @inp-ref)
|
(when should-send
|
||||||
(.focus @inp-ref)) 200)
|
(.clear @inp-ref)
|
||||||
|
(.focus @inp-ref)
|
||||||
(re-frame/dispatch [:send-current-message]))))
|
(re-frame/dispatch [:send-current-message]))))
|
||||||
:on-change (fn [e]
|
:on-change (fn [e]
|
||||||
(let [native-event (.-nativeEvent e)
|
(let [native-event (.-nativeEvent e)
|
||||||
text (.-text native-event)]
|
text (.-text native-event)]
|
||||||
(re-frame/dispatch [:set-chat-input-text text])))}]]
|
(re-frame/dispatch [:set-chat-input-text text])))}]]
|
||||||
[react/touchable-highlight {:on-press (fn []
|
[react/touchable-highlight {:on-press (fn []
|
||||||
(js/setTimeout #(do (.clear @inp-ref) (.focus @inp-ref)) 200)
|
(.clear @inp-ref)
|
||||||
|
(.focus @inp-ref)
|
||||||
(re-frame/dispatch [:send-current-message]))}
|
(re-frame/dispatch [:send-current-message]))}
|
||||||
[react/view {:style {:margin-left 16 :width 30 :height 30 :border-radius 15 :background-color "#eef2f5" :align-items :center
|
[react/view {:style styles/send-icon}
|
||||||
:justify-content :center :transform [{:rotate "90deg"}]}}
|
|
||||||
[icons/icon :icons/arrow-left]]]]]))
|
[icons/icon :icons/arrow-left]]]]]))
|
||||||
|
|
||||||
(views/defview chat-view []
|
(views/defview chat-view []
|
||||||
(views/letsubs [current-chat [:get-current-chat]]
|
(views/letsubs [current-chat [:get-current-chat]]
|
||||||
[react/view {:style {:flex 1 :background-color :white}}
|
[react/view {:style styles/chat-view}
|
||||||
[toolbar-chat-view]
|
[toolbar-chat-view]
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
|
|
||||||
[messages-view current-chat]
|
[messages-view current-chat]
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
|
|
||||||
[chat-text-input]]))
|
[chat-text-input]]))
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
(ns status-im.ui.screens.desktop.main.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(def main-views
|
||||||
|
{:flex 1
|
||||||
|
:flex-direction :row})
|
||||||
|
|
||||||
|
(def left-sidebar
|
||||||
|
{:width 340
|
||||||
|
:background-color colors/white})
|
||||||
|
|
||||||
|
(def pane-separator
|
||||||
|
{:width 1
|
||||||
|
:background-color colors/gray-light})
|
|
@ -0,0 +1,87 @@
|
||||||
|
(ns status-im.ui.screens.desktop.main.tabs.home.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(def chat-list-view
|
||||||
|
{:flex 1
|
||||||
|
:background-color colors/white})
|
||||||
|
|
||||||
|
(defn chat-list-item [current?]
|
||||||
|
{:padding-horizontal 16
|
||||||
|
:flex-direction :row
|
||||||
|
:flex 1
|
||||||
|
:justify-content :space-between
|
||||||
|
:background-color (if current? colors/gray-lighter colors/white)
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def chat-list-header
|
||||||
|
{:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:padding 11})
|
||||||
|
|
||||||
|
(def img-container
|
||||||
|
{:height 78
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def chat-icon
|
||||||
|
{:width 46
|
||||||
|
:height 46
|
||||||
|
:border-radius 46
|
||||||
|
:margin-right 16})
|
||||||
|
|
||||||
|
(def unread-messages-icon
|
||||||
|
{:position :absolute
|
||||||
|
:width 22
|
||||||
|
:height 22
|
||||||
|
:border-radius 22
|
||||||
|
:left 28
|
||||||
|
:top 10
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center
|
||||||
|
:background-color colors/blue})
|
||||||
|
|
||||||
|
(defn unread-messages-text [large?]
|
||||||
|
{:color colors/white
|
||||||
|
:font-size (if large? 10 12)})
|
||||||
|
|
||||||
|
(def chat-list-separator
|
||||||
|
{:height 1
|
||||||
|
:background-color colors/gray-light})
|
||||||
|
|
||||||
|
(def chat-name-box
|
||||||
|
{:flex-direction :row
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def chat-name-last-msg-box
|
||||||
|
{:flex 1
|
||||||
|
:padding-vertical 16})
|
||||||
|
|
||||||
|
(defn chat-name [current?]
|
||||||
|
{:font-size 14
|
||||||
|
:font-weight (if current? "600" :normal)})
|
||||||
|
|
||||||
|
(def chat-last-message
|
||||||
|
{:color colors/gray
|
||||||
|
:font-size 14})
|
||||||
|
|
||||||
|
(def timestamp
|
||||||
|
{:justify-content :flex-start
|
||||||
|
:align-items :flex-end
|
||||||
|
:padding-vertical 16})
|
||||||
|
|
||||||
|
(def add-new
|
||||||
|
{:background-color colors/blue
|
||||||
|
:width 34
|
||||||
|
:height 34
|
||||||
|
:border-radius 34
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(defn topic-image [color]
|
||||||
|
(merge chat-icon
|
||||||
|
{:background-color color
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center}))
|
||||||
|
|
||||||
|
(def topic-text
|
||||||
|
{:font-size 25.6
|
||||||
|
:color colors/white})
|
|
@ -2,6 +2,12 @@
|
||||||
(:require-macros [status-im.utils.views :as views])
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
[status-im.utils.gfycat.core :as gfycat]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
|
||||||
|
[status-im.ui.screens.desktop.main.tabs.home.styles :as styles]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.ui.screens.home.views.inner-item :as chat-item]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
[status-im.ui.components.icons.vector-icons :as icons]
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
[status-im.ui.components.react :as react]))
|
[status-im.ui.components.react :as react]))
|
||||||
|
|
||||||
|
@ -12,36 +18,60 @@
|
||||||
[react/text {:font :medium}
|
[react/text {:font :medium}
|
||||||
@unviewed-messages-count]])))
|
@unviewed-messages-count]])))
|
||||||
|
|
||||||
(views/defview chat-list-item-inner-view [{:keys [chat-id name group-chat public? public-key]}]
|
(views/defview chat-list-item-inner-view [{:keys [chat-id name group-chat color public? public-key] :as chat-item}]
|
||||||
(let [name (str
|
(letsubs [photo-path [:get-chat-photo chat-id]
|
||||||
(if public? "#" "")
|
unviewed-messages-count [:unviewed-messages-count chat-id]
|
||||||
(or name
|
chat-name [:get-chat-name chat-id]
|
||||||
(gfycat/generate-gfy public-key)))]
|
current-chat-id [:get-current-chat-id]
|
||||||
[react/view {:style {:padding 12 :background-color :white :flex-direction :row :align-items :center}}
|
last-message [:get-last-message chat-id]]
|
||||||
(when public?
|
(let [name (or chat-name
|
||||||
[icons/icon :icons/public-chat])
|
(gfycat/generate-gfy public-key))
|
||||||
(when (and group-chat (not public?))
|
[unviewed-messages-label large?] (if (< 99 unviewed-messages-count)
|
||||||
[icons/icon :icons/group-chat])
|
["99+" true]
|
||||||
[react/text
|
[unviewed-messages-count false])]
|
||||||
name]
|
[react/view {:style (styles/chat-list-item (= current-chat-id chat-id))}
|
||||||
[react/view {:style {:flex 1}}]
|
[react/view {:style styles/img-container}
|
||||||
[unviewed-indicator chat-id]]))
|
(if public?
|
||||||
|
[react/view {:style (styles/topic-image color)}
|
||||||
|
[react/text {:style styles/topic-text}
|
||||||
|
(string/capitalize (second name))]]
|
||||||
|
[react/image {:style styles/chat-icon
|
||||||
|
:source {:uri photo-path}}])
|
||||||
|
(when (pos? unviewed-messages-count)
|
||||||
|
[react/view {:style styles/unread-messages-icon}
|
||||||
|
[react/text {:style (styles/unread-messages-text large?)} unviewed-messages-label]])]
|
||||||
|
[react/view {:style styles/chat-name-last-msg-box}
|
||||||
|
[react/view {:style styles/chat-name-box}
|
||||||
|
(when (and group-chat (not public?))
|
||||||
|
[icons/icon :icons/group-chat])
|
||||||
|
(when public?
|
||||||
|
[icons/icon :icons/public-chat])
|
||||||
|
[react/text {:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1
|
||||||
|
:style (styles/chat-name (= current-chat-id chat-id))}
|
||||||
|
name]]
|
||||||
|
[react/text {:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1
|
||||||
|
:style styles/chat-last-message}
|
||||||
|
(or (:content last-message) (i18n/label :no-messages-yet))]]
|
||||||
|
[react/view {:style styles/timestamp}
|
||||||
|
[chat-item/message-timestamp (:timestamp last-message)]]])))
|
||||||
|
|
||||||
(defn chat-list-item [[chat-id chat]]
|
(defn chat-list-item [[chat-id chat]]
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to-chat chat-id])}
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to-chat chat-id])}
|
||||||
[react/view
|
[chat-list-item-inner-view (assoc chat :chat-id chat-id)]])
|
||||||
[chat-list-item-inner-view (assoc chat :chat-id chat-id)]]])
|
|
||||||
|
|
||||||
(views/defview chat-list-view []
|
(views/defview chat-list-view []
|
||||||
(views/letsubs [home-items [:home-items]]
|
(views/letsubs [home-items [:home-items]]
|
||||||
[react/view {:style {:flex 1 :background-color :white}}
|
[react/view {:style styles/chat-list-view}
|
||||||
[react/view {:style {:align-items :center :flex-direction :row :padding 11}}
|
[react/view {:style styles/chat-list-header}
|
||||||
[react/view {:style {:flex 1}}]
|
[react/view {:style {:flex 1}}]
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :new-contact])}
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :new-contact])}
|
||||||
[icons/icon :icons/add]]]
|
[react/view {:style styles/add-new}
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
|
[icons/icon :icons/add {:style {:tint-color :white}}]]]]
|
||||||
|
[react/view {:style styles/chat-list-separator}]
|
||||||
[react/scroll-view
|
[react/scroll-view
|
||||||
[react/view
|
[react/view
|
||||||
(for [[index chat] (map-indexed vector home-items)]
|
(for [[index chat] (map-indexed vector home-items)]
|
||||||
^{:key (str chat index)}
|
^{:key (first chat)}
|
||||||
[chat-list-item chat])]]]))
|
[chat-list-item chat])]]]))
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
(ns status-im.ui.screens.desktop.main.tabs.profile.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(def profile-view
|
||||||
|
{:align-items :center})
|
||||||
|
|
||||||
|
(def profile-badge
|
||||||
|
{:margin-top 34
|
||||||
|
:align-items :center
|
||||||
|
:margin-bottom 16})
|
||||||
|
|
||||||
|
(def logout-row
|
||||||
|
{:justify-content :space-between
|
||||||
|
:flex-direction :row
|
||||||
|
:margin-horizontal 24
|
||||||
|
:align-self :stretch
|
||||||
|
:margin-top 60})
|
||||||
|
|
||||||
|
(defn logout-row-text [color]
|
||||||
|
{:color color
|
||||||
|
:font-size 16})
|
||||||
|
|
||||||
|
(def profile-photo
|
||||||
|
{:border-radius 100
|
||||||
|
:width 100
|
||||||
|
:height 100})
|
||||||
|
|
||||||
|
(def profile-user-name
|
||||||
|
{:font-weight :bold
|
||||||
|
:font-size 18})
|
||||||
|
|
||||||
|
(def share-contact-code
|
||||||
|
{:flex-direction :row
|
||||||
|
:justify-content :space-between
|
||||||
|
:align-items :center
|
||||||
|
:height 45
|
||||||
|
:width 240
|
||||||
|
:margin-horizontal 50
|
||||||
|
:border-radius 8
|
||||||
|
:background-color (colors/alpha colors/blue 0.1)})
|
||||||
|
|
||||||
|
(def share-contact-code-text-container
|
||||||
|
{:margin-left 32
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def share-contact-code-text
|
||||||
|
{:color colors/blue
|
||||||
|
:font-size 14})
|
||||||
|
|
||||||
|
(def share-contact-icon-container
|
||||||
|
{:margin-right 12
|
||||||
|
:width 22
|
||||||
|
:height 22
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def qr-code-container
|
||||||
|
{:align-items :center
|
||||||
|
:padding-top 16
|
||||||
|
:padding-bottom 46
|
||||||
|
:padding-left 58
|
||||||
|
:padding-right 58})
|
||||||
|
|
||||||
|
(def close-icon-container
|
||||||
|
{:flex 1
|
||||||
|
:margin-top 22
|
||||||
|
:margin-right 22
|
||||||
|
:margin-bottom 16
|
||||||
|
:flex-direction :row
|
||||||
|
:justify-content :flex-end})
|
||||||
|
|
||||||
|
(def close-icon
|
||||||
|
{:height 24
|
||||||
|
:width 24
|
||||||
|
:tint-color colors/gray-icon})
|
||||||
|
|
||||||
|
(def check-icon
|
||||||
|
{:height 16
|
||||||
|
:width 16
|
||||||
|
:margin-right 8
|
||||||
|
:tint-color colors/tooltip-green-text})
|
||||||
|
|
||||||
|
(def qr-code-title
|
||||||
|
{:font-size 20
|
||||||
|
:font-weight "600"
|
||||||
|
:margin-bottom 32})
|
||||||
|
|
||||||
|
(def qr-code
|
||||||
|
{:width 130
|
||||||
|
:height 130
|
||||||
|
:margin-bottom 16})
|
||||||
|
|
||||||
|
(def qr-code-text
|
||||||
|
{:font-size 16
|
||||||
|
:text-align :center
|
||||||
|
:margin-bottom 16})
|
||||||
|
|
||||||
|
(def qr-code-copy
|
||||||
|
{:width 185
|
||||||
|
:height 45
|
||||||
|
:border-radius 8
|
||||||
|
:background-color colors/blue
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def qr-code-copy-text
|
||||||
|
{:font-size 16
|
||||||
|
:color colors/white})
|
||||||
|
|
||||||
|
(defn tooltip-container [opacity]
|
||||||
|
{:position :absolute
|
||||||
|
:align-items :center
|
||||||
|
:opacity opacity
|
||||||
|
:top -34})
|
||||||
|
|
||||||
|
(def tooltip-icon-text
|
||||||
|
{:flex-direction :row
|
||||||
|
:justify-content :space-between
|
||||||
|
:align-items :center
|
||||||
|
:height 24
|
||||||
|
:border-radius 8
|
||||||
|
:padding-left 10
|
||||||
|
:padding-right 10
|
||||||
|
:background-color colors/tooltip-green})
|
||||||
|
|
||||||
|
(def tooltip-triangle
|
||||||
|
{:width 0
|
||||||
|
:height 0
|
||||||
|
:border-top-width 9.1
|
||||||
|
:border-left-width 9.1
|
||||||
|
:border-right-width 9.1
|
||||||
|
:border-left-color :transparent
|
||||||
|
:border-right-color :transparent
|
||||||
|
:border-top-color colors/tooltip-green})
|
|
@ -2,40 +2,73 @@
|
||||||
(:require-macros [status-im.utils.views :as views])
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.screens.profile.user.views :as profile]
|
||||||
|
[status-im.utils.build :as build]
|
||||||
|
[status-im.utils.utils :as utils]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||||
|
[status-im.ui.screens.desktop.main.tabs.profile.styles :as styles]
|
||||||
[status-im.ui.screens.profile.user.views :as profile]))
|
[status-im.ui.screens.profile.user.views :as profile]))
|
||||||
|
|
||||||
(defn profile-badge [{:keys [name]}]
|
(defn profile-badge [{:keys [name photo-path]}]
|
||||||
[react/view {:margin-vertical 10}
|
[react/view styles/profile-badge
|
||||||
[react/text {:style {:font-weight :bold}
|
[react/image {:source {:uri photo-path}
|
||||||
|
:style styles/profile-photo}]
|
||||||
|
[react/text {:style styles/profile-user-name
|
||||||
:number-of-lines 1}
|
:number-of-lines 1}
|
||||||
name]])
|
name]])
|
||||||
|
|
||||||
(defn profile-info-item [{:keys [label value]}]
|
(views/defview copied-tooltip [opacity]
|
||||||
[react/view
|
(views/letsubs []
|
||||||
[react/view
|
[react/view {:style (styles/tooltip-container opacity)}
|
||||||
[react/text
|
[react/view {:style styles/tooltip-icon-text}
|
||||||
label]
|
[vector-icons/icon :icons/check
|
||||||
[react/view {:height 10}]
|
{:style styles/check-icon}]
|
||||||
[react/text {:number-of-lines 1
|
[react/text {:style {:font-size 14 :color colors/tooltip-green-text}}
|
||||||
:ellipsizeMode :middle}
|
(i18n/label :sharing-copied-to-clipboard)]]
|
||||||
value]]])
|
[react/view {:style styles/tooltip-triangle}]]))
|
||||||
|
|
||||||
(defn my-profile-info [{:keys [public-key]}]
|
(views/defview qr-code []
|
||||||
[react/view
|
(views/letsubs [{:keys [public-key]} [:get-current-account]
|
||||||
[profile-info-item
|
tooltip-opacity [:get-in [:tooltips :qr-copied]]]
|
||||||
{:label "Contact Key"
|
[react/view
|
||||||
:value public-key}]])
|
[react/view {:style styles/qr-code-container}
|
||||||
|
[react/text {:style styles/qr-code-title}
|
||||||
|
(string/replace (i18n/label :qr-code-public-key-hint) "\n" "")]
|
||||||
|
[react/view {:style styles/qr-code}
|
||||||
|
[qr-code-viewer/qr-code {:value public-key :size 130}]]
|
||||||
|
[react/view {:style {:align-items :center}}
|
||||||
|
[react/text {:style styles/qr-code-text}
|
||||||
|
public-key]
|
||||||
|
(when tooltip-opacity
|
||||||
|
[copied-tooltip tooltip-opacity])]
|
||||||
|
[react/touchable-highlight {:on-press #(do
|
||||||
|
(re-frame/dispatch [:copy-to-clipboard public-key])
|
||||||
|
(re-frame/dispatch [:show-tooltip :qr-copied]))}
|
||||||
|
[react/view {:style styles/qr-code-copy}
|
||||||
|
[react/text {:style styles/qr-code-copy-text}
|
||||||
|
(i18n/label :copy-qr)]]]]]))
|
||||||
|
|
||||||
|
(defn share-contact-code []
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :qr-code])}
|
||||||
|
[react/view {:style styles/share-contact-code}
|
||||||
|
[react/view {:style styles/share-contact-code-text-container}
|
||||||
|
[react/text {:style styles/share-contact-code-text}
|
||||||
|
(i18n/label :share-contact-code)]]
|
||||||
|
[react/view {:style styles/share-contact-icon-container
|
||||||
|
:accessibility-label :share-my-contact-code-button}
|
||||||
|
[vector-icons/icon :icons/qr {:style {:tint-color colors/blue}}]]]])
|
||||||
|
|
||||||
(views/defview profile []
|
(views/defview profile []
|
||||||
(views/letsubs [current-account [:get-current-account]]
|
(views/letsubs [current-account [:get-current-account]]
|
||||||
[react/view {:margin-top 40 :margin-horizontal 10}
|
[react/view styles/profile-view
|
||||||
[react/view
|
[profile-badge current-account]
|
||||||
[profile-badge current-account]]
|
[share-contact-code]
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
|
[react/view {:style styles/logout-row}
|
||||||
[react/view
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:logout])}
|
||||||
[my-profile-info current-account]]
|
[react/text {:style (styles/logout-row-text colors/red)} (i18n/label :t/logout)]]
|
||||||
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
|
[react/view [react/text {:style (styles/logout-row-text colors/gray)} "V" build/version]]]]))
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:logout])
|
|
||||||
:style {:margin-top 60}}
|
|
||||||
[react/view
|
|
||||||
[react/text {:style {:color :red}} "Log out"]]]]))
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require-macros [status-im.utils.views :as views])
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [status-im.ui.screens.desktop.main.tabs.profile.views :as profile.views]
|
(:require [status-im.ui.screens.desktop.main.tabs.profile.views :as profile.views]
|
||||||
[status-im.ui.screens.desktop.main.tabs.home.views :as home.views]
|
[status-im.ui.screens.desktop.main.tabs.home.views :as home.views]
|
||||||
|
[status-im.ui.screens.desktop.main.styles :as styles]
|
||||||
[status-im.ui.screens.desktop.main.chat.views :as chat.views]
|
[status-im.ui.screens.desktop.main.chat.views :as chat.views]
|
||||||
[status-im.ui.screens.desktop.main.add-new.views :as add-new.views]
|
[status-im.ui.screens.desktop.main.add-new.views :as add-new.views]
|
||||||
[status-im.ui.components.desktop.tabs :as tabs]
|
[status-im.ui.components.desktop.tabs :as tabs]
|
||||||
|
@ -24,17 +25,18 @@
|
||||||
(views/defview main-view []
|
(views/defview main-view []
|
||||||
(views/letsubs [view-id [:get :view-id]]
|
(views/letsubs [view-id [:get :view-id]]
|
||||||
(let [component (case view-id
|
(let [component (case view-id
|
||||||
:chat chat.views/chat-view
|
:chat chat.views/chat-view
|
||||||
:new-contact add-new.views/new-contact
|
:new-contact add-new.views/new-contact
|
||||||
|
:qr-code profile.views/qr-code
|
||||||
status-view)]
|
status-view)]
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
[component]])))
|
[component]])))
|
||||||
|
|
||||||
(views/defview main-views []
|
(views/defview main-views []
|
||||||
[react/view {:style {:flex 1 :flex-direction :row}}
|
[react/view {:style styles/main-views}
|
||||||
[react/view {:style {:width 280 :background-color :white}}
|
[react/view {:style styles/left-sidebar}
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
[tab-views]]
|
[tab-views]]
|
||||||
[tabs/main-tabs]]
|
[tabs/main-tabs]]
|
||||||
[react/view {:style {:width 1 :background-color "#e8ebec"}}]
|
[react/view {:style styles/pane-separator}]
|
||||||
[main-view]])
|
[main-view]])
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
[status-im.ui.screens.accounts.recover.views :as recover.views]
|
[status-im.ui.screens.accounts.recover.views :as recover.views]
|
||||||
[status-im.ui.screens.accounts.views :as accounts.views]))
|
[status-im.ui.screens.accounts.views :as accounts.views]))
|
||||||
|
|
||||||
|
(enable-console-print!)
|
||||||
|
|
||||||
(views/defview main []
|
(views/defview main []
|
||||||
(views/letsubs [view-id [:get :view-id]]
|
(views/letsubs [view-id [:get :view-id]]
|
||||||
(let [component (case view-id
|
(let [component (case view-id
|
||||||
|
@ -15,7 +17,7 @@
|
||||||
:accounts accounts.views/accounts
|
:accounts accounts.views/accounts
|
||||||
:recover recover.views/recover
|
:recover recover.views/recover
|
||||||
:create-account create.views/create-account
|
:create-account create.views/create-account
|
||||||
(:new-contact :chat :home) main.views/main-views
|
(:new-contact :chat :home :qr-code) main.views/main-views
|
||||||
:login login.views/login
|
:login login.views/login
|
||||||
react/view)]
|
react/view)]
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
|
|
|
@ -345,8 +345,8 @@
|
||||||
[:process-pending-messages]
|
[:process-pending-messages]
|
||||||
[:update-wallet]
|
[:update-wallet]
|
||||||
[:update-transactions]
|
[:update-transactions]
|
||||||
|
(when platform/mobile? [:get-fcm-token])
|
||||||
[:sync-wallet-transactions]
|
[:sync-wallet-transactions]
|
||||||
[:get-fcm-token]
|
|
||||||
[:update-sign-in-time]]
|
[:update-sign-in-time]]
|
||||||
(seq events-after) (into events-after))}))
|
(seq events-after) (into events-after))}))
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,7 @@
|
||||||
(defstyle datetime-text
|
(defstyle datetime-text
|
||||||
{:color component.styles/text4-color
|
{:color component.styles/text4-color
|
||||||
:android {:font-size 14}
|
:android {:font-size 14}
|
||||||
|
:desktop {:font-size 14}
|
||||||
:ios {:font-size 15}})
|
:ios {:font-size 15}})
|
||||||
|
|
||||||
(def new-messages-container
|
(def new-messages-container
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
[status-im.utils.platform :as platform])
|
[status-im.utils.platform :as platform])
|
||||||
(:require-macros [status-im.utils.styles :refer [defnstyle]]))
|
(:require-macros [status-im.utils.styles :refer [defnstyle]]))
|
||||||
|
|
||||||
(def tabs-height (if platform/ios? 52 56))
|
(def tabs-height
|
||||||
|
(cond
|
||||||
|
platform/android? 56
|
||||||
|
platform/ios? 52
|
||||||
|
platform/desktop? 68))
|
||||||
|
|
||||||
(def tab-height (dec tabs-height))
|
(def tab-height (dec tabs-height))
|
||||||
|
|
||||||
(def tabs-container
|
(def tabs-container
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
(ns status-im.ui.screens.profile.events
|
(ns status-im.ui.screens.profile.events
|
||||||
(:require [clojure.spec.alpha :as spec]
|
(:require [clojure.spec.alpha :as spec]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.ui.components.react :refer [show-image-picker]]
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.chat.constants :as chat-const]
|
||||||
[status-im.ui.screens.profile.navigation]
|
[status-im.ui.screens.profile.navigation]
|
||||||
[status-im.ui.screens.accounts.utils :as accounts.utils]
|
[status-im.ui.screens.accounts.utils :as accounts.utils]
|
||||||
[status-im.chat.events :as chat-events]
|
[status-im.chat.events :as chat-events]
|
||||||
|
@ -15,7 +16,7 @@
|
||||||
:open-image-picker
|
:open-image-picker
|
||||||
;; the image picker is only used here for now, this effect can be use in other scenarios as well
|
;; the image picker is only used here for now, this effect can be use in other scenarios as well
|
||||||
(fn [callback-event]
|
(fn [callback-event]
|
||||||
(show-image-picker
|
(react/show-image-picker
|
||||||
(fn [image]
|
(fn [image]
|
||||||
(let [path (get (js->clj image) "path")
|
(let [path (get (js->clj image) "path")
|
||||||
_ (log/debug path)
|
_ (log/debug path)
|
||||||
|
@ -114,3 +115,40 @@
|
||||||
(handlers-macro/merge-fx cofx
|
(handlers-macro/merge-fx cofx
|
||||||
{:db (update db :my-profile/seed assoc :step :finish :error nil :word nil)}
|
{:db (update db :my-profile/seed assoc :step :finish :error nil :word nil)}
|
||||||
(accounts.utils/clean-seed-phrase))))
|
(accounts.utils/clean-seed-phrase))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:copy-to-clipboard
|
||||||
|
(fn [value]
|
||||||
|
(react/copy-to-clipboard value)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:copy-to-clipboard
|
||||||
|
(fn [_ [_ value]]
|
||||||
|
{:copy-to-clipboard value}))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:show-tooltip
|
||||||
|
(let [tooltips (atom {})]
|
||||||
|
(fn [tooltip-id]
|
||||||
|
(when-let [{:keys [interval-id]} (@tooltips tooltip-id)]
|
||||||
|
(js/clearInterval interval-id))
|
||||||
|
(let [interval-id (js/setInterval
|
||||||
|
#(let [{:keys [opacity interval-id cnt]} (@tooltips tooltip-id)]
|
||||||
|
(when opacity
|
||||||
|
(swap! tooltips assoc-in [tooltip-id :cnt] (inc cnt))
|
||||||
|
(if (and opacity (>= 0.0 opacity))
|
||||||
|
(do
|
||||||
|
(log/debug "remove interval:" interval-id)
|
||||||
|
(js/clearInterval interval-id)
|
||||||
|
(re-frame/dispatch [:set-in [:tooltips tooltip-id] nil])
|
||||||
|
(swap! tooltips dissoc interval-id))
|
||||||
|
(do (re-frame/dispatch [:set-in [:tooltips tooltip-id] opacity])
|
||||||
|
(when (< 10 cnt)
|
||||||
|
(swap! tooltips assoc-in [tooltip-id :opacity] (- opacity 0.05)))))))
|
||||||
|
100)]
|
||||||
|
(swap! tooltips assoc tooltip-id {:opacity 1.0 :interval-id interval-id :cnt 0})))))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:show-tooltip
|
||||||
|
(fn [_ [_ tooltip-id]]
|
||||||
|
{:show-tooltip tooltip-id}))
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
(ns status-im.ui.screens.profile.subs
|
(ns status-im.ui.screens.profile.subs
|
||||||
(:require [re-frame.core :refer [reg-sub]]
|
(:require [re-frame.core :refer [reg-sub]]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[status-im.utils.build :as build]))
|
[status-im.utils.build :as build]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
(reg-sub
|
(reg-sub
|
||||||
:get-profile-unread-messages-number
|
:get-profile-unread-messages-number
|
||||||
|
@ -12,7 +13,8 @@
|
||||||
(reg-sub
|
(reg-sub
|
||||||
:get-app-version
|
:get-app-version
|
||||||
(fn [{:keys [web3-node-version]}]
|
(fn [{:keys [web3-node-version]}]
|
||||||
(str build/version " (" build/build-no ")\nnode " (or web3-node-version "N/A") "")))
|
(let [version (if platform/desktop? build/version build/build-no)]
|
||||||
|
(str build/version " (" version ")\nnode " (or web3-node-version "N/A") ""))))
|
||||||
|
|
||||||
(reg-sub :get-device-UUID
|
(reg-sub :get-device-UUID
|
||||||
(fn [db]
|
(fn [db]
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
status-im.ui.screens.currency-settings.subs
|
status-im.ui.screens.currency-settings.subs
|
||||||
status-im.ui.screens.browser.subs
|
status-im.ui.screens.browser.subs
|
||||||
status-im.ui.screens.add-new.new-chat.subs
|
status-im.ui.screens.add-new.new-chat.subs
|
||||||
|
status-im.ui.screens.add-new.new-public-chat.subs
|
||||||
status-im.ui.screens.profile.subs))
|
status-im.ui.screens.profile.subs))
|
||||||
|
|
||||||
(reg-sub :get
|
(reg-sub :get
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
(ns status-im.utils.keychain.core
|
(ns status-im.utils.keychain.core
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[status-im.react-native.js-dependencies :as rn]))
|
[status-im.react-native.js-dependencies :as rn]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
(def key-bytes 64)
|
(def key-bytes 64)
|
||||||
(def username "status-im.encryptionkey")
|
(def username "status-im.encryptionkey")
|
||||||
|
@ -73,3 +74,6 @@
|
||||||
(defn reset []
|
(defn reset []
|
||||||
(log/debug "resetting key...")
|
(log/debug "resetting key...")
|
||||||
(.resetGenericPassword rn/keychain))
|
(.resetGenericPassword rn/keychain))
|
||||||
|
|
||||||
|
(defn set-username []
|
||||||
|
(when platform/desktop? (.setUsername rn/keychain username)))
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
(ns status-im.utils.keychain.events
|
(ns status-im.utils.keychain.events
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[status-im.utils.keychain.core :as keychain]))
|
[status-im.utils.keychain.core :as keychain]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
(defn handle-key-error [event {:keys [error key]}]
|
(defn handle-key-error [event {:keys [error key]}]
|
||||||
(if (= :weak-key error)
|
(if (= :weak-key error)
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
:get-encryption-key
|
:get-encryption-key
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
(when platform/desktop? (keychain/set-username))
|
||||||
(.. (keychain/get-encryption-key)
|
(.. (keychain/get-encryption-key)
|
||||||
(then #(re-frame/dispatch (conj event %)))
|
(then #(re-frame/dispatch (conj event %)))
|
||||||
(catch (partial handle-key-error event)))))
|
(catch (partial handle-key-error event)))))
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
[status-im.utils.config :as config]
|
[status-im.utils.config :as config]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.ui.components.react :refer [copy-to-clipboard]]
|
[status-im.ui.components.react :refer [copy-to-clipboard]]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
;; Work in progress namespace responsible for push notifications and interacting
|
;; Work in progress namespace responsible for push notifications and interacting
|
||||||
;; with Firebase Cloud Messaging.
|
;; with Firebase Cloud Messaging.
|
||||||
|
@ -28,14 +29,16 @@
|
||||||
|
|
||||||
;; NOTE: Only need to explicitly request permissions on iOS.
|
;; NOTE: Only need to explicitly request permissions on iOS.
|
||||||
(defn request-permissions []
|
(defn request-permissions []
|
||||||
(-> (.requestPermissions (.-default rn/react-native-fcm))
|
(if platform/desktop?
|
||||||
(.then
|
(dispatch [:request-notifications-granted {}])
|
||||||
(fn [_]
|
(-> (.requestPermissions (.-default rn/react-native-fcm))
|
||||||
(log/debug "notifications-granted")
|
(.then
|
||||||
(dispatch [:request-notifications-granted {}]))
|
(fn [_]
|
||||||
(fn [_]
|
(log/debug "notifications-granted")
|
||||||
(log/debug "notifications-denied")
|
(dispatch [:request-notifications-granted {}]))
|
||||||
(dispatch [:request-notifications-denied {}])))))
|
(fn [_]
|
||||||
|
(log/debug "notifications-denied")
|
||||||
|
(dispatch [:request-notifications-denied {}]))))))
|
||||||
|
|
||||||
(defn get-fcm-token []
|
(defn get-fcm-token []
|
||||||
(-> (.getFCMToken (object/get rn/react-native-fcm "default"))
|
(-> (.getFCMToken (object/get rn/react-native-fcm "default"))
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
(def android? (= os "android"))
|
(def android? (= os "android"))
|
||||||
(def ios? (= os "ios"))
|
(def ios? (= os "ios"))
|
||||||
|
(def desktop? (= os "desktop"))
|
||||||
|
(def mobile? (not= os "desktop"))
|
||||||
(def iphone-x? (and ios? (ios/iphone-x-dimensions?)))
|
(def iphone-x? (and ios? (ios/iphone-x-dimensions?)))
|
||||||
|
|
||||||
(def platform-specific
|
(def platform-specific
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
(defn body [style]
|
(defn body [style]
|
||||||
`(let [style# ~style
|
`(let [style# ~style
|
||||||
common# (dissoc style# :android :ios)
|
common# (dissoc style# :android :ios :desktop)
|
||||||
platform# (keyword status-im.utils.platform/os)
|
platform# (keyword status-im.utils.platform/os)
|
||||||
platform-specific# (get style# platform#)]
|
platform-specific# (get style# platform#)]
|
||||||
(if platform-specific#
|
(if platform-specific#
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2016, Canonical Ltd.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
console.debug = console.log;
|
||||||
|
|
||||||
|
|
||||||
|
var net = require('net');
|
||||||
|
var repl = require('repl');
|
||||||
|
var vm = require('vm');
|
||||||
|
var util = require('util');
|
||||||
|
var Buffer = require('buffer').Buffer;
|
||||||
|
var realmConstructor = require("./node_modules/realm/lib/index.js");
|
||||||
|
console.log("Loaded realmConstructor: " + realmConstructor);
|
||||||
|
|
||||||
|
var DEBUG = 1;
|
||||||
|
|
||||||
|
function rnUbuntuServer(readable, writable) {
|
||||||
|
console.reportErrorsAsExceptions = false; // XXX:
|
||||||
|
var sandbox = { console: console, util: util, outerRealmConstructor: realmConstructor };
|
||||||
|
vm.createContext(sandbox);
|
||||||
|
|
||||||
|
var state = 'start';
|
||||||
|
var length = 0;
|
||||||
|
var buffer = new Buffer(0);
|
||||||
|
|
||||||
|
var internalEval = function(code) {
|
||||||
|
DEBUG > 3 && console.error("-- internalEval: executing script(length=" + code.length + "): " + code.slice(0, 80) + " ... " + code.slice(-80));
|
||||||
|
DEBUG > 3 && console.error("-- before sandbox=" + util.inspect(sandbox, { colors: true, depth: null }));
|
||||||
|
var result = vm.runInContext(code, sandbox);
|
||||||
|
DEBUG > 3 && console.error("-- internalEval: result = " + result);
|
||||||
|
DEBUG > 3 && console.error("-- after sandbox=" + util.inspect(sandbox, { colors: true, depth: null }));
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
var sendResponse = function(result) {
|
||||||
|
function sendResponsePacket(response) {
|
||||||
|
const sizeBuf = new Buffer(4);
|
||||||
|
const dataBuf = new Buffer(response);
|
||||||
|
sizeBuf.writeUInt32LE(dataBuf.length, 0);
|
||||||
|
writable.write(sizeBuf);
|
||||||
|
writable.write(dataBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringifiedResult = JSON.stringify(result);
|
||||||
|
DEBUG > 3 && console.error("-- sending result=" + stringifiedResult);
|
||||||
|
if (stringifiedResult === undefined) {
|
||||||
|
sendResponsePacket('undefined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendResponsePacket(stringifiedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
readable.on('error', function (exc) {
|
||||||
|
console.warn("ignoring exception: " + exc);
|
||||||
|
});
|
||||||
|
|
||||||
|
readable.on('data', function(chunk) {
|
||||||
|
DEBUG > 2 && console.error("-- Data received from RN Client: state = " + state)
|
||||||
|
DEBUG > 2 && console.error("-- chunk length: " + chunk.length)
|
||||||
|
DEBUG > 2 && console.error("-- buffer length(original): " + buffer.length)
|
||||||
|
|
||||||
|
if (chunk == null || state === 'eof')
|
||||||
|
return;
|
||||||
|
|
||||||
|
buffer = Buffer.concat([buffer, chunk]);
|
||||||
|
DEBUG > 2 && console.error("-- buffer length(concat): " + buffer.length)
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if (state === 'start') {
|
||||||
|
if (buffer.length < 4)
|
||||||
|
return;
|
||||||
|
length = buffer.readUInt32LE(0);
|
||||||
|
DEBUG > 2 && console.error("-- New Packet: length=" + length);
|
||||||
|
|
||||||
|
if (buffer.length >= length + 4) {
|
||||||
|
var result = internalEval(buffer.toString('utf8', 4, length + 4));
|
||||||
|
var tmpBuffer = new Buffer(buffer.length - 4 - length);
|
||||||
|
buffer.copy(tmpBuffer, 0, length + 4, buffer.length);
|
||||||
|
buffer = tmpBuffer;
|
||||||
|
sendResponse(result);
|
||||||
|
} else {
|
||||||
|
state = 'script';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state === 'script') {
|
||||||
|
DEBUG > 2 && console.error("-- Packet length: " + length);
|
||||||
|
if (buffer.length >= length + 4) {
|
||||||
|
var result = internalEval(buffer.toString('utf8', 4, length + 4));
|
||||||
|
var tmpBuffer = new Buffer(buffer.length - 4 - length);
|
||||||
|
buffer.copy(tmpBuffer, 0, length + 4, buffer.length);
|
||||||
|
buffer = tmpBuffer;
|
||||||
|
state = 'start';
|
||||||
|
sendResponse(result);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
readable.on('end', function() {
|
||||||
|
state = 'eof';
|
||||||
|
DEBUG && console.error("-- Session ended");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv.indexOf('--pipe') != -1) {
|
||||||
|
console.log = console.error
|
||||||
|
rnUbuntuServer(process.stdin, process.stdout);
|
||||||
|
} else {
|
||||||
|
var server = net.createServer((sock) => {
|
||||||
|
DEBUG && console.error("-- Connection from RN client");
|
||||||
|
rnUbuntuServer(sock, sock);
|
||||||
|
}).listen(5000, function() { console.error("-- Server starting") });
|
||||||
|
}
|
Loading…
Reference in New Issue