moved re-frame app to root folder
|
@ -25,7 +25,7 @@ project.xcworkspace
|
|||
# Android/IJ
|
||||
#
|
||||
.idea
|
||||
.gradle/
|
||||
.gradle
|
||||
local.properties
|
||||
|
||||
# node.js
|
||||
|
@ -41,9 +41,4 @@ target/
|
|||
|
||||
# Figwheel
|
||||
#
|
||||
figwheel_server.log
|
||||
.nrepl-port
|
||||
|
||||
# Mercurial
|
||||
.hg/
|
||||
.hgignore
|
||||
figwheel_server.log
|
16
.re-natal
|
@ -1,17 +1,21 @@
|
|||
{
|
||||
"name": "Messenger",
|
||||
"interface": "om-next",
|
||||
"androidHost": "localhost",
|
||||
"name": "SyngIm",
|
||||
"interface": "reagent",
|
||||
"androidHost": "10.0.3.2",
|
||||
"modules": [
|
||||
"react-native-contacts",
|
||||
"react-native-invertible-scroll-view",
|
||||
"awesome-phonenumber",
|
||||
"realm",
|
||||
"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": [
|
||||
"images"
|
||||
],
|
||||
"iosHost": "localhost"
|
||||
]
|
||||
}
|
|
@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. This change
|
|||
### Changed
|
||||
- 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
|
||||
- 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 widget maker to keep working when daylight savings switches over.
|
||||
|
||||
## 0.1.0 - 2016-02-21
|
||||
## 0.1.0 - 2016-03-23
|
||||
### Added
|
||||
- Files from the new template.
|
||||
- Widget maker public API - `make-widget-sync`.
|
||||
|
||||
[unreleased]: https://github.com/your-name/messenger/compare/0.1.1...HEAD
|
||||
[0.1.1]: https://github.com/your-name/messenger/compare/0.1.0...0.1.1
|
||||
[unreleased]: https://github.com/your-name/syng-im/compare/0.1.1...HEAD
|
||||
[0.1.1]: https://github.com/your-name/syng-im/compare/0.1.0...0.1.1
|
||||
|
|
23
README.md
|
@ -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
|
||||
|
||||
|
||||
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
|
||||
Distributed under the Eclipse Public License either version 1.0 or (at
|
||||
your option) any later version.
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -26,9 +26,7 @@ import com.android.build.OutputFile
|
|||
*
|
||||
* // 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
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'bundleIn${productFlavor}${buildType}'
|
||||
* // 'bundleIn${buildType}'
|
||||
* // The configuration property is in the format 'bundleIn${productFlavor}${buildType}'
|
||||
* // bundleInFreeDebug: true,
|
||||
* // bundleInPaidRelease: true,
|
||||
* // bundleInBeta: true,
|
||||
|
@ -62,7 +60,8 @@ import com.android.build.OutputFile
|
|||
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 x86 devices
|
||||
* The advantage is the size of the APK is reduced by about 4MB.
|
||||
|
@ -81,7 +80,7 @@ android {
|
|||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.messenger"
|
||||
applicationId "com.syngim"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
|
@ -92,9 +91,9 @@ android {
|
|||
}
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
universalApk false
|
||||
reset()
|
||||
include "armeabi-v7a", "x86"
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +119,9 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':randombytes')
|
||||
compile project(':realm')
|
||||
compile project(':react-native-vector-icons')
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
compile "com.android.support:appcompat-v7:23.0.1"
|
||||
compile "com.facebook.react:react-native:+" // From node_modules
|
||||
|
@ -128,6 +130,5 @@ dependencies {
|
|||
// compile(name:'geth', 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"])
|
||||
}
|
||||
|
|
|
@ -30,20 +30,21 @@ gradle.projectsEvaluated {
|
|||
|
||||
productFlavors.each { productFlavorName ->
|
||||
buildTypes.each { buildTypeName ->
|
||||
// Create variant and target names
|
||||
def targetName = "${productFlavorName.capitalize()}${buildTypeName.capitalize()}"
|
||||
def targetPath = productFlavorName ?
|
||||
"${productFlavorName}/${buildTypeName}" :
|
||||
"${buildTypeName}"
|
||||
// Create variant and source names
|
||||
def sourceName = "${buildTypeName}"
|
||||
def targetName = "${sourceName.capitalize()}"
|
||||
if (productFlavorName) {
|
||||
sourceName = "${productFlavorName}${targetName}"
|
||||
}
|
||||
|
||||
// React js bundle directories
|
||||
def jsBundleDirConfigName = "jsBundleDir${targetName}"
|
||||
def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
|
||||
file("$buildDir/intermediates/assets/${targetPath}")
|
||||
file("$buildDir/intermediates/assets/${sourceName}")
|
||||
|
||||
def resourcesDirConfigName = "jsBundleDir${targetName}"
|
||||
def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
|
||||
file("$buildDir/intermediates/res/merged/${targetPath}")
|
||||
file("$buildDir/intermediates/res/merged/${sourceName}")
|
||||
def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
|
||||
|
||||
// Bundle task name for variant
|
||||
|
@ -79,9 +80,7 @@ gradle.projectsEvaluated {
|
|||
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
|
||||
}
|
||||
|
||||
enabled config."bundleIn${targetName}" ||
|
||||
config."bundleIn${buildTypeName.capitalize()}" ?:
|
||||
targetName.toLowerCase().contains("release")
|
||||
enabled config."bundleIn${targetName}" ?: targetName.toLowerCase().contains("release")
|
||||
}
|
||||
|
||||
// Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<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.READ_CONTACTS" />
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">Messenger</string>
|
||||
<string name="app_name">SyngIm</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
rootProject.name = 'Messenger'
|
||||
rootProject.name = 'SyngIm'
|
||||
|
||||
include ':app'
|
||||
|
||||
|
@ -8,5 +8,9 @@ project(':react-native-contacts').projectDir = new File(settingsDir, '../node_mo
|
|||
include ':react-native-i18n'
|
||||
project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android')
|
||||
// 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'
|
||||
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')
|
|
@ -1,3 +1,3 @@
|
|||
# Introduction to messenger
|
||||
# Introduction to syng-im
|
||||
|
||||
TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
(ns ^:figwheel-no-load env.android.main
|
||||
(:require [om.next :as om]
|
||||
[messenger.android.core :as core]
|
||||
[messenger.omnext :as omnext]
|
||||
[figwheel.client :as figwheel :include-macros true]))
|
||||
(ns ^:figwheel-no-load env.android.main
|
||||
(:require [reagent.core :as r]
|
||||
[syng-im.android.core :refer [app-root]]
|
||||
[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
|
||||
:websocket-url "ws://localhost:3449/figwheel-ws"
|
||||
:heads-up-display true
|
||||
:jsload-callback #(om/add-root! omnext/reconciler core/AppRoot 1))
|
||||
:websocket-url "ws://10.0.3.2:3449/figwheel-ws"
|
||||
:heads-up-display true
|
||||
:jsload-callback #(swap! cnt inc))
|
||||
|
||||
(core/init)
|
||||
|
||||
(def root-el (core/app-root))
|
||||
(core/init)
|
|
@ -1,16 +1,17 @@
|
|||
(ns ^:figwheel-no-load env.ios.main
|
||||
(:require [om.next :as om]
|
||||
[messenger.ios.core :as core]
|
||||
[messenger.omnext :as omnext]
|
||||
(ns ^:figwheel-no-load env.ios.main
|
||||
(:require [reagent.core :as r]
|
||||
[syng-im.ios.core :as core]
|
||||
[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
|
||||
:websocket-url "ws://localhost:3449/figwheel-ws"
|
||||
:heads-up-display true
|
||||
:jsload-callback #(om/add-root! omnext/reconciler core/AppRoot 1))
|
||||
:websocket-url "ws://localhost:3449/figwheel-ws"
|
||||
:heads-up-display true
|
||||
:jsload-callback #(swap! cnt inc))
|
||||
|
||||
(core/init)
|
||||
|
||||
(def root-el (core/app-root))
|
||||
(core/init)
|
|
@ -1,4 +1,6 @@
|
|||
(ns env.android.main
|
||||
(:require [messenger.android.core :as core]))
|
||||
(ns env.android.main
|
||||
(:require [syng-im.android.core :as core]))
|
||||
|
||||
(core/init)
|
||||
|
||||
|
||||
(core/init)
|
|
@ -1,4 +1,6 @@
|
|||
(ns env.ios.main
|
||||
(:require [messenger.ios.core :as core]))
|
||||
(ns env.ios.main
|
||||
(:require [syng-im.ios.core :as core]))
|
||||
|
||||
(core/init)
|
||||
|
||||
|
||||
(core/init)
|
Before Width: | Height: | Size: 916 B After Width: | Height: | Size: 916 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 124 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
@ -5,7 +5,6 @@
|
|||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.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 */; };
|
||||
E343FE8F1C96F54A00C01DB5 /* libRCTContacts.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E343FE841C96F4DA00C01DB5 /* libRCTContacts.a */; };
|
||||
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 */
|
||||
|
||||
/* 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>"; };
|
||||
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>"; };
|
||||
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 */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -180,6 +208,11 @@
|
|||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.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;
|
||||
};
|
||||
|
@ -304,6 +337,9 @@
|
|||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
|
||||
F04672B9D3824B768FCF6F71 /* RNVectorIcons.xcodeproj */,
|
||||
06F26555B4054594966B6B08 /* RNRandomBytes.xcodeproj */,
|
||||
0D4A52AE301842E1B2533BD3 /* RealmReact.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
@ -324,6 +360,7 @@
|
|||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
00E356EF1AD99517003FC87E /* MessengerTests */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
A72CA0FB822D450E98649ACB /* Resources */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
|
@ -359,10 +396,28 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
E343FE901C971D4200C01DB5 /* Geth.framework */,
|
||||
8003209F13C24D35AABD3933 /* libc++.tbd */,
|
||||
313A77B1D7804DBDBE6FF6F5 /* libz.tbd */,
|
||||
);
|
||||
name = Frameworks;
|
||||
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 */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -408,7 +463,7 @@
|
|||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0720;
|
||||
LastUpgradeCheck = 720;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
00E356ED1AD99517003FC87E = {
|
||||
|
@ -594,6 +649,14 @@
|
|||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets 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;
|
||||
};
|
||||
|
@ -675,6 +738,11 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Messenger.app/Messenger";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -693,6 +761,11 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Messenger.app/Messenger";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
@ -709,6 +782,9 @@
|
|||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(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;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -730,6 +806,9 @@
|
|||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(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;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -778,6 +857,9 @@
|
|||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(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;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
|
@ -818,6 +900,9 @@
|
|||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(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;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "Messenger",
|
||||
"name": "SyngIm",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -8,10 +8,14 @@
|
|||
"dependencies": {
|
||||
"awesome-phonenumber": "^1.0.12",
|
||||
"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-i18n": "0.0.8",
|
||||
"react-native-invertible-scroll-view": "^0.2.0",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
66
project.clj
|
@ -1,13 +1,15 @@
|
|||
(defproject messenger "0.1.0-SNAPSHOT"
|
||||
(defproject syng-im "0.1.0-SNAPSHOT"
|
||||
:description "FIXME: write description"
|
||||
:url "http://example.com/FIXME"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:dependencies [[org.clojure/clojure "1.7.0"]
|
||||
[org.clojure/clojurescript "1.7.170"]
|
||||
[org.omcljs/om "1.0.0-alpha30" :exclusions [cljsjs/react cljsjs/react-dom]]
|
||||
[natal-shell "0.1.6"]
|
||||
[syng-im/protocol "0.1.1"]]
|
||||
[reagent "0.5.1" :exclusions [cljsjs/react]]
|
||||
[re-frame "0.6.0"]
|
||||
[prismatic/schema "1.0.4"]
|
||||
[syng-im/protocol "0.1.1"]
|
||||
[natal-shell "0.1.6"]]
|
||||
:plugins [[lein-cljsbuild "1.1.1"]
|
||||
[lein-figwheel "0.5.0-2"]]
|
||||
:clean-targets ["target/" "index.ios.js" "index.android.js"]
|
||||
|
@ -16,32 +18,30 @@
|
|||
["with-profile" "prod" "cljsbuild" "once" "ios"]
|
||||
["with-profile" "prod" "cljsbuild" "once" "android"]]}
|
||||
:figwheel {:nrepl-port 7888}
|
||||
:profiles
|
||||
{:dev {:dependencies [[figwheel-sidecar "0.5.0-2"]
|
||||
[com.cemerick/piggieback "0.2.1"]]
|
||||
:source-paths ["src" "env/dev"]
|
||||
:cljsbuild {:builds
|
||||
{:ios {:source-paths ["src" "env/dev"]
|
||||
:figwheel true
|
||||
:compiler {:output-to "target/ios/not-used.js"
|
||||
:main "env.ios.main"
|
||||
:output-dir "target/ios"
|
||||
:optimizations :none}}
|
||||
:android {:source-paths ["src" "env/dev"]
|
||||
:figwheel true
|
||||
:compiler {:output-to "target/android/not-used.js"
|
||||
:main "env.android.main"
|
||||
:output-dir "target/android"
|
||||
:optimizations :none}}}}
|
||||
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
|
||||
:prod {:cljsbuild {:builds
|
||||
{:ios {:source-paths ["src" "env/prod"]
|
||||
:compiler {:output-to "index.ios.js"
|
||||
:main "env.ios.main"
|
||||
:output-dir "target/ios"
|
||||
:optimizations :simple}}
|
||||
:android {:source-paths ["src" "env/prod"]
|
||||
:compiler {:output-to "index.android.js"
|
||||
:main "env.android.main"
|
||||
:output-dir "target/android"
|
||||
:optimizations :simple}}}}}})
|
||||
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.0-2"]
|
||||
[com.cemerick/piggieback "0.2.1"]]
|
||||
:source-paths ["src" "env/dev"]
|
||||
:cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"]
|
||||
:figwheel true
|
||||
:compiler {:output-to "target/ios/not-used.js"
|
||||
:main "env.ios.main"
|
||||
:output-dir "target/ios"
|
||||
:optimizations :none}}
|
||||
:android {:source-paths ["src" "env/dev"]
|
||||
:figwheel true
|
||||
:compiler {:output-to "target/android/not-used.js"
|
||||
:main "env.android.main"
|
||||
:output-dir "target/android"
|
||||
:optimizations :none}}}}
|
||||
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
|
||||
:prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"]
|
||||
:compiler {:output-to "index.ios.js"
|
||||
:main "env.ios.main"
|
||||
:output-dir "target/ios"
|
||||
:optimizations :simple}}
|
||||
:android {:source-paths ["src" "env/prod"]
|
||||
:compiler {:output-to "index.android.js"
|
||||
:main "env.android.main"
|
||||
:output-dir "target/android"
|
||||
:optimizations :simple}}}}
|
||||
}})
|
|
@ -1 +0,0 @@
|
|||
(ns cljsjs.react.dom)
|
|
@ -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)))
|
|
@ -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))
|
|
@ -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))
|
|
@ -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}]))
|
|
@ -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)))
|
|
@ -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))
|
|
@ -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))
|
||||
|
|
@ -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}))
|
|
@ -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))
|
|
@ -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}))
|
||||
|
|
@ -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))
|
|
@ -1,4 +0,0 @@
|
|||
(ns messenger.components.iname)
|
||||
|
||||
(defprotocol IName
|
||||
(get-name [this]))
|
|
@ -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))))
|
|
@ -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)))
|
|
@ -1,5 +0,0 @@
|
|||
(ns messenger.constants)
|
||||
|
||||
(def ethereum-rpc-url "http://localhost:8545")
|
||||
|
||||
(def text-content-type "text/plain")
|
|
@ -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)))
|
|
@ -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)))
|
|
@ -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))
|
|
@ -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))
|
|
@ -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))
|
||||
|
||||
)
|
|
@ -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]))
|
|
@ -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)))))
|
|
@ -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))
|
|
@ -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)))
|
|
@ -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)))
|
|
@ -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
|
||||
|
||||
)
|
|
@ -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)
|
||||
))})
|
|
@ -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))
|
|
@ -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
|
||||
|
||||
)
|
|
@ -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)
|
||||
)
|
|
@ -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))
|
|
@ -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))
|
|
@ -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
|
||||
|
||||
)
|
|
@ -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))
|
|
@ -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))))))
|
|
@ -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"))))
|
|
@ -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"))
|
|
@ -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))
|
|
@ -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)))
|
|
@ -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))))))))
|
|
@ -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))))
|
||||
|