moved re-frame app to root folder

This commit is contained in:
michaelr 2016-04-04 19:21:10 +03:00
parent bd2767bf17
commit 5a3b923b0c
189 changed files with 212 additions and 5027 deletions

7
.gitignore vendored
View File

@ -25,7 +25,7 @@ project.xcworkspace
# Android/IJ # Android/IJ
# #
.idea .idea
.gradle/ .gradle
local.properties local.properties
# node.js # node.js
@ -42,8 +42,3 @@ target/
# Figwheel # Figwheel
# #
figwheel_server.log figwheel_server.log
.nrepl-port
# Mercurial
.hg/
.hgignore

View File

@ -1,17 +1,21 @@
{ {
"name": "Messenger", "name": "SyngIm",
"interface": "om-next", "interface": "reagent",
"androidHost": "localhost", "androidHost": "10.0.3.2",
"modules": [ "modules": [
"react-native-contacts", "react-native-contacts",
"react-native-invertible-scroll-view", "react-native-invertible-scroll-view",
"awesome-phonenumber", "awesome-phonenumber",
"realm", "realm",
"react-native-loading-spinner-overlay", "react-native-loading-spinner-overlay",
"react-native-i18n" "react-native-i18n",
"realm/react-native",
"react-native-action-button",
"react-native-vector-icons/Ionicons",
"react-native-circle-checkbox",
"react-native-randombytes"
], ],
"imageDirs": [ "imageDirs": [
"images" "images"
], ]
"iosHost": "localhost"
} }

View File

@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. This change
### Changed ### Changed
- Add a new arity to `make-widget-async` to provide a different widget shape. - Add a new arity to `make-widget-async` to provide a different widget shape.
## [0.1.1] - 2016-02-21 ## [0.1.1] - 2016-03-23
### Changed ### Changed
- Documentation on how to make the widgets. - Documentation on how to make the widgets.
@ -15,10 +15,10 @@ All notable changes to this project will be documented in this file. This change
### Fixed ### Fixed
- Fixed widget maker to keep working when daylight savings switches over. - Fixed widget maker to keep working when daylight savings switches over.
## 0.1.0 - 2016-02-21 ## 0.1.0 - 2016-03-23
### Added ### Added
- Files from the new template. - Files from the new template.
- Widget maker public API - `make-widget-sync`. - Widget maker public API - `make-widget-sync`.
[unreleased]: https://github.com/your-name/messenger/compare/0.1.1...HEAD [unreleased]: https://github.com/your-name/syng-im/compare/0.1.1...HEAD
[0.1.1]: https://github.com/your-name/messenger/compare/0.1.0...0.1.1 [0.1.1]: https://github.com/your-name/syng-im/compare/0.1.0...0.1.1

View File

@ -1,21 +1,14 @@
# messenger # syng-im
## Setup A Clojure library designed to ... well, that part is up to you.
https://github.com/drapanjanas/re-natal ## Usage
FIXME
Can be required after pulling changes: ## License
switching between android device Copyright © 2016 FIXME
https://github.com/drapanjanas/re-natal#switching-between-android-devices Distributed under the Eclipse Public License either version 1.0 or (at
your option) any later version.
Change `server-address` value at `/src/messenger/android/utils.cljs`
## Issues
`Requiring unknown module "react"`
Solution: https://github.com/exponentjs/react-native-invertible-scroll-view/issues/20

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="Messenger" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="Messenger" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":app" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
<afterSyncTasks>
<task>generateDebugAndroidTestSources</task>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/debug" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/drawee/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fbcore/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fresco/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline-okhttp/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.react/react-native/0.20.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/org.webkit/android-jsc/r174650/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="okhttp-ws-2.5.0" level="project" />
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
<orderEntry type="library" exported="" name="okio-1.6.0" level="project" />
<orderEntry type="library" exported="" name="stetho-okhttp-1.2.0" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.5.0" level="project" />
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
<orderEntry type="library" exported="" name="stetho-1.2.0" level="project" />
<orderEntry type="library" exported="" name="jackson-core-2.2.3" level="project" />
<orderEntry type="library" exported="" name="fbcore-0.8.1" level="project" />
<orderEntry type="library" exported="" name="commons-cli-1.2" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-0.8.1" level="project" />
<orderEntry type="library" exported="" name="android-jsc-r174650" level="project" />
<orderEntry type="library" exported="" name="fresco-0.8.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.8.1" level="project" />
<orderEntry type="library" exported="" name="bolts-android-1.1.4" level="project" />
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
<orderEntry type="library" exported="" name="drawee-0.8.1" level="project" />
<orderEntry type="library" exported="" name="react-native-0.20.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
<orderEntry type="module" module-name="react-native-contacts" exported="" />
</component>
</module>

View File

@ -26,9 +26,7 @@ import com.android.build.OutputFile
* *
* // whether to bundle JS and assets in another build variant (if configured). * // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats * // The configuration property is in the format 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true, * // bundleInFreeDebug: true,
* // bundleInPaidRelease: true, * // bundleInPaidRelease: true,
* // bundleInBeta: true, * // bundleInBeta: true,
@ -62,7 +60,8 @@ import com.android.build.OutputFile
apply from: "react.gradle" apply from: "react.gradle"
/** /**
* Set this to true to create two separate APKs instead of one: * Set this to true to create three separate APKs instead of one:
* - A universal APK that works on all devices
* - An APK that only works on ARM devices * - An APK that only works on ARM devices
* - An APK that only works on x86 devices * - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB. * The advantage is the size of the APK is reduced by about 4MB.
@ -81,7 +80,7 @@ android {
buildToolsVersion "23.0.1" buildToolsVersion "23.0.1"
defaultConfig { defaultConfig {
applicationId "com.messenger" applicationId "com.syngim"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 22 targetSdkVersion 22
versionCode 1 versionCode 1
@ -92,9 +91,9 @@ android {
} }
splits { splits {
abi { abi {
reset()
enable enableSeparateBuildPerCPUArchitecture enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK universalApk false
reset()
include "armeabi-v7a", "x86" include "armeabi-v7a", "x86"
} }
} }
@ -120,6 +119,9 @@ android {
} }
dependencies { dependencies {
compile project(':randombytes')
compile project(':realm')
compile project(':react-native-vector-icons')
compile fileTree(dir: "libs", include: ["*.jar"]) compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1" compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+" // From node_modules compile "com.facebook.react:react-native:+" // From node_modules
@ -128,6 +130,5 @@ dependencies {
// compile(name:'geth', ext:'aar') // compile(name:'geth', ext:'aar')
compile(group: 'syng-im', name: 'android-geth', version: '1.4.0-201603131817-92d65cf', ext: 'aar') compile(group: 'syng-im', name: 'android-geth', version: '1.4.0-201603131817-92d65cf', ext: 'aar')
compile project(":realm")
compile fileTree(dir: "node_modules/realm/android/libs", include: ["*.jar"]) compile fileTree(dir: "node_modules/realm/android/libs", include: ["*.jar"])
} }

View File

@ -30,20 +30,21 @@ gradle.projectsEvaluated {
productFlavors.each { productFlavorName -> productFlavors.each { productFlavorName ->
buildTypes.each { buildTypeName -> buildTypes.each { buildTypeName ->
// Create variant and target names // Create variant and source names
def targetName = "${productFlavorName.capitalize()}${buildTypeName.capitalize()}" def sourceName = "${buildTypeName}"
def targetPath = productFlavorName ? def targetName = "${sourceName.capitalize()}"
"${productFlavorName}/${buildTypeName}" : if (productFlavorName) {
"${buildTypeName}" sourceName = "${productFlavorName}${targetName}"
}
// React js bundle directories // React js bundle directories
def jsBundleDirConfigName = "jsBundleDir${targetName}" def jsBundleDirConfigName = "jsBundleDir${targetName}"
def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?: def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
file("$buildDir/intermediates/assets/${targetPath}") file("$buildDir/intermediates/assets/${sourceName}")
def resourcesDirConfigName = "jsBundleDir${targetName}" def resourcesDirConfigName = "jsBundleDir${targetName}"
def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?: def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
file("$buildDir/intermediates/res/merged/${targetPath}") file("$buildDir/intermediates/res/merged/${sourceName}")
def jsBundleFile = file("$jsBundleDir/$bundleAssetName") def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
// Bundle task name for variant // Bundle task name for variant
@ -79,9 +80,7 @@ gradle.projectsEvaluated {
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
} }
enabled config."bundleIn${targetName}" || enabled config."bundleIn${targetName}" ?: targetName.toLowerCase().contains("release")
config."bundleIn${buildTypeName.capitalize()}" ?:
targetName.toLowerCase().contains("release")
} }
// Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process // Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.messenger"> package="com.syngim">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" />

View File

@ -1,80 +0,0 @@
package com.messenger;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.rt2zz.reactnativecontacts.ReactNativeContacts;
import android.os.Bundle;
import android.os.Environment;
import com.github.ethereum.go_ethereum.cmd.Geth;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.io.File;
import com.i18n.reactnativei18n.ReactNativeI18n;
import io.realm.react.RealmReactPackage;
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Required for android-16 (???)
System.loadLibrary("gethraw");
System.loadLibrary("geth");
// Required because of crazy APN settings redirecting localhost
Properties properties = System.getProperties();
properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
properties.setProperty("https.nonProxyHosts", "localhost|127.0.0.1");
File extStore = Environment.getExternalStorageDirectory();
final String dataFolder = extStore.exists() ?
extStore.getAbsolutePath() :
getApplicationInfo().dataDir;
// Launch!
new Thread(new Runnable() {
public void run() {
Geth.run("--bootnodes enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:30303 --shh --ipcdisable --nodiscover --rpc --rpcapi db,eth,net,web3,shh --fast --datadir=" + dataFolder);
}
}).start();
}
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "Messenger";
}
/**
* Returns whether dev mode should be enabled.
* This enables e.g. the dev menu.
*/
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
/**
* A list of packages used by the app. If the app uses additional views
* or modules besides the default ones, add more packages here.
*/
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ReactNativeContacts(),
new ReactNativeI18n(),
new RealmReactPackage()
);
}
}

View File

@ -1,3 +1,3 @@
<resources> <resources>
<string name="app_name">Messenger</string> <string name="app_name">SyngIm</string>
</resources> </resources>

View File

@ -1,4 +1,4 @@
rootProject.name = 'Messenger' rootProject.name = 'SyngIm'
include ':app' include ':app'
@ -8,5 +8,9 @@ project(':react-native-contacts').projectDir = new File(settingsDir, '../node_mo
include ':react-native-i18n' include ':react-native-i18n'
project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android') project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android')
// realm dependency // realm dependency
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
include ':realm' include ':realm'
project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android') project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android')
include ':randombytes'
project(':randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/app')

View File

@ -1,3 +1,3 @@
# Introduction to messenger # Introduction to syng-im
TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)

View File

@ -1,16 +1,18 @@
(ns ^:figwheel-no-load env.android.main (ns ^:figwheel-no-load env.android.main
(:require [om.next :as om] (:require [reagent.core :as r]
[messenger.android.core :as core] [syng-im.android.core :refer [app-root]]
[messenger.omnext :as omnext] [figwheel.client :as figwheel :include-macros true]
[figwheel.client :as figwheel :include-macros true])) [syng-im.android.core :as core]))
(enable-console-print!) (enable-console-print!)
(def cnt (r/atom 0))
(defn reloader [] @cnt [app-root])
(def root-el (r/as-element [reloader]))
(figwheel/watch-and-reload (figwheel/watch-and-reload
:websocket-url "ws://localhost:3449/figwheel-ws" :websocket-url "ws://10.0.3.2:3449/figwheel-ws"
:heads-up-display true :heads-up-display true
:jsload-callback #(om/add-root! omnext/reconciler core/AppRoot 1)) :jsload-callback #(swap! cnt inc))
(core/init) (core/init)
(def root-el (core/app-root))

View File

@ -1,16 +1,17 @@
(ns ^:figwheel-no-load env.ios.main (ns ^:figwheel-no-load env.ios.main
(:require [om.next :as om] (:require [reagent.core :as r]
[messenger.ios.core :as core] [syng-im.ios.core :as core]
[messenger.omnext :as omnext]
[figwheel.client :as figwheel :include-macros true])) [figwheel.client :as figwheel :include-macros true]))
(enable-console-print!) (enable-console-print!)
(def cnt (r/atom 0))
(defn reloader [] @cnt [core/app-root])
(def root-el (r/as-element [reloader]))
(figwheel/watch-and-reload (figwheel/watch-and-reload
:websocket-url "ws://localhost:3449/figwheel-ws" :websocket-url "ws://localhost:3449/figwheel-ws"
:heads-up-display true :heads-up-display true
:jsload-callback #(om/add-root! omnext/reconciler core/AppRoot 1)) :jsload-callback #(swap! cnt inc))
(core/init) (core/init)
(def root-el (core/app-root))

View File

@ -1,4 +1,6 @@
(ns env.android.main (ns env.android.main
(:require [messenger.android.core :as core])) (:require [syng-im.android.core :as core]))
(core/init) (core/init)

View File

@ -1,4 +1,6 @@
(ns env.ios.main (ns env.ios.main
(:require [messenger.ios.core :as core])) (:require [syng-im.ios.core :as core]))
(core/init) (core/init)

View File

Before

Width:  |  Height:  |  Size: 916 B

After

Width:  |  Height:  |  Size: 916 B

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 124 B

After

Width:  |  Height:  |  Size: 124 B

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -5,7 +5,6 @@
}; };
objectVersion = 46; objectVersion = 46;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
@ -25,6 +24,19 @@
E343FE8E1C96F54100C01DB5 /* libRNI18n.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E343FE8B1C96F4E200C01DB5 /* libRNI18n.a */; }; E343FE8E1C96F54100C01DB5 /* libRNI18n.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E343FE8B1C96F4E200C01DB5 /* libRNI18n.a */; };
E343FE8F1C96F54A00C01DB5 /* libRCTContacts.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E343FE841C96F4DA00C01DB5 /* libRCTContacts.a */; }; E343FE8F1C96F54A00C01DB5 /* libRCTContacts.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E343FE841C96F4DA00C01DB5 /* libRCTContacts.a */; };
E343FE911C971D4200C01DB5 /* Geth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E343FE901C971D4200C01DB5 /* Geth.framework */; }; E343FE911C971D4200C01DB5 /* Geth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E343FE901C971D4200C01DB5 /* Geth.framework */; };
5F301739E81C4A7B92E80915 /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1429DFB76DE749D59880DD64 /* libRNVectorIcons.a */; };
2171A55FE83747678065F72A /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 93C8E68B46DA4C0A98C39F9D /* Entypo.ttf */; };
BDF23426F8854AC2A0416A03 /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 38E7B297EE0748008056796A /* EvilIcons.ttf */; };
221509FA6D5443C0B5215C52 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2CF9FE7E98A3454D980A0BED /* FontAwesome.ttf */; };
A33AC3EAFBC04C0B93BD2EC4 /* Foundation.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 5A831378BBA14830A9540B8C /* Foundation.ttf */; };
1A4121618C94428C9F0DF1FE /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 5F085711AC4A4BA3887A4655 /* Ionicons.ttf */; };
59FCD4F0208949BE80CC72BF /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0063E967269B49EE80DC3A77 /* MaterialIcons.ttf */; };
4452A93C123F4392A99A7719 /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A74F40BECFF8439FB1F41D8A /* Octicons.ttf */; };
1AE91A3E2C1A43EFA90C1CD7 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BCEC948817B84597AC493C0B /* Zocial.ttf */; };
34535F62E77D4A75A25E2981 /* libRNRandomBytes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2925028DE4684DDAAA7389D7 /* libRNRandomBytes.a */; };
97BD21CBE96A4223B253A1E2 /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B29C182EE0942C889049F91 /* libRealmReact.a */; };
22802A9C745148D885F0AA01 /* libc++.tbd in Resources */ = {isa = PBXBuildFile; fileRef = 8003209F13C24D35AABD3933 /* libc++.tbd */; };
50EE6BCC6F1A48BBA1BDB893 /* libz.tbd in Resources */ = {isa = PBXBuildFile; fileRef = 313A77B1D7804DBDBE6FF6F5 /* libz.tbd */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -153,6 +165,22 @@
E343FE7F1C96F4DA00C01DB5 /* RCTContacts.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTContacts.xcodeproj; path = "../node_modules/react-native-contacts/ios/RCTContacts.xcodeproj"; sourceTree = "<group>"; }; E343FE7F1C96F4DA00C01DB5 /* RCTContacts.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTContacts.xcodeproj; path = "../node_modules/react-native-contacts/ios/RCTContacts.xcodeproj"; sourceTree = "<group>"; };
E343FE851C96F4E200C01DB5 /* RNI18n.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNI18n.xcodeproj; path = "../node_modules/react-native-i18n/RNI18n.xcodeproj"; sourceTree = "<group>"; }; E343FE851C96F4E200C01DB5 /* RNI18n.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNI18n.xcodeproj; path = "../node_modules/react-native-i18n/RNI18n.xcodeproj"; sourceTree = "<group>"; };
E343FE901C971D4200C01DB5 /* Geth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Geth.framework; path = target/Frameworks/Geth.framework; sourceTree = "<group>"; }; E343FE901C971D4200C01DB5 /* Geth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Geth.framework; path = target/Frameworks/Geth.framework; sourceTree = "<group>"; };
F04672B9D3824B768FCF6F71 /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; name = "RNVectorIcons.xcodeproj"; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
1429DFB76DE749D59880DD64 /* libRNVectorIcons.a */ = {isa = PBXFileReference; name = "libRNVectorIcons.a"; path = "libRNVectorIcons.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
93C8E68B46DA4C0A98C39F9D /* Entypo.ttf */ = {isa = PBXFileReference; name = "Entypo.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
38E7B297EE0748008056796A /* EvilIcons.ttf */ = {isa = PBXFileReference; name = "EvilIcons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
2CF9FE7E98A3454D980A0BED /* FontAwesome.ttf */ = {isa = PBXFileReference; name = "FontAwesome.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
5A831378BBA14830A9540B8C /* Foundation.ttf */ = {isa = PBXFileReference; name = "Foundation.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Foundation.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
5F085711AC4A4BA3887A4655 /* Ionicons.ttf */ = {isa = PBXFileReference; name = "Ionicons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
0063E967269B49EE80DC3A77 /* MaterialIcons.ttf */ = {isa = PBXFileReference; name = "MaterialIcons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
A74F40BECFF8439FB1F41D8A /* Octicons.ttf */ = {isa = PBXFileReference; name = "Octicons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
BCEC948817B84597AC493C0B /* Zocial.ttf */ = {isa = PBXFileReference; name = "Zocial.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
06F26555B4054594966B6B08 /* RNRandomBytes.xcodeproj */ = {isa = PBXFileReference; name = "RNRandomBytes.xcodeproj"; path = "../node_modules/react-native-randombytes/RNRandomBytes.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
2925028DE4684DDAAA7389D7 /* libRNRandomBytes.a */ = {isa = PBXFileReference; name = "libRNRandomBytes.a"; path = "libRNRandomBytes.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
0D4A52AE301842E1B2533BD3 /* RealmReact.xcodeproj */ = {isa = PBXFileReference; name = "RealmReact.xcodeproj"; path = "../node_modules/realm/react-native/ios/RealmReact.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
2B29C182EE0942C889049F91 /* libRealmReact.a */ = {isa = PBXFileReference; name = "libRealmReact.a"; path = "libRealmReact.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
8003209F13C24D35AABD3933 /* libc++.tbd */ = {isa = PBXFileReference; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; };
313A77B1D7804DBDBE6FF6F5 /* libz.tbd */ = {isa = PBXFileReference; name = "libz.tbd"; path = "usr/lib/libz.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -180,6 +208,11 @@
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
5F301739E81C4A7B92E80915 /* libRNVectorIcons.a in Frameworks */,
34535F62E77D4A75A25E2981 /* libRNRandomBytes.a in Frameworks */,
97BD21CBE96A4223B253A1E2 /* libRealmReact.a in Frameworks */,
22802A9C745148D885F0AA01 /* libc++.tbd in Resources */,
50EE6BCC6F1A48BBA1BDB893 /* libz.tbd in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -304,6 +337,9 @@
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
F04672B9D3824B768FCF6F71 /* RNVectorIcons.xcodeproj */,
06F26555B4054594966B6B08 /* RNRandomBytes.xcodeproj */,
0D4A52AE301842E1B2533BD3 /* RealmReact.xcodeproj */,
); );
name = Libraries; name = Libraries;
sourceTree = "<group>"; sourceTree = "<group>";
@ -324,6 +360,7 @@
832341AE1AAA6A7D00B99B32 /* Libraries */, 832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* MessengerTests */, 00E356EF1AD99517003FC87E /* MessengerTests */,
83CBBA001A601CBA00E9B192 /* Products */, 83CBBA001A601CBA00E9B192 /* Products */,
A72CA0FB822D450E98649ACB /* Resources */,
); );
indentWidth = 2; indentWidth = 2;
sourceTree = "<group>"; sourceTree = "<group>";
@ -359,10 +396,28 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
E343FE901C971D4200C01DB5 /* Geth.framework */, E343FE901C971D4200C01DB5 /* Geth.framework */,
8003209F13C24D35AABD3933 /* libc++.tbd */,
313A77B1D7804DBDBE6FF6F5 /* libz.tbd */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
A72CA0FB822D450E98649ACB /* Resources */ = {
isa = PBXGroup;
children = (
93C8E68B46DA4C0A98C39F9D /* Entypo.ttf */,
38E7B297EE0748008056796A /* EvilIcons.ttf */,
2CF9FE7E98A3454D980A0BED /* FontAwesome.ttf */,
5A831378BBA14830A9540B8C /* Foundation.ttf */,
5F085711AC4A4BA3887A4655 /* Ionicons.ttf */,
0063E967269B49EE80DC3A77 /* MaterialIcons.ttf */,
A74F40BECFF8439FB1F41D8A /* Octicons.ttf */,
BCEC948817B84597AC493C0B /* Zocial.ttf */,
);
name = Resources;
path = "";
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -408,7 +463,7 @@
83CBB9F71A601CBA00E9B192 /* Project object */ = { 83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 0720; LastUpgradeCheck = 720;
ORGANIZATIONNAME = Facebook; ORGANIZATIONNAME = Facebook;
TargetAttributes = { TargetAttributes = {
00E356ED1AD99517003FC87E = { 00E356ED1AD99517003FC87E = {
@ -594,6 +649,14 @@
files = ( files = (
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
2171A55FE83747678065F72A /* Entypo.ttf in Resources */,
BDF23426F8854AC2A0416A03 /* EvilIcons.ttf in Resources */,
221509FA6D5443C0B5215C52 /* FontAwesome.ttf in Resources */,
A33AC3EAFBC04C0B93BD2EC4 /* Foundation.ttf in Resources */,
1A4121618C94428C9F0DF1FE /* Ionicons.ttf in Resources */,
59FCD4F0208949BE80CC72BF /* MaterialIcons.ttf in Resources */,
4452A93C123F4392A99A7719 /* Octicons.ttf in Resources */,
1AE91A3E2C1A43EFA90C1CD7 /* Zocial.ttf in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -675,6 +738,11 @@
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Messenger.app/Messenger"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Messenger.app/Messenger";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
}; };
name = Debug; name = Debug;
}; };
@ -693,6 +761,11 @@
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Messenger.app/Messenger"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Messenger.app/Messenger";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
}; };
name = Release; name = Release;
}; };
@ -709,6 +782,9 @@
"$(inherited)", "$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**", "$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-randombytes",
"$(SRCROOT)/../node_modules/realm/src/**",
); );
INFOPLIST_FILE = Messenger/Info.plist; INFOPLIST_FILE = Messenger/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@ -730,6 +806,9 @@
"$(inherited)", "$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**", "$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-randombytes",
"$(SRCROOT)/../node_modules/realm/src/**",
); );
INFOPLIST_FILE = Messenger/Info.plist; INFOPLIST_FILE = Messenger/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@ -778,6 +857,9 @@
"$(inherited)", "$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**", "$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-randombytes",
"$(SRCROOT)/../node_modules/realm/src/**",
); );
IPHONEOS_DEPLOYMENT_TARGET = 7.0; IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
@ -818,6 +900,9 @@
"$(inherited)", "$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**", "$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-randombytes",
"$(SRCROOT)/../node_modules/realm/src/**",
); );
IPHONEOS_DEPLOYMENT_TARGET = 7.0; IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;

View File

@ -1,5 +1,5 @@
{ {
"name": "Messenger", "name": "SyngIm",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
@ -8,10 +8,14 @@
"dependencies": { "dependencies": {
"awesome-phonenumber": "^1.0.12", "awesome-phonenumber": "^1.0.12",
"react-native": "^0.22.0", "react-native": "^0.22.0",
"react-native-action-button": "^1.1.3",
"react-native-circle-checkbox": "^0.1.3",
"react-native-contacts": "^0.2.1", "react-native-contacts": "^0.2.1",
"react-native-i18n": "0.0.8", "react-native-i18n": "0.0.8",
"react-native-invertible-scroll-view": "^0.2.0", "react-native-invertible-scroll-view": "^0.2.0",
"react-native-loading-spinner-overlay": "0.0.6", "react-native-loading-spinner-overlay": "0.0.6",
"realm": "^0.10.0" "react-native-randombytes": "^2.0.0",
"react-native-vector-icons": "^1.3.3",
"realm": "^0.11.0"
} }
} }

View File

@ -1,13 +1,15 @@
(defproject messenger "0.1.0-SNAPSHOT" (defproject syng-im "0.1.0-SNAPSHOT"
:description "FIXME: write description" :description "FIXME: write description"
:url "http://example.com/FIXME" :url "http://example.com/FIXME"
:license {:name "Eclipse Public License" :license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"} :url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.7.0"] :dependencies [[org.clojure/clojure "1.7.0"]
[org.clojure/clojurescript "1.7.170"] [org.clojure/clojurescript "1.7.170"]
[org.omcljs/om "1.0.0-alpha30" :exclusions [cljsjs/react cljsjs/react-dom]] [reagent "0.5.1" :exclusions [cljsjs/react]]
[natal-shell "0.1.6"] [re-frame "0.6.0"]
[syng-im/protocol "0.1.1"]] [prismatic/schema "1.0.4"]
[syng-im/protocol "0.1.1"]
[natal-shell "0.1.6"]]
:plugins [[lein-cljsbuild "1.1.1"] :plugins [[lein-cljsbuild "1.1.1"]
[lein-figwheel "0.5.0-2"]] [lein-figwheel "0.5.0-2"]]
:clean-targets ["target/" "index.ios.js" "index.android.js"] :clean-targets ["target/" "index.ios.js" "index.android.js"]
@ -16,12 +18,10 @@
["with-profile" "prod" "cljsbuild" "once" "ios"] ["with-profile" "prod" "cljsbuild" "once" "ios"]
["with-profile" "prod" "cljsbuild" "once" "android"]]} ["with-profile" "prod" "cljsbuild" "once" "android"]]}
:figwheel {:nrepl-port 7888} :figwheel {:nrepl-port 7888}
:profiles :profiles {:dev {:dependencies [[figwheel-sidecar "0.5.0-2"]
{:dev {:dependencies [[figwheel-sidecar "0.5.0-2"]
[com.cemerick/piggieback "0.2.1"]] [com.cemerick/piggieback "0.2.1"]]
:source-paths ["src" "env/dev"] :source-paths ["src" "env/dev"]
:cljsbuild {:builds :cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"]
{:ios {:source-paths ["src" "env/dev"]
:figwheel true :figwheel true
:compiler {:output-to "target/ios/not-used.js" :compiler {:output-to "target/ios/not-used.js"
:main "env.ios.main" :main "env.ios.main"
@ -34,8 +34,7 @@
:output-dir "target/android" :output-dir "target/android"
:optimizations :none}}}} :optimizations :none}}}}
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}} :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
:prod {:cljsbuild {:builds :prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"]
{:ios {:source-paths ["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" :output-dir "target/ios"
@ -44,4 +43,5 @@
:compiler {:output-to "index.android.js" :compiler {:output-to "index.android.js"
:main "env.android.main" :main "env.android.main"
:output-dir "target/android" :output-dir "target/android"
:optimizations :simple}}}}}}) :optimizations :simple}}}}
}})

View File

@ -1 +0,0 @@
(ns cljsjs.react.dom)

View File

@ -1,79 +0,0 @@
(ns messenger.android.core
(:require-macros
[natal-shell.components :refer [navigator view text image touchable-highlight
list-view toolbar-android]]
[natal-shell.data-source :refer [data-source clone-with-rows]]
[natal-shell.back-android :refer [add-event-listener remove-event-listener]]
[natal-shell.core :refer [with-error-view]]
[natal-shell.alert :refer [alert]])
(:require [om.next :as om :refer-macros [defui]]
[re-natal.support :as sup]
[messenger.omnext :as omnext]
[messenger.state :as state]
[messenger.utils.utils :refer [log toast]]
[messenger.android.login :refer [login Login]]
[messenger.comm.pubsub :as pubsub]
[messenger.comm.intercom :as intercom :refer [load-user-phone-number]]
[messenger.protocol.protocol-handler :refer [make-handler]]
[messenger.init :refer [init-simple-store]]
[messenger.components.chat.chat :as chat]
[syng-im.protocol.api :refer [init-protocol]]
[syng-im.utils.logging :as log]
[messenger.components.iname :as in]
[messenger.models.navigation :as n]
[messenger.components.contact-list.contact-list :refer [ContactList contact-list]]))
(def app-registry (.-AppRegistry js/React))
(def back-button-handler-atom (atom {:nav nil
:handler nil}))
(defn init-back-button-handler! [nav]
(let [back-button-handler @back-button-handler-atom]
(when (not= (:nav back-button-handler) nav)
(remove-event-listener "hardwareBackPress" (:handler back-button-handler))
(let [new-listener (fn []
(binding [state/*nav-render* false]
(when (< 1 (.-length (.getCurrentRoutes nav)))
(.pop nav)
true)))]
(reset! back-button-handler-atom {:nav nav
:handler new-listener})
(add-event-listener "hardwareBackPress" new-listener)))))
(defui AppRoot
static om/IQuery
(query [this]
(let [component (n/current-screen-class)]
[{(in/get-name component) (om/get-query component)}]))
Object
(render [this]
(log/debug "APPROOT Rendering")
(navigator
{:initialRoute {:component contact-list}
:renderScene (fn [route nav]
(log/debug "RENDER SCENE")
(when state/*nav-render*
(init-back-button-handler! nav)
(let [{:keys [component]} (js->clj route :keywordize-keys true)
props (om/props this)
props (om/computed props {:nav nav})]
(component props))))})))
;; TODO to service?
(swap! state/app-state assoc :contacts-ds
(data-source {:rowHasChanged (fn [row1 row2]
(not= row1 row2))}))
(defonce RootNode (sup/root-node! 1))
(defonce app-root (om/factory RootNode))
(defn init []
(n/set-current-screen-class ContactList)
(init-simple-store)
(pubsub/setup-pub-sub)
(init-protocol (make-handler))
(load-user-phone-number)
(om/add-root! omnext/reconciler AppRoot 1)
(.registerComponent app-registry "Messenger" (fn [] app-root)))

View File

@ -1,83 +0,0 @@
(ns messenger.android.login
(:require-macros
[natal-shell.components :refer [view text image touchable-highlight list-view
toolbar-android text-input]]
[natal-shell.core :refer [with-error-view]])
(:require [om.next :as om :refer-macros [defui]]
[re-natal.support :as sup]
[messenger.state :as state]
[messenger.comm.intercom :as intercom :refer [set-user-phone-number]]
[messenger.utils.utils :refer [log toast http-post]]
[messenger.utils.phone-number :refer [format-phone-number]]
[messenger.utils.resources :as res]
[messenger.components.spinner :refer [spinner]]
[messenger.android.sign-up-confirm :refer [sign-up-confirm]]
[messenger.constants :refer [ethereum-rpc-url]]
[messenger.components.iname :as in]))
(def nav-atom (atom nil))
(defn show-confirm-view []
(swap! state/app-state assoc :loading false)
(intercom/show-signup-confirm @nav-atom))
(defn sign-up []
(swap! state/app-state assoc :loading true)
(let [app-state (state/state)
phone-number (:user-phone-number app-state)
whisper-identity (:public (:user-identity app-state))]
(intercom/sign-up phone-number whisper-identity show-confirm-view)))
(defn update-phone-number [value]
(let [formatted (format-phone-number value)]
(set-user-phone-number formatted)))
(defui Login
static in/IName
(get-name [this]
:login/login)
static om/IQuery
(query [this]
'[:user-phone-number :user-identity :loading])
Object
(render [this]
(let [{{:keys [user-phone-number user-identity loading]} :login/login} (om/props this)
{:keys [nav]} (om/get-computed this)]
(reset! nav-atom nav)
(view
{:style {:flex 1}}
(view
{:style {:flex 1
:backgroundColor "white"}}
(toolbar-android {:logo res/logo-icon
:title "Login"
:titleColor "#4A5258"
:style {:backgroundColor "white"
:height 56
:elevation 2}})
(view {:style { ;; :alignItems "center"
}}
(text-input {:underlineColorAndroid "#9CBFC0"
:placeholder "Enter your phone number"
:keyboardType "phone-pad"
:onChangeText (fn [value]
(update-phone-number value))
:style {:flex 1
:marginHorizontal 18
:lineHeight 42
:fontSize 14
:fontFamily "Avenir-Roman"
:color "#9CBFC0"}}
user-phone-number)
(touchable-highlight {:onPress #(sign-up)
:style {:alignSelf "center"
:borderRadius 7
:backgroundColor "#E5F5F6"
:width 100}}
(text {:style {:marginVertical 10
:textAlign "center"}}
"Sign up"))))
(when (or loading (not user-identity))
(spinner {:visible true}))))))
(def login (om/factory Login))

View File

@ -1,108 +0,0 @@
(ns messenger.android.sign-up-confirm
(:require-macros
[natal-shell.components :refer [view text image touchable-highlight list-view
toolbar-android text-input]]
[natal-shell.async-storage :refer [get-item set-item]]
[natal-shell.core :refer [with-error-view]]
[natal-shell.alert :refer [alert]])
(:require [om.next :as om :refer-macros [defui]]
[re-natal.support :as sup]
[messenger.state :as state]
[messenger.utils.utils :refer [log toast]]
[messenger.utils.resources :as res]
[messenger.components.spinner :refer [spinner]]
[messenger.components.contact-list.contact-list :refer [contact-list]]
[messenger.comm.intercom :as intercom :refer [set-confirmation-code]]
[messenger.components.iname :as in]))
(def nav-atom (atom nil))
(defn show-home-view []
(swap! state/app-state assoc :loading false)
(intercom/show-contacts @nav-atom))
(defn sync-contacts []
(intercom/sync-contacts show-home-view))
(defn on-send-code-response [body]
(log body)
(toast (if (:confirmed body)
"Confirmed"
"Wrong code"))
(when (:confirmed body)
;; TODO user action required
(sync-contacts)))
(defn code-valid? [code]
(= 4 (count code)))
(defn send-code [code]
(when (code-valid? code)
(swap! state/app-state assoc :loading true)
(intercom/sign-up-confirm code on-send-code-response)))
(defn update-code [value]
(let [formatted value]
(set-confirmation-code formatted)))
(defui SignUpConfirm
static in/IName
(get-name [this]
:signup/confirm)
static om/IQuery
(query [this]
'[:confirmation-code :loading])
Object
(render
[this]
(let [{{:keys [confirmation-code loading]} :signup/confirm} (om/props this)
{:keys [nav]} (om/get-computed this)]
(reset! nav-atom nav)
(view
{:style {:flex 1}}
(view
{:style {:flex 1
:backgroundColor "white"}}
(toolbar-android {:logo res/logo-icon
:title "Confirm"
:titleColor "#4A5258"
:style {:backgroundColor "white"
:height 56
:elevation 2}})
(view {}
(text-input {:underlineColorAndroid "#9CBFC0"
:placeholder "Enter confirmation code"
:keyboardType "number-pad"
:maxLength 4
:onChangeText (fn [value]
(update-code value))
:style {:flex 1
:marginHorizontal 18
:lineHeight 42
:fontSize 14
:fontFamily "Avenir-Roman"
:color "#9CBFC0"}}
confirmation-code)
(if (code-valid? confirmation-code)
(touchable-highlight
{:onPress #(send-code confirmation-code)
:style {:alignSelf "center"
:borderRadius 7
:backgroundColor "#E5F5F6"
:width 100}}
(text {:style {:marginVertical 10
:textAlign "center"}}
"Confirm"))
(view
{:style {:alignSelf "center"
:borderRadius 7
:backgroundColor "#AAB2B2"
:width 100}}
(text {:style {:marginVertical 10
:textAlign "center"}}
"Confirm")))))
(when loading
(spinner {:visible true}))))))
(def sign-up-confirm (om/factory SignUpConfirm))

View File

@ -1,75 +0,0 @@
(ns messenger.comm.intercom
(:require [cljs.core.async :as async :refer [put!]]
[messenger.state :refer [state
pub-sub-publisher]]
[syng-im.utils.logging :as log]))
(defn publish! [topic message]
(let [publisher (->> (state)
(pub-sub-publisher))]
(put! publisher [topic message])))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; user data
(defn set-user-phone-number [phone-number]
(publish! :service [:user-data :user-data/set-phone-number phone-number]))
(defn save-user-phone-number [phone-number]
(publish! :service [:user-data :user-data/save-phone-number phone-number]))
(defn load-user-phone-number []
;; :service [service_name action_id args_map]
(publish! :service [:user-data :user-data/load-phone-number nil]))
(defn set-confirmation-code [confirmation-code]
(publish! :service [:user-data :user-data/set-confirmation-code confirmation-code]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; server
(defn sign-up [phone-number whisper-identity handler]
(publish! :service [:server :server/sign-up {:phone-number phone-number
:whisper-identity whisper-identity
:handler handler}]))
(defn sign-up-confirm [confirmation-code handler]
(publish! :service [:server :server/sign-up-confirm
{:confirmation-code confirmation-code
:handler handler}]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; contacts
(defn load-syng-contacts []
(publish! :service [:contacts :contacts/load-syng-contacts nil]))
(defn sync-contacts [handler]
(publish! :service [:contacts :contacts/sync-contacts handler]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; protocol
(defn protocol-initialized [identity]
(publish! :service [:protocol :protocol/initialized {:identity identity}]))
(defn save-new-msg [msg]
(publish! :service [:protocol :protocol/save-new-msg {:msg msg}]))
(defn send-msg [chat-id text]
(publish! :service [:protocol :protocol/send-msg {:chat-id chat-id
:text text}]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; navigate-to
(defn show-chat [navigator chat-id]
(publish! :service [:navigate-to :scene/chat {:chat-id chat-id
:navigator navigator}]))
(defn show-signup-confirm [navigator]
(publish! :service [:navigate-to :scene/signup-confirm {:navigator navigator}]))
(defn show-contacts [navigator]
(publish! :service [:navigate-to :scene/contacts {:navigator navigator}]))

View File

@ -1,33 +0,0 @@
(ns messenger.comm.pubsub
(:require-macros [cljs.core.async.macros :refer [go alt!]])
(:require [cljs.core.async :as async :refer [chan pub sub]]
[messenger.state :refer [state
pub-sub-publisher
app-state
pub-sub-path]]
[messenger.comm.services :refer [services-handler]]
[messenger.utils.event :refer [handle-channel-events]]))
(defn service-id [message]
(first message))
(defn payload [message]
(rest message))
(defn subscribe-handler [publication topic handler]
(let [chn (chan)]
(sub publication topic chn)
(handle-channel-events chn (fn [_topic message]
(handler app-state
(service-id message)
(payload message))))))
(defn setup-publication! [app-state]
(let [publisher (pub-sub-publisher @app-state)
publication (pub publisher first)]
(swap! app-state assoc-in pub-sub-path publication)
publication))
(defn setup-pub-sub []
(-> (setup-publication! app-state)
(subscribe-handler :service services-handler)))

View File

@ -1,35 +0,0 @@
(ns messenger.comm.services
(:require
[syng-im.utils.logging :as log]
[messenger.services.user-data :refer [user-data-handler]]
[messenger.services.protocol :refer [protocol-handler]]
[messenger.services.server :refer [server-handler]]
[messenger.services.contacts :refer [contacts-handler]]
[messenger.services.navigate-to :refer [navigate-to-handler]]))
(defmulti service (fn [state service-id args]
service-id))
(defmethod service :user-data
[state service-id args]
(user-data-handler state args))
(defmethod service :server
[state service-id args]
(server-handler state args))
(defmethod service :contacts
[state service-id args]
(contacts-handler state args))
(defmethod service :protocol
[state service-id args]
(protocol-handler state args))
(defmethod service :navigate-to
[state service-id args]
(navigate-to-handler state args))
(defn services-handler [state service-id args]
(log/info "handling " service-id " args = " args)
(service state service-id args))

View File

@ -1,91 +0,0 @@
(ns messenger.components.chat.chat
(:require-macros
[natal-shell.components :refer [view list-view toolbar-android]]
[natal-shell.data-source :refer [data-source clone-with-rows]])
(:require [om.next :as om :refer-macros [defui]]
[messenger.utils.resources :as res]
[messenger.components.invertible-scroll-view :refer [invertible-scroll-view]]
[messenger.components.chat.message :refer [message]]
[messenger.components.chat.new-message :refer [new-message NewMessage]]
[messenger.state :as state]
[syng-im.utils.logging :as log]
[messenger.components.iname :as in]
[messenger.omnext :as omnext]))
;(defn generate-message [n]
; {:id n
; :type (if (= (rem n 4) 3)
; :audio
; :text)
; :body (if (= (rem n 3) 0)
; (apply str n "." (repeat 5 " This is a text."))
; (str n ". This is a text."))
; :outgoing (< (rand) 0.5)
; :delivery-status (if (< (rand) 0.5) :delivered :seen)
; :date "TODAY"
; :new-day (= (rem n 3) 0)})
;
;(defn generate-messages [n]
; (map generate-message (range 1 (inc n))))
;(defn load-messages []
; (clone-with-rows (data-source {:rowHasChanged (fn [row1 row2]
; (not= row1 row2))})
; (vec (generate-messages 100))))
;
(defn to-datasource [msgs]
(-> (data-source {:rowHasChanged (fn [row1 row2]
(not= row1 row2))})
(clone-with-rows msgs)))
(defn nav-pop [nav]
(binding [state/*nav-render* false]
(.pop nav)))
(defn render-row [row section-id row-id]
(message (js->clj row :keywordize-keys true)))
(defui Chat
static in/IName
(get-name [this]
:chat/chat)
static om/IQuery
(query [this]
`[:chat/messages ~@(om/get-query NewMessage)])
Object
(componentDidMount [this]
(om.next.protocols/reindex! omnext/reconciler))
(render
[this]
(let [{:keys [nav]} (om/get-computed this)
{{messages :chat/messages
chat-id :chat/chat-id} :chat/chat} (om/props this)
_ (log/debug "messages=" messages)
messages-ds (when messages
(to-datasource messages))]
(view {:style {:flex 1
:backgroundColor "white"}}
(toolbar-android {:logo res/logo-icon
:title "Chat name"
:titleColor "#4A5258"
:subtitle "Last seen just now"
:subtitleColor "#AAB2B2"
:navIcon res/nav-back-icon
:style {:backgroundColor "white"
:height 56
:elevation 2}
:onIconClicked (fn []
(nav-pop nav))})
(when messages-ds
(list-view {:dataSource messages-ds
:renderScrollComponent
(fn [props]
(invertible-scroll-view nil))
:renderRow render-row
:style {:backgroundColor "white"}}))
(new-message {:chat-id chat-id})))))
(def chat (om/factory Chat))

View File

@ -1,107 +0,0 @@
(ns messenger.components.chat.message
(:require-macros
[natal-shell.components :refer [view text image]])
(:require [om.next :as om :refer-macros [defui]]
[messenger.utils.resources :as res]
[messenger.constants :refer [text-content-type]]))
(defui Message
static om/Ident
(ident [this {:keys [msg-id]}]
[:message/by-id msg-id])
static om/IQuery
(query [this]
'[:msg-id :content :content-type :outgoing :delivery-status :date :new-day])
Object
(render
[this]
(let [{:keys [msg-id content content-type outgoing delivery-status date new-day] :as props} (om/props this)]
(view {:paddingHorizontal 15}
;;; date
(when new-day
(text {:style {:marginVertical 10
:fontFamily "Avenir-Roman"
:fontSize 11
:color "#AAB2B2"
:letterSpacing 1
:lineHeight 15
:textAlign "center"
:opacity 0.8}}
date))
;;; body
(view {:style (merge {:flexDirection "column"
:width 260
:marginVertical 5}
(if outgoing
{:alignSelf "flex-end"
:alignItems "flex-end"}
{:alignSelf "flex-start"
:alignItems "flex-start"}))}
(view {:style (merge {:borderRadius 6}
(if (= content-type text-content-type)
{:paddingVertical 12
:paddingHorizontal 16}
{:paddingVertical 14
:paddingHorizontal 10})
(if outgoing
{:backgroundColor "#D3EEEF"}
{:backgroundColor "#FBF6E3"}))}
(if (= content-type text-content-type)
(text {:style {:fontSize 14
:fontFamily "Avenir-Roman"
:color "#4A5258"}}
content)
;;; audio
(view {:style {:flexDirection "row"
:alignItems "center"}}
(view {:style {:width 33
:height 33
:borderRadius 50
:elevation 1}}
(image {:source res/play
:style {:width 33
:height 33}}))
(view {:style {:marginTop 10
:marginLeft 10
:width 120
:height 26
:elevation 1}}
(view {:style {:position "absolute"
:top 4
:width 120
:height 2
:backgroundColor "#EC7262"}})
(view {:style {:position "absolute"
:left 0
:top 0
:width 2
:height 10
:backgroundColor "#4A5258"}})
(text {:style {:position "absolute"
:left 1
:top 11
:fontFamily "Avenir-Roman"
:fontSize 11
:color "#4A5258"
:letterSpacing 1
:lineHeight 15}}
"03:39")))))
;;; delivery status
(when (and outgoing delivery-status)
(view {:style {:flexDirection "row"
:marginTop 2}}
(image {:source (if (= (keyword delivery-status) :seen)
res/seen-icon
res/delivered-icon)
:style {:marginTop 6
:opacity 0.6}})
(text {:style {:fontFamily "Avenir-Roman"
:fontSize 11
:color "#AAB2B2"
:opacity 0.8
:marginLeft 5}}
(if (= (keyword delivery-status) :seen)
"Seen"
"Delivered")))))))))
(def message (om/factory Message {:keyfn :msg-id}))

View File

@ -1,60 +0,0 @@
(ns messenger.components.chat.new-message
(:require-macros
[natal-shell.components :refer [view image text-input]])
(:require [om.next :as om :refer-macros [defui]]
[messenger.utils.resources :as res]
[syng-im.utils.logging :as log]
[messenger.utils.state :refer [from-state]]
[messenger.comm.intercom :refer [send-msg]]))
(def local-state (atom {}))
(defui NewMessage
static om/IQuery
(query [this]
'[:chat/chat-id])
Object
(render [this]
(view {:style {:flexDirection "row"
:margin 10
:height 40
:backgroundColor "#E5F5F6"
:borderRadius 5}}
(image {:source res/mic
:style {:marginTop 11
:marginLeft 14
:width 13
:height 20}})
(text-input {:underlineColorAndroid "#9CBFC0"
:style {:flex 1
:marginLeft 18
:lineHeight 42
:fontSize 14
:fontFamily "Avenir-Roman"
:color "#9CBFC0"}
:autoFocus true
:placeholder "Enter your message here"
:value (from-state this :text)
:onChangeText (fn [text]
;(log/debug (with-out-str (pr (js->clj (om/props this)))) (-> (om/props this) :chat-id))
;(om/set-state! this (clj->js {:text text}))
(swap! local-state assoc :text text)
)
:onSubmitEditing (fn [e]
(let [chat-id (-> (om/props this) :chat-id)
;text (from-state this :text)
text (get @local-state :text)]
;(om/set-state! this (clj->js {:text nil}))
(send-msg chat-id text)))})
(image {:source res/smile
:style {:marginTop 11
:marginRight 12
:width 18
:height 18}})
(image {:source res/att
:style {:marginTop 14
:marginRight 16
:width 17
:height 14}}))))
(def new-message (om/factory NewMessage))

View File

@ -1,120 +0,0 @@
(ns messenger.components.contact-list.contact
(:require-macros
[natal-shell.components :refer [view text image touchable-highlight]])
(:require [om.next :as om :refer-macros [defui]]
[messenger.state :as state]
[messenger.utils.utils :refer [log toast http-post]]
[messenger.utils.resources :as res]
[messenger.comm.intercom :as intercom :refer [show-chat]]
[messenger.components.chat.chat :refer [chat]]))
(def react-native-contacts (js/require "react-native-contacts"))
(defui Contact
static om/Ident
(ident [this {:keys [name]}]
[:contact/by-name name])
static om/IQuery
(query [this]
'[:name :photo-path :delivery-status :datetime :new-messages-count :online :whisper-identity])
Object
(render [this]
(let [{:keys [name photo-path delivery-status datetime new-messages-count online whisper-identity]}
(dissoc (om/props this) :om.next/computed)
{:keys [nav]} (om/get-computed this)]
(touchable-highlight
{:onPress (fn []
(show-chat nav whisper-identity))}
(view {:style {:flexDirection "row"
:marginTop 5
:marginBottom 5
:paddingLeft 15
:paddingRight 15
:height 75}}
(view {:width 54
:height 54}
;;; photo
(view {:width 54
:height 54
:borderRadius 50
:backgroundColor "#FFFFFF"
:elevation 6}
(image {:source (if (< 0 (count photo-path))
{:uri photo-path}
res/user-no-photo)
:style {:borderWidth 2
:borderColor "#FFFFFF"
:borderRadius 50
:width 54
:height 54
:position "absolute"}}))
;;; online
(when online
(view {:position "absolute"
:top 41
:left 36
:width 12
:height 12
:borderRadius 50
:backgroundColor "#FFFFFF"
:elevation 6}
(image {:source res/online-icon
:style {:width 12
:height 12}}))))
(view {:style {:flexDirection "column"
:marginLeft 7
:marginRight 10
:flex 1
:position "relative"}}
;;; name
(text {:style {:fontSize 15
:fontFamily "Avenir-Roman"}} name)
;;; last message
(text {:style {:color "#AAB2B2"
:fontFamily "Avenir-Roman"
:fontSize 14
:marginTop 2
:paddingRight 10}}
(str "Hi, I'm " name)))
(view {:style {:flexDirection "column"}}
;;; delivery status
(view {:style {:flexDirection "row"
:position "absolute"
:top 0
:right 0}}
(when delivery-status
(image {:source (if (= (keyword delivery-status) :seen)
res/seen-icon
res/delivered-icon)
:style {:marginTop 5}}))
;;; datetime
(text {:style {:fontFamily "Avenir-Roman"
:fontSize 11
:color "#AAB2B2"
:letterSpacing 1
:lineHeight 15
:marginLeft 5}}
datetime))
;;; new messages count
(when (< 0 new-messages-count)
(view {:style {:position "absolute"
:right 0
:bottom 24
:width 18
:height 18
:backgroundColor "#6BC6C8"
:borderColor "#FFFFFF"
:borderRadius 50
:alignSelf "flex-end"}}
(text {:style {:width 18
:height 17
:fontFamily "Avenir-Roman"
:fontSize 10
:color "#FFFFFF"
:lineHeight 19
:textAlign "center"
:top 1}}
new-messages-count)))))))))
(def contact (om/factory Contact {:keyfn :name}))

View File

@ -1,47 +0,0 @@
(ns messenger.components.contact-list.contact-list
(:require-macros
[natal-shell.components :refer [view text image touchable-highlight list-view
toolbar-android]]
[natal-shell.core :refer [with-error-view]])
(:require [om.next :as om :refer-macros [defui]]
[messenger.utils.utils :refer [log toast http-post]]
[messenger.utils.resources :as res]
[messenger.comm.intercom :as intercom]
[messenger.components.contact-list.contact :refer [contact]]
[messenger.components.iname :as in]
[syng-im.utils.logging :as log]))
(defn render-row [nav row section-id row-id]
(contact (om/computed (js->clj row :keywordize-keys true)
{:nav nav})))
(defn load-contacts []
(intercom/load-syng-contacts))
(defui ContactList
static in/IName
(get-name [this]
:contacts/contacts)
static om/IQuery
(query [this]
'[:contacts-ds])
Object
(componentDidMount [this]
(load-contacts))
(render [this]
(let [{{contacts-ds :contacts-ds} :contacts/contacts} (om/props this)
{:keys [nav]} (om/get-computed this)]
(view {:style {:flex 1
:backgroundColor "white"}}
(toolbar-android {:logo res/logo-icon
:title "Chats"
:titleColor "#4A5258"
:style {:backgroundColor "white"
:height 56
:elevation 2}})
(when contacts-ds
(list-view {:dataSource contacts-ds
:renderRow (partial render-row nav)
:style {:backgroundColor "white"}}))))))
(def contact-list (om/factory ContactList))

View File

@ -1,4 +0,0 @@
(ns messenger.components.iname)
(defprotocol IName
(get-name [this]))

View File

@ -1,7 +0,0 @@
(ns messenger.components.invertible-scroll-view)
(set! js/InvertibleScrollView (js/require "react-native-invertible-scroll-view"))
(defn invertible-scroll-view [props]
(js/React.createElement js/InvertibleScrollView
(clj->js (merge {:inverted true} props))))

View File

@ -1,7 +0,0 @@
(ns messenger.components.spinner)
(set! js/Spinner (.-default (js/require "react-native-loading-spinner-overlay")))
(defn spinner [props]
(js/React.createElement js/Spinner
(clj->js props)))

View File

@ -1,5 +0,0 @@
(ns messenger.constants)
(def ethereum-rpc-url "http://localhost:8545")
(def text-content-type "text/plain")

View File

@ -1,6 +0,0 @@
(ns messenger.init
(:require [messenger.persistence.simple-kv-store :as kv]
[messenger.state :as state]))
(defn init-simple-store []
(swap! state/app-state assoc-in state/simple-store-path (kv/->SimpleKvStore)))

View File

@ -1,33 +0,0 @@
(ns messenger.ios.core
(:require-macros [natal-shell.components :refer [view text image touchable-highlight]]
[natal-shell.alert :refer [alert]])
(:require [om.next :as om :refer-macros [defui]]
[re-natal.support :as sup]
[messenger.omnext :as omnext]))
(set! js/React (js/require "react-native"))
(def app-registry (.-AppRegistry js/React))
(def logo-img (js/require "./images/cljs.png"))
(defui AppRoot
static om/IQuery
(query [this]
'[:app/msg])
Object
(render [this]
(let [{:keys [app/msg]} (om/props this)]
(view {:style {:flexDirection "column" :margin 40 :alignItems "center"}}
(text {:style {:fontSize 30 :fontWeight "100" :marginBottom 20 :textAlign "center"}} msg)
(image {:source logo-img
:style {:width 80 :height 80 :marginBottom 30}})
(touchable-highlight {:style {:backgroundColor "#999" :padding 10 :borderRadius 5}
:onPress #(alert "HELLO!")}
(text {:style {:color "white" :textAlign "center" :fontWeight "bold"}} "press me"))))))
(defonce RootNode (sup/root-node! 1))
(defonce app-root (om/factory RootNode))
(defn init []
(om/add-root! omnext/reconciler AppRoot 1)
(.registerComponent app-registry "Messenger" (fn [] app-root)))

View File

@ -1,8 +0,0 @@
(ns messenger.models.chat
(:require [messenger.state :as state]))
(defn set-current-chat-id [chat-id]
(swap! state/app-state assoc-in state/current-chat-id-path chat-id))
(defn current-chat-id []
(get-in @state/app-state state/current-chat-id-path))

View File

@ -1,78 +0,0 @@
(ns messenger.models.contacts
(:require-macros [natal-shell.data-source :refer [data-source clone-with-rows]])
(:require [cljs.core.async :as async :refer [chan put! <! >!]]
[messenger.state :as state]
[messenger.utils.utils :refer [log toast http-post]]
[messenger.persistence.realm :as realm]))
(def fake-contacts? false)
(def react-native-contacts (js/require "react-native-contacts"))
(defn- generate-contact [n]
{:name (str "Contact " n)
:photo-path ""
:phone-numbers [{:label "mobile" :number (apply str (repeat 7 n))}]
:delivery-status (if (< (rand) 0.5) :delivered :seen)
:datetime "15:30"
:new-messages-count (rand-int 3)
:online (< (rand) 0.5)})
(defn- generate-contacts [n]
(map generate-contact (range 1 (inc n))))
(defn load-phone-contacts []
(let [ch (chan)]
(if fake-contacts?
(put! ch {:error nil, :contacts (generate-contacts 10)})
(.getAll react-native-contacts
(fn [error raw-contacts]
(put! ch
{:error error
:contacts
(when (not error)
(map (fn [contact]
(merge contact
(generate-contact 1)
{:name (:givenName contact)
:photo-path (:thumbnailPath contact)
:phone-numbers (:phoneNumbers contact)}))
(js->clj raw-contacts :keywordize-keys true)))}))))
ch))
(defn- get-contacts []
(realm/get-list "Contact"))
(defn load-syng-contacts []
(let [contacts (map (fn [contact]
(merge contact
{:delivery-status (if (< (rand) 0.5) :delivered :seen)
:datetime "15:30"
:new-messages-count (rand-int 3)
:online (< (rand) 0.5)}))
(get-contacts))]
(swap! state/app-state update :contacts-ds
#(clone-with-rows % contacts))))
(defn- create-contact [{:keys [phone-number whisper-identity name photo-path]}]
(realm/create "Contact"
{:phone-number phone-number
:whisper-identity whisper-identity
:name (or name "")
:photo-path (or photo-path "")}))
(defn- contact-exist? [contacts contact]
(some #(= (:phone-number contact) (:phone-number %)) contacts))
(defn- add-contacts [contacts]
(realm/write (fn []
(let [db-contacts (get-contacts)]
(dorun (map (fn [contact]
(if (not (contact-exist? db-contacts contact))
(create-contact contact)
;; TODO else override?
))
contacts))))))
(defn save-syng-contacts [syng-contacts]
(add-contacts syng-contacts))

View File

@ -1,42 +0,0 @@
(ns messenger.models.messages
(:require [messenger.persistence.realm :as r]
[cljs.reader :refer [read-string]]
[syng-im.utils.random :refer [timestamp]]))
(defn save-message [chat-id {:keys [from to msg-id content content-type outgoing] :or {outgoing false} :as msg}]
(when-not (r/exists? :msgs :msg-id msg-id)
(r/write
(fn []
(r/create :msgs {:chat-id chat-id
:msg-id msg-id
:from from
:to to
:content content
:content-type content-type
:outgoing outgoing
:timestamp (timestamp)} true)))))
(defn get-messages* [chat-id]
(-> (r/get-by-field :msgs :chat-id chat-id)
(r/sorted :timestamp :desc)
(r/page 0 10)))
(defn get-messages [chat-id]
(-> (get-messages* chat-id)
(js->clj :keywordize-keys true)))
(comment
(save-message "0x040028c500ff086ecf1cfbb3c1a7240179cde5b86f9802e6799b9bbe9cdd7ad1b05ae8807fa1f9ed19cc8ce930fc2e878738c59f030a6a2f94b3522dc1378ff154"
{:msg-id "153"
:content "hello!"
:content-type "text/plain"})
(get-messages* "0x040028c500ff086ecf1cfbb3c1a7240179cde5b86f9802e6799b9bbe9cdd7ad1b05ae8807fa1f9ed19cc8ce930fc2e878738c59f030a6a2f94b3522dc1378ff154")
(get-messages "0x043df89d36f6e3d8ade18e55ac3e2e39406ebde152f76f2f82d674681d59319ffd9880eebfb4f5f8d5c222ec485b44d6e30ba3a03c96b1c946144fdeba1caccd43")
(doseq [msg (get-messages* "0x043df89d36f6e3d8ade18e55ac3e2e39406ebde152f76f2f82d674681d59319ffd9880eebfb4f5f8d5c222ec485b44d6e30ba3a03c96b1c946144fdeba1caccd43")]
(r/delete msg))
)

View File

@ -1,8 +0,0 @@
(ns messenger.models.navigation
(:require [messenger.state :as state]))
(defn set-current-screen-class [class]
(swap! state/app-state assoc-in [:current-screen-class] class))
(defn current-screen-class []
(get-in @state/app-state [:current-screen-class]))

View File

@ -1,23 +0,0 @@
(ns messenger.models.protocol
(:require [cljs.reader :refer [read-string]]
[messenger.state :as state]
[syng-im.protocol.state.storage :as s]
[syng-im.utils.encryption :refer [password-encrypt
password-decrypt]]
[messenger.utils.types :refer [to-edn-string]]))
(defn set-initialized [initialized?]
(swap! state/app-state assoc-in state/protocol-initialized-path initialized?))
(defn update-identity [identity]
(let [password (get-in @state/app-state state/identity-password-path)
encrypted (->> (to-edn-string identity)
(password-encrypt password))]
(s/put (state/kv-store) :identity encrypted)))
(defn current-identity []
(let [encrypted (s/get (state/kv-store) :identity)
password (get-in @state/app-state state/identity-password-path)]
(when encrypted
(-> (password-decrypt password encrypted)
(read-string)))))

View File

@ -1,28 +0,0 @@
(ns messenger.models.user-data
(:require-macros
[natal-shell.async-storage :refer [get-item set-item]])
(:require [cljs.core.async :as async :refer [chan put! <! >!]]
[syng-im.protocol.web3 :as web3]
[messenger.state :as state]
[messenger.utils.utils :refer [log on-error toast]]))
(defn set-phone-number [phone-number]
(swap! state/app-state assoc :user-phone-number phone-number))
(defn save-phone-number [phone-number]
(set-item "user-phone-number" phone-number)
(swap! state/app-state assoc :user-phone-number phone-number))
(defn load-phone-number []
(get-item "user-phone-number"
(fn [error value]
(if error
(on-error error)
(swap! state/app-state assoc :user-phone-number (when value
(str value)))))))
(defn set-identity [identity]
(swap! state/app-state assoc :user-identity identity))
(defn set-confirmation-code [code]
(swap! state/app-state assoc :confirmation-code code))

View File

@ -1,74 +0,0 @@
(ns messenger.omnext
(:require [om.next :as om]
[syng-im.utils.logging :as log]
[re-natal.support :as sup]
[messenger.models.messages :as msgs]
[messenger.models.chat :as chat]
[messenger.state :as state]
[messenger.components.iname :as in]))
(defmulti read om/dispatch)
(defmethod read :default [{:keys [state] :as env} key param]
(log/debug "reading" "key=" key "param=" param)
(let [st @state]
(if-let [[_ v] (find st key)]
{:value v}
{:value :not-found})))
(defmethod read :chat/chat [env key param]
(log/debug "reading" "key=" key "param=" param)
(let [chat-id (chat/current-chat-id)
val {:value {:chat/messages (msgs/get-messages chat-id)
:chat/chat-id chat-id}}
_ (log/debug "returning" val)]
val))
(defmethod read :chat/messages [env key param]
(log/debug "reading" "key=" key "param=" param)
(let [chat-id (chat/current-chat-id)
val {:value {:chat/messages (msgs/get-messages chat-id)
:chat/chat-id chat-id}}
_ (log/debug "returning" val)]
val))
(defmethod read :contacts/contacts [env key param]
(log/debug "reading" "key=" key "param=" param)
(let [val {:value {:contacts-ds (get-in @state/app-state [:contacts-ds])}}
_ (log/debug "returning" val)]
val))
(defmethod read :login/login [env key param]
(log/debug "reading" "key=" key "param=" param)
(let [val {:value (select-keys @state/app-state [:user-phone-number :user-identity :loading])}
_ (log/debug "returning" val)]
val))
(defmethod read :signup/confirm [env key param]
(log/debug "reading" "key=" key "param=" param)
(let [val {:value (select-keys @state/app-state [:confirmation-code :loading])}
_ (log/debug "returning" val)]
val))
(defmulti mutate om/dispatch)
(defmethod mutate 'chat/add-msg-to-chat [{:keys [state] :as env} key {:keys [chat-id msg] :as param}]
(log/debug "writing" "key=" key "param=" param)
{:action #(do
(log/debug "Writing msg to db")
(msgs/save-message chat-id msg)
(swap! state/app-state assoc-in [:chat :messages] msg))})
(defonce reconciler
(om/reconciler
{:state state/app-state
:parser (om/parser {:read read
:mutate mutate})
:root-render sup/root-render
:root-unmount sup/root-unmount}))
(defn set-root-query [component]
(let [app-root (om/class->any reconciler (om/app-root reconciler))]
(om/set-query! app-root {:query [{(in/get-name component) (om/get-query component)}]})
(om.next.protocols/reindex! reconciler)))

View File

@ -1,94 +0,0 @@
(ns messenger.persistence.realm
(:require [cljs.reader :refer [read-string]]
[syng-im.utils.logging :as log]
[messenger.utils.types :refer [to-string]])
(:refer-clojure :exclude [exists?]))
(set! js/Realm (js/require "realm"))
(def opts {:schema [{:name "Contact"
:properties {:phone-number "string"
:whisper-identity "string"
:name "string"
:photo-path "string"}}
{:name :kv-store
:primaryKey :key
:properties {:key "string"
:value "string"}}
{:name :msgs
:primaryKey :msg-id
:properties {:msg-id "string"
:from "string"
:to "string"
:content "string" ;; TODO make it ArrayBuffer
:content-type "string"
:timestamp "int"
:chat-id "string"
:outgoing "bool"}}]})
(def realm (js/Realm. (clj->js opts)))
(def schema-by-name (->> (:schema opts)
(mapv (fn [{:keys [name] :as schema}]
[name schema]))
(into {})))
(defn field-type [schema-name field]
(get-in schema-by-name [schema-name :properties field]))
(defn write [f]
(.write realm f))
(defn create
([schema-name obj]
(create schema-name obj false))
([schema-name obj update?]
(.create realm (to-string schema-name) (clj->js obj) update?)))
(defmulti to-query (fn [schema-name operator field value]
operator))
(defmethod to-query :eq [schema-name operator field value]
(let [value (to-string value)
query (str (name field) "=" (if (= "string" (field-type schema-name field))
(str "\"" value "\"")
value))
;_ (log/debug query)
]
query))
(defn get-by-field [schema-name field value]
(-> (.objects realm (name schema-name))
(.filtered (to-query schema-name :eq field value))))
(defn sorted [results field-name order]
(.sorted results (to-string field-name) (if (= order :asc)
false
true)))
(defn page [results from to]
(js/Array.prototype.slice.call results from to))
(defn single [result]
(-> (aget result 0)))
(defn single-cljs [result]
(some-> (aget result 0)
(js->clj :keywordize-keys true)))
(defn decode-value [{:keys [key value]}]
(read-string value))
(defn delete [obj]
(write (fn []
(.delete realm obj))))
(defn exists? [schema-name field value]
(> (.-length (get-by-field schema-name field value))
0))
(defn get-count [objs]
(.-length objs))
(defn get-list [schema-name]
(vals (js->clj (.objects realm schema-name) :keywordize-keys true)))

View File

@ -1,26 +0,0 @@
(ns messenger.persistence.simple-kv-store
(:require [syng-im.protocol.state.storage :as st]
[messenger.persistence.realm :as r]
[messenger.utils.types :refer [to-edn-string]]))
(defrecord SimpleKvStore []
st/Storage
(put [_ key value]
(r/write
(fn []
(r/create :kv-store {:key key
:value (to-edn-string value)} true))))
(get [_ key]
(some-> (r/get-by-field :kv-store :key key)
(r/single-cljs)
(r/decode-value)))
(contains-key? [_ key]
(r/exists? :kv-store :key key))
(delete [_ key]
(-> (r/get-by-field :kv-store :key key)
(r/single)
(r/delete))))
(comment
)

View File

@ -1,46 +0,0 @@
(ns messenger.protocol.protocol-handler
(:require [syng-im.utils.logging :as log]
[messenger.constants :refer [ethereum-rpc-url]]
[messenger.comm.intercom :refer [protocol-initialized
save-new-msg]]
[messenger.models.protocol :refer [current-identity]]
[messenger.state :refer [kv-store]]))
(defn make-handler []
{:ethereum-rpc-url ethereum-rpc-url
:identity (current-identity)
:storage (kv-store)
:handler (fn [{:keys [event-type] :as event}]
(log/info "Event:" (clj->js event))
(case event-type
:initialized (let [{:keys [identity]} event]
(protocol-initialized identity))
:new-msg (let [{:keys [from to payload]} event]
(save-new-msg (assoc payload :from from :to to)))
;:msg-acked (let [{:keys [msg-id]} event]
; (add-to-chat "chat" ":" (str "Message " msg-id " was acked")))
;:delivery-failed (let [{:keys [msg-id]} event]
; (add-to-chat "chat" ":" (str "Delivery of message " msg-id " failed")))
;:new-group-chat (let [{:keys [from group-id identities]} event]
; (set-group-id! group-id)
; (set-group-identities identities)
; (add-to-chat "group-chat" ":" (str "Received group chat invitation from " from " for group-id: " group-id)))
;:group-chat-invite-acked (let [{:keys [from group-id]} event]
; (add-to-chat "group-chat" ":" (str "Received ACK for group chat invitation from " from " for group-id: " group-id)))
;:new-group-msg (let [{from :from
; {content :content} :payload} event]
; (add-to-chat "group-chat" from content))
;:group-new-participant (let [{:keys [group-id identity from]} event]
; (add-to-chat "group-chat" ":" (str (shorten from) " added " (shorten identity) " to group chat"))
; (add-identity-to-group-list identity))
;:group-removed-participant (let [{:keys [group-id identity from]} event]
; (add-to-chat "group-chat" ":" (str (shorten from) " removed " (shorten identity) " from group chat"))
; (remove-identity-from-group-list identity))
;:removed-from-group (let [{:keys [group-id from]} event]
; (add-to-chat "group-chat" ":" (str (shorten from) " removed you from group chat")))
;:participant-left-group (let [{:keys [group-id from]} event]
; (add-to-chat "group-chat" ":" (str (shorten from) " left group chat")))
;(add-to-chat "chat" ":" (str "Don't know how to handle " event-type))
(log/info "Don't know how to handle" event-type)
))})

View File

@ -1,84 +0,0 @@
(ns messenger.services.contacts
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [clojure.string :as cstr]
[cljs.core.async :as async :refer [chan put! <!]]
[messenger.utils.utils :refer [log on-error http-post toast]]
[messenger.utils.crypt :refer [encrypt]]
[messenger.utils.phone-number :refer [format-phone-number]]
[messenger.comm.intercom :as intercom :refer [save-user-phone-number]]
[messenger.models.contacts :as contacts-model]
[syng-im.utils.logging :as log]))
(defn- get-contact-name [phone-contact]
(cstr/join " "
(filter #(not (cstr/blank? %))
[(:givenName phone-contact)
(:middleName phone-contact)
(:familyName phone-contact)])))
(defn- to-syng-contacts [contacts-by-hash data]
(map (fn [server-contact]
(let [number-info (get contacts-by-hash
(:phone-number-hash server-contact))
phone-contact (:contact number-info)]
{:phone-number (:number number-info)
:whisper-identity (:whisper-identity server-contact)
:name (get-contact-name phone-contact)
:photo-path (:photo-path phone-contact)}))
(js->clj (:contacts data))))
(defn- get-contacts-by-hash [contacts]
(let [numbers-info (reduce (fn [numbers contact]
(into numbers
(map (fn [c]
{:number (format-phone-number (:number c))
:contact contact})
(:phone-numbers contact))))
'()
contacts)]
(reduce (fn [m number-info]
(let [number (:number number-info)
hash (encrypt number)]
(assoc m hash number-info)))
{}
numbers-info)))
(defn- request-syng-contacts [contacts]
(let [contacts-by-hash (get-contacts-by-hash contacts)
data (keys contacts-by-hash)
ch (chan)]
(http-post "get-contacts" {:phone-number-hashes data}
(fn [data]
(put! ch
(to-syng-contacts contacts-by-hash data))))
ch))
(defn sync-contacts [handler]
(go
(let [result (<! (contacts-model/load-phone-contacts))]
(if-let [error (:error result)]
(on-error error)
(let [syng-contacts (<! (request-syng-contacts (:contacts result)))]
(contacts-model/save-syng-contacts syng-contacts)
(handler))))))
(defn- load-syng-contacts []
(contacts-model/load-syng-contacts))
(defmulti contacts (fn [state id args]
id))
(defmethod contacts :contacts/load-syng-contacts
[state id args]
(log/info "handling " id " args = " args)
(load-syng-contacts))
(defmethod contacts :contacts/sync-contacts
[state id args]
(log/info "handling " id " args = " args)
(sync-contacts args))
(defn contacts-handler [state [id args]]
(log/info "contacts-handler: " args)
(contacts state id args))

View File

@ -1,52 +0,0 @@
(ns messenger.services.navigate-to
(:require [syng-im.utils.logging :as log]
[messenger.state :as state]
[messenger.components.chat.chat :as chat]
[messenger.android.sign-up-confirm :as sc]
[messenger.components.contact-list.contact-list :as cl]
[messenger.models.chat :refer [set-current-chat-id]]
[om.next :as om]
[messenger.omnext :as omnext]
[messenger.components.iname :as in]
[messenger.models.navigation :as n]))
(defn nav-push [nav route]
(binding [state/*nav-render* false]
(.push nav (clj->js route))))
(defn nav-replace [nav route]
(binding [state/*nav-render* false]
(.replace nav (clj->js route))))
(defmulti navigate-to (fn [state id args]
id))
(defmethod navigate-to :scene/chat
[state id {:keys [navigator chat-id] :as args}]
(log/debug "handling " id "args = " (dissoc args :navigator))
(n/set-current-screen-class chat/Chat)
(set-current-chat-id chat-id)
(nav-push navigator {:component chat/chat}))
(defmethod navigate-to :scene/signup-confirm
[state id {:keys [navigator] :as args}]
(log/debug "handling " id "args = " (dissoc args :navigator))
(n/set-current-screen-class sc/SignUpConfirm)
(nav-replace navigator {:component sc/sign-up-confirm
:name "sign-up-confirm"}))
(defmethod navigate-to :scene/contacts
[state id {:keys [navigator] :as args}]
(log/debug "handling " id "args = " (dissoc args :navigator))
(n/set-current-screen-class cl/ContactList)
(nav-replace navigator {:component cl/contact-list
:name "contact-list"}))
(defn navigate-to-handler [state [id args]]
(log/debug "navigate-to-handler: " (dissoc args :navigator))
(navigate-to state id args))
(comment
)

View File

@ -1,58 +0,0 @@
(ns messenger.services.protocol
(:require [messenger.models.protocol :refer [set-initialized
update-identity]]
[messenger.models.messages :refer [save-message]]
[messenger.models.user-data :refer [set-identity]]
[syng-im.utils.logging :as log]
[syng-im.protocol.api :as api]
[messenger.omnext :as omnext]
[om.next :as om]
[messenger.constants :refer [text-content-type]]))
(defmulti protocol (fn [state id args]
id))
(defmethod protocol :protocol/initialized
[state id {:keys [identity] :as args}]
(log/debug "handling " id "args = " args)
(update-identity identity)
(set-identity identity)
(set-initialized true))
(defmethod protocol :protocol/save-new-msg
[state id {{from :from :as msg} :msg :as args}]
(log/debug "handling " id "args = " args)
(let [chat-id from]
(om/transact! omnext/reconciler `[(chat/add-msg-to-chat {:msg ~msg
:chat-id ~chat-id}) [:chat/messages :chat/chat-id :chat/chat]])))
(defmethod protocol :protocol/send-msg
[state id {:keys [chat-id text] :as args}]
(log/debug "handling " id "args = " args)
(let [{msg-id :msg-id
{from :from
to :to} :msg} (api/send-user-msg {:to chat-id
:content text})
msg {:msg-id msg-id
:from from
:to to
:content text
:content-type text-content-type
:outgoing true}]
(om/transact! omnext/reconciler ;;(om/class->any omnext/reconciler messenger.components.chat.chat/Chat)
`[(chat/add-msg-to-chat {:msg ~msg
:chat-id ~chat-id}) [:chat/messages :chat/chat-id :chat/chat]])))
(defn protocol-handler [state [id args]]
(log/debug "protocol-handler: " args)
(protocol state id args))
(comment
(om/transact! omnext/reconciler `[(chat/add-msg-to-chat {:msg {:msg-id "1458670960090-ed5f995a-b686-5cbe-bf96-8a60ada8f6c3"}
:chat-id "1"}) [:chat/chat]])
(om/get-indexer omnext/reconciler)
(om.next.protocols/reindex! omnext/reconciler)
)

View File

@ -1,31 +0,0 @@
(ns messenger.services.server
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.core.async :as async :refer [chan put! <!]]
[messenger.utils.utils :refer [log on-error http-post]]
[messenger.comm.intercom :as intercom :refer [save-user-phone-number]]
[syng-im.utils.logging :as log]))
(defmulti server (fn [state id args]
id))
(defmethod server :server/sign-up
[state id {:keys [phone-number whisper-identity handler] :as args}]
(log/info "handling " id " args = " args)
(save-user-phone-number phone-number)
(http-post "sign-up" {:phone-number phone-number
:whisper-identity whisper-identity}
(fn [body]
(log body)
;; TODO replace with core.async
(handler))))
(defmethod server :server/sign-up-confirm
[state id {:keys [confirmation-code handler] :as args}]
(log/info "handling " id " args = " args)
(http-post "sign-up-confirm"
{:code confirmation-code}
handler))
(defn server-handler [state [id args]]
(log/info "contacts handler: " args)
(server state id args))

View File

@ -1,38 +0,0 @@
(ns messenger.services.user-data
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.core.async :as async :refer [<!]]
[messenger.models.user-data :refer [set-phone-number
save-phone-number
load-phone-number
set-identity
set-confirmation-code]]
[messenger.models.protocol :refer [current-identity]]
[messenger.utils.utils :refer [log on-error]]
[syng-im.utils.logging :as log]))
(defmulti user-data (fn [state id args]
id))
(defmethod user-data :user-data/set-phone-number
[state id phone-number]
(log/info "handling " id " args = " phone-number)
(set-phone-number phone-number))
(defmethod user-data :user-data/save-phone-number
[state id phone-number]
(log/info "handling " id " args = " phone-number)
(save-phone-number phone-number))
(defmethod user-data :user-data/load-phone-number
[state id args]
(log/debug "handling " id "args = " args)
(load-phone-number))
(defmethod user-data :user-data/set-confirmation-code
[state id confirmation-code]
(log/info "handling " id " args = " confirmation-code)
(set-confirmation-code confirmation-code))
(defn user-data-handler [state [id args]]
(log/debug "user-data-handler: " args)
(user-data state id args))

View File

@ -1,64 +0,0 @@
(ns messenger.state
(:require [cljs.core.async :as async :refer [chan pub sub]]
[re-natal.support :as sup]
[syng-im.utils.logging :as log]))
(def ^{:dynamic true :private true} *nav-render*
"Flag to suppress navigator re-renders from outside om when pushing/popping."
true)
(set! js/React (js/require "react-native"))
(defonce app-state (atom {:component nil
:loading false
:user-phone-number nil
:user-identity nil
:confirmation-code nil
:chat {:chat-id nil}
:identity-password "replace-me-with-user-entered-password"
:channels {:pub-sub-publisher (chan)
:pub-sub-publication nil}}))
(defn state [] @app-state)
(def pub-sub-bus-path [:channels :pub-sub-publisher])
(def pub-sub-path [:channels :pub-sub-publication])
(def user-notification-path [:user-notification])
(def protocol-initialized-path [:protocol-initialized])
(def simple-store-path [:simple-store])
(def identity-password-path [:identity-password])
(def current-chat-id-path [:chat :current-chat-id])
(defn pub-sub-publisher [app] (get-in app pub-sub-bus-path))
(defn kv-store []
(get-in @app-state simple-store-path))
(comment
(use 'figwheel-sidecar.repl-api)
(cljs-repl)
(defn read
[{:keys [state] :as env} key params]
(let [st @state]
(if-let [[_ v] (find st key)]
{:value v}
{:value :not-found})))
(def my-parser (om/parser {:read read}))
(def my-state (atom {:count 0 :title "what"}))
(my-parser {:state my-state} [:count :title])
(defn mutate
[{:keys [state] :as env} key params]
(if (= 'increment key)
{:value {:keys [:count]}
:action #(swap! state update-in [:count] inc)}
{:value :not-found}))
(def my-parser (om/parser {:read read :mutate mutate}))
(my-parser {:state my-state} '[(increment)])
@my-state
)

View File

@ -1,17 +0,0 @@
(ns messenger.utils.crypt
(:require [goog.crypt :refer [byteArrayToHex]])
(:import goog.crypt.Sha256))
(def sha-256 (Sha256.))
(defn bytes-to-str [arr]
(apply str (map char arr)))
(defn str-to-bytes [s]
(map (comp int) s))
(defn encrypt [s]
(.reset sha-256)
(.update sha-256 s)
(-> (.digest sha-256)
byteArrayToHex))

View File

@ -1,9 +0,0 @@
(ns messenger.utils.event
(:require [cljs.core.async :refer [<!]])
(:require-macros [cljs.core.async.macros :refer [go]]))
(defn handle-channel-events [chan handler]
(go (loop [[msg args] (<! chan)]
(when msg
(handler msg args)
(recur (<! chan))))))

View File

@ -1,9 +0,0 @@
(ns messenger.utils.phone-number)
(def i18n (js/require "react-native-i18n"))
(def locale (.-locale i18n))
(def country-code (subs locale 3 5))
(set! js/PhoneNumber (js/require "awesome-phonenumber"))
(defn format-phone-number [number]
(str (.getNumber (js/PhoneNumber. number country-code "international"))))

View File

@ -1,12 +0,0 @@
(ns messenger.utils.resources)
(def logo-icon (js/require "./images/logo.png"))
(def nav-back-icon (js/require "./images/nav-back.png"))
(def user-no-photo (js/require "./images/no-photo.png"))
(def online-icon (js/require "./images/online.png"))
(def seen-icon (js/require "./images/seen.png"))
(def delivered-icon (js/require "./images/delivered.png"))
(def play (js/require "./images/play.png"))
(def mic (js/require "./images/mic.png"))
(def smile (js/require "./images/smile.png"))
(def att (js/require "./images/att.png"))

View File

@ -1,7 +0,0 @@
(ns messenger.utils.state
(:require [om.next :as om]))
(defn from-state [component key]
(-> (om/get-state component)
(js->clj :keywordize-keys true)
key))

View File

@ -1,9 +0,0 @@
(ns messenger.utils.types)
(defn to-string [s]
(if (keyword? s)
(name s)
s))
(defn to-edn-string [value]
(with-out-str (pr value)))

View File

@ -1,38 +0,0 @@
(ns messenger.utils.utils
(:require-macros
[natal-shell.async-storage :refer [get-item set-item]]
[natal-shell.alert :refer [alert]]
[natal-shell.toast-android :as toast]))
(def server-address "http://rpc0.syng.im:20000/")
;; (def server-address "http://10.0.3.2:3000/")
(defn log [obj]
(.log js/console obj))
(defn toast [s]
(toast/show s (toast/long)))
(defn on-error [error]
(toast (str "error: " error)))
(defn http-post
([action data on-success]
(http-post action data on-success nil))
([action data on-success on-error]
(-> (.fetch js/window
(str server-address action)
(clj->js {:method "POST"
:headers {:accept "application/json"
:content-type "application/json"}
:body (.stringify js/JSON (clj->js data))}))
(.then (fn [response]
(log response)
(.text response)))
(.then (fn [text]
(let [json (.parse js/JSON text)
obj (js->clj json :keywordize-keys true)]
(on-success obj))))
(.catch (or on-error
(fn [error]
(toast (str error))))))))

View File

@ -1,35 +0,0 @@
(ns re-natal.support
(:require [om.next :refer-macros [ui]]))
(defonce root-nodes (atom {}))
(defn root-node!
"A substitute for a real root node (1) for mounting om-next component.
You have to call function :on-render and :on-unmount in reconciler :root-render :root-unmount function."
[id]
(let [content (atom nil)
instance (atom nil)
class (ui Object
(componentWillMount [this] (reset! instance this))
(render [_] @content))]
(swap! root-nodes assoc id {:on-render (fn [el]
(reset! content el)
(when @instance
(.forceUpdate @instance)))
:on-unmount (fn [])
:class class})
class))
(defn root-render
"Use this as reconciler :root-render function."
[el id]
(let [node (get @root-nodes id)
on-render (:on-render node)]
(when on-render (on-render el))))
(defn root-unmount
"Use this as reconciler :root-unmount function."
[id]
(let [node (get @root-nodes id)
unmount-fn (:on-unmount node)]
(when unmount-fn (unmount-fn))))

Some files were not shown because too many files have changed in this diff Show More