From c10abb17bb012157dae8e472227b7df5d5e0e28e Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Thu, 26 May 2016 15:31:11 +0300 Subject: [PATCH 01/19] first attempt Former-commit-id: dc2839e0861cd17ae5b40d28f08c27dc6f658c8c --- .gitignore | 4 +++ project.clj | 9 +++--- test/status_im/appium.clj | 53 ++++++++++++++++++++++++++++++++++++ test/status_im/console.clj | 44 ++++++++++++++++++++++++++++++ test/status_im/core_test.clj | 7 ----- 5 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 test/status_im/appium.clj create mode 100644 test/status_im/console.clj delete mode 100644 test/status_im/core_test.clj diff --git a/.gitignore b/.gitignore index 14773fe52f..ea7f8f836b 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,7 @@ target/ # figwheel_server.log .nrepl-port + +# Lein +# +.lein-failures diff --git a/project.clj b/project.clj index 647d7ad498..d68172cc05 100644 --- a/project.clj +++ b/project.clj @@ -8,7 +8,7 @@ [reagent "0.5.1" :exclusions [cljsjs/react]] [re-frame "0.6.0"] [prismatic/schema "1.0.4"] - ^{:voom {:repo "https://github.com/status-im/status-lib.git" + ^{:voom {:repo "git@github.com:status-im/status-lib.git" :branch "master"}} [status-im/protocol "0.1.1-20160525_083359-g53ab2c2"] [natal-shell "0.1.6"] @@ -22,7 +22,9 @@ ["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"]] + [com.cemerick/piggieback "0.2.1"] + [io.appium/java-client "3.4.1"] + ] :source-paths ["src" "env/dev"] :cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"] :figwheel true @@ -46,5 +48,4 @@ :compiler {:output-to "index.android.js" :main "env.android.main" :output-dir "target/android" - :optimizations :simple}}}} - }}) + :optimizations :simple}}}}}}) diff --git a/test/status_im/appium.clj b/test/status_im/appium.clj new file mode 100644 index 0000000000..a879a68ba2 --- /dev/null +++ b/test/status_im/appium.clj @@ -0,0 +1,53 @@ +(ns status-im.appium + (:require [clojure.java.io :as io] + [clojure.test :refer :all]) + (:import (org.openqa.selenium.remote DesiredCapabilities) + (org.openqa.selenium By) + (io.appium.java_client.android AndroidDriver) + (java.net URL) + (java.util.concurrent TimeUnit))) + + +(defn init [] + (let [dir (io/file (str (System/getProperty "user.dir") + "/android/app/build/outputs/apk")) + app (io/file dir "app-debug.apk") + capabilities (doto (DesiredCapabilities.) + (.setCapability "deviceName" "device") + (.setCapability "platformVersion" "6.0.0") + (.setCapability "app" (.getAbsolutePath app)) + (.setCapability "appPackage" "com.statusim") + (.setCapability "appActivity" ".MainActivity")) + driver (AndroidDriver. (URL. "http://127.0.0.1:4723/wd/hub") capabilities)] + (-> driver + .manage + .timeouts + (.implicitlyWait 100 TimeUnit/MILLISECONDS)) + (Thread/sleep 9000) + driver)) + +(defn by-xpath [driver xpath] + (.findElement driver (By/xpath xpath))) + +(defn elements-by-xpath [driver xpath] + (.findElements driver (By/xpath xpath))) + +(defn click [driver xpath] + (.click (by-xpath driver xpath))) + +(defn write [driver input-xpath text] + (.sendKeys (by-xpath driver input-xpath) (into-array [text]))) + +(defn get-text [driver xpath] + (.getText (by-xpath driver xpath))) + +(defn xpath-by-text [text] + (str ".//*[@text='" text "']" )) + +(defn contains-text [driver text] + (is (= 1 (->> (xpath-by-text text) + (elements-by-xpath driver) + (.size))))) + +(defn quit [driver] + (.quit driver)) diff --git a/test/status_im/console.clj b/test/status_im/console.clj new file mode 100644 index 0000000000..a99251393d --- /dev/null +++ b/test/status_im/console.clj @@ -0,0 +1,44 @@ +(ns status-im.console + (:require [clojure.test :refer :all] + [status-im.appium :refer :all])) + +(def command-request-icon + (str + "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" + "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" + "/android.widget.ScrollView[1]/android.view.ViewGroup[1]" + "/android.view.ViewGroup[1]/android.view.ViewGroup[1]" + "/android.view.ViewGroup[2]/android.widget.ImageView[1]")) + +(def input + (str + "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" + "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" + "/android.view.ViewGroup[2]/android.view.ViewGroup[1]" + "/android.widget.EditText[1]")) + +(def send-button1 + (str "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" + "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" + "/android.view.ViewGroup[2]/android.view.ViewGroup[1]" + "/android.view.ViewGroup[2]/android.view.ViewGroup[1]")) + +(def send-button2 + (str "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" + "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" + "/android.view.ViewGroup[2]/android.view.ViewGroup[2]" + "/android.view.ViewGroup[2]/android.view.ViewGroup[1]")) + +(def message-text + (str "Your phone number is also required to use the app. Type" + " the exclamation mark or hit the icon to open the command " + "list and choose the !phone command")) + +(deftest console-test + (let [driver (init)] + (click driver command-request-icon) + (write driver input "123") + (click driver send-button1) + (click driver send-button2) + (contains-text driver message-text) + (quit driver))) diff --git a/test/status_im/core_test.clj b/test/status_im/core_test.clj deleted file mode 100644 index 1224033d1c..0000000000 --- a/test/status_im/core_test.clj +++ /dev/null @@ -1,7 +0,0 @@ -(ns status-im.core-test - (:require [clojure.test :refer :all] - [status-im.core :refer :all])) - -(deftest a-test - (testing "FIXME, I fail." - (is (= 0 1)))) From 6823acd171eeb4ff5b777a49bc30abbb8e805da8 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Thu, 26 May 2016 16:46:14 +0300 Subject: [PATCH 02/19] :accessibility-label Former-commit-id: 63dd0d4a4a63c1d71bcafe6b7e56ecc00fd3c9aa --- src/status_im/chat/views/command.cljs | 6 ++-- src/status_im/chat/views/message.cljs | 7 ++++- src/status_im/chat/views/plain_input.cljs | 19 ++++++------ test/status_im/appium.clj | 14 +++++++-- test/status_im/console.clj | 35 +++-------------------- 5 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/status_im/chat/views/command.cljs b/src/status_im/chat/views/command.cljs index ab90de0426..2b550dc7bf 100644 --- a/src/status_im/chat/views/command.cljs +++ b/src/status_im/chat/views/command.cljs @@ -38,11 +38,13 @@ :onChangeText set-input-message :onSubmitEditing (fn [] (when (valid? message validator) - (send-command)))} + (send-command))) + :accessibility-label :command-input} input-options) message] (if (valid? message validator) - [touchable-highlight {:on-press send-command} + [touchable-highlight {:on-press send-command + :accessibility-label :stage-command} [view st/send-container [icon :send st/send-icon]]] [touchable-highlight {:on-press cancel-command-input} [view st/cancel-container diff --git a/src/status_im/chat/views/message.cljs b/src/status_im/chat/views/message.cljs index d1b9750f5f..ceb430fc76 100644 --- a/src/status_im/chat/views/message.cljs +++ b/src/status_im/chat/views/message.cljs @@ -72,13 +72,18 @@ (defn set-chat-command [msg-id command] (dispatch [:set-response-chat-command msg-id (:command command)])) +(defn label [{:keys [command]}] + (->> (name command) + (str "request-"))) + (defn message-content-command-request [{:keys [msg-id content from incoming-group]}] (let [commands-atom (subscribe [:get-commands])] (fn [{:keys [msg-id content from incoming-group]}] (let [commands @commands-atom {:keys [command content]} (parse-command-request commands content)] - [touchable-highlight {:onPress #(set-chat-command msg-id command)} + [touchable-highlight {:onPress #(set-chat-command msg-id command) + :accessibility-label (label command)} [view st/comand-request-view [view st/command-request-message-view (when incoming-group diff --git a/src/status_im/chat/views/plain_input.cljs b/src/status_im/chat/views/plain_input.cljs index eaece17dfb..dcbc75780a 100644 --- a/src/status_im/chat/views/plain_input.cljs +++ b/src/status_im/chat/views/plain_input.cljs @@ -1,9 +1,9 @@ (ns status-im.chat.views.plain-input (:require [re-frame.core :refer [subscribe dispatch]] [status-im.components.react :refer [view - icon - touchable-highlight - text-input]] + icon + touchable-highlight + text-input]] [status-im.chat.views.suggestions :refer [suggestions-view]] [status-im.chat.styles.plain-input :as st])) @@ -39,15 +39,16 @@ (if @typing-command? [icon :close-gray st/close-icon] [icon :list st/list-icon])]] - [text-input {:style st/message-input - :autoFocus (pos? (count @staged-commands-atom)) - :onChangeText set-input-message - :onSubmitEditing #(try-send @chat @staged-commands-atom - input-message)} + [text-input {:style st/message-input + :autoFocus (pos? (count @staged-commands-atom)) + :onChangeText set-input-message + :onSubmitEditing #(try-send @chat @staged-commands-atom + input-message)} input-message] ;; TODO emoticons: not implemented [icon :smile st/smile-icon] (when (message-valid? @staged-commands-atom input-message) - [touchable-highlight {:on-press #(send @chat input-message)} + [touchable-highlight {:on-press #(send @chat input-message) + :accessibility-label :send-message} [view st/send-container [icon :send st/send-icon]]])]])))) diff --git a/test/status_im/appium.clj b/test/status_im/appium.clj index a879a68ba2..7a857711de 100644 --- a/test/status_im/appium.clj +++ b/test/status_im/appium.clj @@ -32,11 +32,19 @@ (defn elements-by-xpath [driver xpath] (.findElements driver (By/xpath xpath))) -(defn click [driver xpath] - (.click (by-xpath driver xpath))) +(defn by-id [driver id] + (.findElementByAccessibilityId driver (name id))) + +(defn get-element [driver id] + (if (keyword? id) + (by-id driver id) + (by-xpath driver id))) + +(defn click [driver id] + (.click (get-element driver id))) (defn write [driver input-xpath text] - (.sendKeys (by-xpath driver input-xpath) (into-array [text]))) + (.sendKeys (get-element driver input-xpath) (into-array [text]))) (defn get-text [driver xpath] (.getText (by-xpath driver xpath))) diff --git a/test/status_im/console.clj b/test/status_im/console.clj index a99251393d..4d748af7c2 100644 --- a/test/status_im/console.clj +++ b/test/status_im/console.clj @@ -2,33 +2,6 @@ (:require [clojure.test :refer :all] [status-im.appium :refer :all])) -(def command-request-icon - (str - "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" - "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" - "/android.widget.ScrollView[1]/android.view.ViewGroup[1]" - "/android.view.ViewGroup[1]/android.view.ViewGroup[1]" - "/android.view.ViewGroup[2]/android.widget.ImageView[1]")) - -(def input - (str - "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" - "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" - "/android.view.ViewGroup[2]/android.view.ViewGroup[1]" - "/android.widget.EditText[1]")) - -(def send-button1 - (str "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" - "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" - "/android.view.ViewGroup[2]/android.view.ViewGroup[1]" - "/android.view.ViewGroup[2]/android.view.ViewGroup[1]")) - -(def send-button2 - (str "//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]" - "/android.widget.FrameLayout[1]/android.view.ViewGroup[1]" - "/android.view.ViewGroup[2]/android.view.ViewGroup[2]" - "/android.view.ViewGroup[2]/android.view.ViewGroup[1]")) - (def message-text (str "Your phone number is also required to use the app. Type" " the exclamation mark or hit the icon to open the command " @@ -36,9 +9,9 @@ (deftest console-test (let [driver (init)] - (click driver command-request-icon) - (write driver input "123") - (click driver send-button1) - (click driver send-button2) + (click driver :request-keypair-password) + (write driver :command-input "123") + (click driver :stage-command) + (click driver :send-message) (contains-text driver message-text) (quit driver))) From 23b646c2131c681a2083bd8cc9633a81228a53b1 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Thu, 26 May 2016 17:00:42 +0300 Subject: [PATCH 03/19] appium-test macro Former-commit-id: 54ae25dc67ec9ca2d75e87f8b62637c4c8592c43 --- test/status_im/appium.clj | 10 +++++++++- test/status_im/console.clj | 14 ++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/test/status_im/appium.clj b/test/status_im/appium.clj index 7a857711de..d2ff6adb53 100644 --- a/test/status_im/appium.clj +++ b/test/status_im/appium.clj @@ -50,7 +50,7 @@ (.getText (by-xpath driver xpath))) (defn xpath-by-text [text] - (str ".//*[@text='" text "']" )) + (str ".//*[@text='" text "']")) (defn contains-text [driver text] (is (= 1 (->> (xpath-by-text text) @@ -59,3 +59,11 @@ (defn quit [driver] (.quit driver)) + +(defmacro appium-test [name & body] + (let [sym (gensym)] + `(deftest ~name + (let [~sym (init)] + ~@(for [[f & rest] body] + `(~f ~sym ~@rest)) + (quit ~sym))))) diff --git a/test/status_im/console.clj b/test/status_im/console.clj index 4d748af7c2..5cdf17ae45 100644 --- a/test/status_im/console.clj +++ b/test/status_im/console.clj @@ -7,11 +7,9 @@ " the exclamation mark or hit the icon to open the command " "list and choose the !phone command")) -(deftest console-test - (let [driver (init)] - (click driver :request-keypair-password) - (write driver :command-input "123") - (click driver :stage-command) - (click driver :send-message) - (contains-text driver message-text) - (quit driver))) +(appium-test console-test + (click :request-keypair-password) + (write :command-input "123") + (click :stage-command) + (click :send-message) + (contains-text message-text)) From e8256f34e918b353ebc69c82d89757c2b74d9dc8 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Thu, 26 May 2016 18:13:37 +0300 Subject: [PATCH 04/19] implicitly wait 25s Former-commit-id: 0e3c1d10ba0ef3205efb800ce5d98f71f4266274 --- test/status_im/appium.clj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/status_im/appium.clj b/test/status_im/appium.clj index d2ff6adb53..061ed3f4b4 100644 --- a/test/status_im/appium.clj +++ b/test/status_im/appium.clj @@ -22,8 +22,7 @@ (-> driver .manage .timeouts - (.implicitlyWait 100 TimeUnit/MILLISECONDS)) - (Thread/sleep 9000) + (.implicitlyWait 25 TimeUnit/SECONDS)) driver)) (defn by-xpath [driver xpath] From ee2087ce7784594bb7f0c6b2286d602f7fecc2ca Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Thu, 26 May 2016 18:05:10 +0200 Subject: [PATCH 05/19] run appium with second param Former-commit-id: a2e14e4ff09b49cce3d170341e8623cdcd4c46d9 --- .re-natal | 2 +- run-osx.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.re-natal b/.re-natal index 1455b14c43..b4f25ba62a 100644 --- a/.re-natal +++ b/.re-natal @@ -1,7 +1,7 @@ { "name": "StatusIm", "interface": "reagent", - "androidHost": "localhost", + "androidHost": "10.0.3.2", "modules": [ "react-native-contacts", "react-native-invertible-scroll-view", diff --git a/run-osx.sh b/run-osx.sh index 9f89a05857..d02de2a3e1 100755 --- a/run-osx.sh +++ b/run-osx.sh @@ -59,3 +59,9 @@ sleep 10s adb reverse tcp:8081 tcp:8081 && adb reverse tcp:3449 tcp:3449 react-native run-android + +if [ ! -z $2 ] +then + tab "appium" + lein test +fi \ No newline at end of file From ecf8ea0f337381a28fcaf40940f0593b925ca2a7 Mon Sep 17 00:00:00 2001 From: Adrian Tiberius Date: Thu, 26 May 2016 19:20:39 +0300 Subject: [PATCH 06/19] workaround for adding peer to geth Former-commit-id: 32b10794d20d6ac149bb484d1d65dacff4cc84d7 --- .../src/main/java/com/statusim/MainActivity.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/java/com/statusim/MainActivity.java b/android/app/src/main/java/com/statusim/MainActivity.java index 3d411d9213..f076461d8b 100644 --- a/android/app/src/main/java/com/statusim/MainActivity.java +++ b/android/app/src/main/java/com/statusim/MainActivity.java @@ -13,6 +13,9 @@ import com.bitgo.randombytes.RandomBytesPackage; import com.BV.LinearGradient.LinearGradientPackage; import com.centaurwarchief.smslistener.SmsListener; +import android.os.Handler; +import android.util.Log; + import java.util.Arrays; import java.util.List; import java.util.Properties; @@ -23,6 +26,8 @@ import io.realm.react.RealmReactPackage; public class MainActivity extends ReactActivity { + final Handler handler = new Handler(); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -43,11 +48,19 @@ public class MainActivity extends ReactActivity { getApplicationInfo().dataDir; // Launch! + final Runnable addPeer = new Runnable() { + public void run() { + Log.w("Geth", "adding peer"); + Geth.run("--exec admin.addPeer(\"enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:55555\") attach http://localhost:8545"); + } + }; 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,admin --fast --datadir=" + dataFolder); + Geth.run("--shh --ipcdisable --nodiscover --rpc --rpcapi db,eth,net,web3,shh,admin --fast --datadir=" + dataFolder); + } }).start(); + handler.postDelayed(addPeer, 5000); } /** From 17c1c7600328835f079d54012691a437a517cba6 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Fri, 27 May 2016 19:44:06 +0300 Subject: [PATCH 07/19] clean js/window first attempt Former-commit-id: 7694ad9e873d80824a07798de66b96b0f6a96dbb --- src/status_im/components/action_button.cljs | 6 +++--- src/status_im/components/icons/ionicons.cljs | 4 +--- .../components/invertible_scroll_view.cljs | 5 ++--- src/status_im/components/item_checkbox.cljs | 4 +--- src/status_im/components/realm.cljs | 9 -------- src/status_im/components/toolbar.cljs | 4 +--- src/status_im/i18n.cljs | 21 +++++-------------- src/status_im/utils/crypt.cljs | 10 ++++----- src/status_im/utils/listview.cljs | 3 +-- 9 files changed, 19 insertions(+), 47 deletions(-) delete mode 100644 src/status_im/components/realm.cljs diff --git a/src/status_im/components/action_button.cljs b/src/status_im/components/action_button.cljs index db303f5f6d..6ee896d1ed 100644 --- a/src/status_im/components/action_button.cljs +++ b/src/status_im/components/action_button.cljs @@ -1,7 +1,7 @@ (ns status-im.components.action-button (:require [reagent.core :as r])) -(set! js/window.ActionButton (js/require "react-native-action-button")) +(def class (js/require "react-native-action-button")) -(def action-button (r/adapt-react-class (.-default js/ActionButton))) -(def action-button-item (r/adapt-react-class (.. js/ActionButton -default -Item))) \ No newline at end of file +(def action-button (r/adapt-react-class (.-default class))) +(def action-button-item (r/adapt-react-class (.. class -default -Item))) diff --git a/src/status_im/components/icons/ionicons.cljs b/src/status_im/components/icons/ionicons.cljs index 885af057d5..5bc4a06ddc 100644 --- a/src/status_im/components/icons/ionicons.cljs +++ b/src/status_im/components/icons/ionicons.cljs @@ -1,6 +1,4 @@ (ns status-im.components.icons.ionicons (:require [reagent.core :as r])) -(set! js/window.Ionicons (js/require "react-native-vector-icons/Ionicons")) - -(def icon (r/adapt-react-class js/Ionicons)) +(def icon (r/adapt-react-class (js/require "react-native-vector-icons/Ionicons"))) diff --git a/src/status_im/components/invertible_scroll_view.cljs b/src/status_im/components/invertible_scroll_view.cljs index daf873a773..ba4a1d546a 100644 --- a/src/status_im/components/invertible_scroll_view.cljs +++ b/src/status_im/components/invertible_scroll_view.cljs @@ -1,8 +1,7 @@ (ns status-im.components.invertible-scroll-view) -(set! js/window.InvertibleScrollView (js/require "react-native-invertible-scroll-view")) +(def class (js/require "react-native-invertible-scroll-view")) (defn invertible-scroll-view [props] - (js/React.createElement js/InvertibleScrollView - (clj->js (merge {:inverted true} props)))) + (js/React.createElement class (clj->js (merge {:inverted true} props)))) diff --git a/src/status_im/components/item_checkbox.cljs b/src/status_im/components/item_checkbox.cljs index 97d43ecd37..45c667141d 100644 --- a/src/status_im/components/item_checkbox.cljs +++ b/src/status_im/components/item_checkbox.cljs @@ -1,7 +1,5 @@ (ns status-im.components.item-checkbox (:require [reagent.core :as r])) -(set! js/window.ItemCheckbox (js/require "react-native-circle-checkbox")) - -(def item-checkbox (r/adapt-react-class js/ItemCheckbox)) +(def item-checkbox (r/adapt-react-class (js/require "react-native-circle-checkbox"))) diff --git a/src/status_im/components/realm.cljs b/src/status_im/components/realm.cljs deleted file mode 100644 index eff8c1fee5..0000000000 --- a/src/status_im/components/realm.cljs +++ /dev/null @@ -1,9 +0,0 @@ -(ns status-im.components.realm - (:require [reagent.core :as r])) - -(set! js/window.RealmReactNative (js/require "realm/react-native")) - -(def list-view-class (r/adapt-react-class (.-ListView js/RealmReactNative))) - -(defn list-view [props] - [list-view-class (merge {:enableEmptySections true} props)]) diff --git a/src/status_im/components/toolbar.cljs b/src/status_im/components/toolbar.cljs index 3f21fc8a35..0591c1aba1 100644 --- a/src/status_im/components/toolbar.cljs +++ b/src/status_im/components/toolbar.cljs @@ -12,9 +12,7 @@ color-purple text1-color text2-color - toolbar-background1]] - [status-im.components.realm :refer [list-view]] - [reagent.core :as r])) + toolbar-background1]])) (defn toolbar [{:keys [title nav-action hide-nav? action custom-action background-color custom-content style]}] diff --git a/src/status_im/i18n.cljs b/src/status_im/i18n.cljs index 9abde5c46e..4a6157cc23 100644 --- a/src/status_im/i18n.cljs +++ b/src/status_im/i18n.cljs @@ -2,22 +2,11 @@ (:require [status-im.translations.en :as en])) -(set! js/window.I18n (js/require "react-native-i18n")) -(set! (.-fallbacks js/I18n) true) -(set! (.-defaultSeparator js/I18n) "/") +(def i18n (js/require "react-native-i18n")) +(set! (.-fallbacks i18n) true) +(set! (.-defaultSeparator i18n) "/") -(set! (.-translations js.I18n) (clj->js {:en en/translations})) +(set! (.-translations i18n) (clj->js {:en en/translations})) (defn label [path & options] - (.t js/I18n (name path) (clj->js options))) - -(comment - (defn deep-merge [& maps] - (if (every? map? maps) - (apply merge-with deep-merge maps) - (last maps))) - - (defn add-translations [new-translations] - (let [translations (.-translations js/I18n)] - (set! (.-translations js/I18n) (clj->js (deep-merge (js->clj translations) new-translations))))) - ) \ No newline at end of file + (.t i18n (name path) (clj->js options))) diff --git a/src/status_im/utils/crypt.cljs b/src/status_im/utils/crypt.cljs index 722581d10c..87730efe8c 100644 --- a/src/status_im/utils/crypt.cljs +++ b/src/status_im/utils/crypt.cljs @@ -3,7 +3,7 @@ [clojure.string :as s]) (:import goog.crypt.Sha256)) -(set! js/window.RnRandomBytes (js/require "react-native-randombytes")) +(def random-bytes (js/require "react-native-randombytes")) (def sha-256 (Sha256.)) @@ -19,7 +19,7 @@ (byteArrayToHex (.digest sha-256))) (defn gen-random-bytes [length cb] - (.randomBytes js/window.RnRandomBytes length (fn [& [err buf]] - (if err - (cb {:error err}) - (cb {:buffer buf}))))) + (.randomBytes random-bytes length (fn [& [err buf]] + (if err + (cb {:error err}) + (cb {:buffer buf}))))) diff --git a/src/status_im/utils/listview.cljs b/src/status_im/utils/listview.cljs index bd9dfe5dc5..dcd63da8bd 100644 --- a/src/status_im/utils/listview.cljs +++ b/src/status_im/utils/listview.cljs @@ -1,6 +1,5 @@ (ns status-im.utils.listview - (:require-macros [natal-shell.data-source :refer [data-source]]) - (:require [status-im.components.realm])) + (:require-macros [natal-shell.data-source :refer [data-source]])) (defn clone-with-rows [ds rows] (.cloneWithRows ds (reduce (fn [ac el] (.push ac el) ac) From 59cf02194b0f3b06384c86bd8e528edcc1aa2e15 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Sun, 29 May 2016 10:30:46 +0300 Subject: [PATCH 08/19] js/window Former-commit-id: 043d28c44d8c62496627e39fd0cb21d4a70fb27e --- src/status_im/android/core.cljs | 3 +- .../components/carousel/carousel.cljs | 5 ++- src/status_im/components/drawer/view.cljs | 5 ++- .../components/invertible_scroll_view.cljs | 5 ++- src/status_im/components/react.cljs | 45 ++++++++++--------- src/status_im/discovery/views/popular.cljs | 6 +-- src/status_im/persistence/realm.cljs | 6 +-- 7 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/status_im/android/core.cljs b/src/status_im/android/core.cljs index 080a91fa54..cf3c7d48e1 100644 --- a/src/status_im/android/core.cljs +++ b/src/status_im/android/core.cljs @@ -60,4 +60,5 @@ (dispatch [:init-console-chat]) (dispatch [:init-chat]) (init-back-button-handler!) - (.registerComponent app-registry "StatusIm" #(r/reactify-component app-root))) + ;(.registerComponent app-registry "StatusIm" #(r/reactify-component app-root)) + ) diff --git a/src/status_im/components/carousel/carousel.cljs b/src/status_im/components/carousel/carousel.cljs index c3181df6ce..8c61cb114e 100644 --- a/src/status_im/components/carousel/carousel.cljs +++ b/src/status_im/components/carousel/carousel.cljs @@ -5,11 +5,12 @@ touchable-without-feedback text]] [status-im.components.carousel.styles :as st] - [status-im.utils.logging :as log])) + [status-im.utils.logging :as log] + [status-im.components.react :as r])) (defn window-page-width [] - (.-width (.get (.. js/React -Dimensions) "window"))) + (.-width (.get (.. r/react -Dimensions) "window"))) (def defaults {:gap 10 :sneak 10 diff --git a/src/status_im/components/drawer/view.cljs b/src/status_im/components/drawer/view.cljs index 1cd4ae43e8..0ac23a7dbb 100644 --- a/src/status_im/components/drawer/view.cljs +++ b/src/status_im/components/drawer/view.cljs @@ -12,7 +12,8 @@ touchable-opacity]] [status-im.resources :as res] [status-im.components.drawer.styles :as st] - [status-im.i18n :refer [label]])) + [status-im.i18n :refer [label]] + [status-im.components.react :refer [react]])) (defonce drawer-atom (atom)) @@ -72,7 +73,7 @@ (defn drawer-view [items] [drawer-layout-android {:drawerWidth 260 - :drawerPosition js/React.DrawerLayoutAndroid.positions.Left + :drawerPosition react.DrawerLayoutAndroid.positions.Left :render-navigation-view #(r/as-element [drawer-menu]) :ref (fn [drawer] (reset! drawer-atom drawer))} diff --git a/src/status_im/components/invertible_scroll_view.cljs b/src/status_im/components/invertible_scroll_view.cljs index ba4a1d546a..429d66d6ed 100644 --- a/src/status_im/components/invertible_scroll_view.cljs +++ b/src/status_im/components/invertible_scroll_view.cljs @@ -1,7 +1,8 @@ -(ns status-im.components.invertible-scroll-view) +(ns status-im.components.invertible-scroll-view + (:require [reagent.core :as r])) (def class (js/require "react-native-invertible-scroll-view")) (defn invertible-scroll-view [props] - (js/React.createElement class (clj->js (merge {:inverted true} props)))) + (r/create-element class (clj->js (merge {:inverted true} props)))) diff --git a/src/status_im/components/react.cljs b/src/status_im/components/react.cljs index 930f6deedf..d79d7d4fa9 100644 --- a/src/status_im/components/react.cljs +++ b/src/status_im/components/react.cljs @@ -2,25 +2,28 @@ (:require [reagent.core :as r] [status-im.components.styles :as st])) -(set! js/window.React (js/require "react-native")) +(when (exists? js/window) + (set! js/window.React (js/require "react-native"))) -(def app-registry (.-AppRegistry js/React)) -(def navigator (r/adapt-react-class (.-Navigator js/React))) -(def text (r/adapt-react-class (.-Text js/React))) -(def view (r/adapt-react-class (.-View js/React))) -(def image (r/adapt-react-class (.-Image js/React))) -(def touchable-highlight-class (r/adapt-react-class (.-TouchableHighlight js/React))) +(def react (js/require "react-native")) + +(def app-registry (.-AppRegistry react)) +(def navigator (r/adapt-react-class (.-Navigator react))) +(def text (r/adapt-react-class (.-Text react))) +(def view (r/adapt-react-class (.-View react))) +(def image (r/adapt-react-class (.-Image react))) +(def touchable-highlight-class (r/adapt-react-class (.-TouchableHighlight react))) (defn touchable-highlight [props content] [touchable-highlight-class (merge {:underlay-color :transparent} props) content]) -(def toolbar-android (r/adapt-react-class (.-ToolbarAndroid js/React))) -(def list-view-class (r/adapt-react-class (.-ListView js/React))) +(def toolbar-android (r/adapt-react-class (.-ToolbarAndroid react))) +(def list-view-class (r/adapt-react-class (.-ListView react))) (defn list-view [props] [list-view-class (merge {:enableEmptySections true} props)]) -(def scroll-view (r/adapt-react-class (.-ScrollView js/React))) -(def touchable-without-feedback (r/adapt-react-class (.-TouchableWithoutFeedback js/React))) -(def text-input-class (r/adapt-react-class (.-TextInput js/React))) +(def scroll-view (r/adapt-react-class (.-ScrollView react))) +(def touchable-without-feedback (r/adapt-react-class (.-TouchableWithoutFeedback react))) +(def text-input-class (r/adapt-react-class (.-TextInput react))) (defn text-input [props text] [text-input-class (merge {:underlineColorAndroid :transparent @@ -28,11 +31,11 @@ :placeholder "Type"} props) text]) -(def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid js/React))) -(def touchable-opacity (r/adapt-react-class (.-TouchableOpacity js/React))) -(def modal (r/adapt-react-class (.-Modal js/React))) -(def picker (r/adapt-react-class (.-Picker js/React))) -(def picker-item (r/adapt-react-class (.-Item (.-Picker js/React)))) +(def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid react))) +(def touchable-opacity (r/adapt-react-class (.-TouchableOpacity react))) +(def modal (r/adapt-react-class (.-Modal react))) +(def picker (r/adapt-react-class (.-Picker react))) +(def picker-item (r/adapt-react-class (.-Item (.-Picker react)))) (defn icon @@ -44,13 +47,13 @@ ;(def react-linear-gradient (.-default (js/require "react-native-linear-gradient"))) ;(def linear-gradient (r/adapt-react-class react-linear-gradient)) -(set! js/window.LinearGradient (js/require "react-native-linear-gradient")) +(def linear-gradient-class (js/require "react-native-linear-gradient")) (defn linear-gradient [props] - (js/React.createElement js/LinearGradient - (clj->js (merge {:inverted true} props)))) + (r/creacteElement linear-gradient-class + (clj->js (merge {:inverted true} props)))) -(def platform (.. js/React -Platform -OS)) +(def platform (.. react -Platform -OS)) (def android? (= platform "android")) diff --git a/src/status_im/discovery/views/popular.cljs b/src/status_im/discovery/views/popular.cljs index 9fbeb4f9fb..b91b233603 100644 --- a/src/status_im/discovery/views/popular.cljs +++ b/src/status_im/discovery/views/popular.cljs @@ -2,16 +2,16 @@ (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe]] - [status-im.utils.logging :as log] [status-im.components.react :refer [android? text]] [status-im.components.carousel.carousel :refer [carousel]] [status-im.discovery.styles :as st] [status-im.discovery.views.popular-list :refer [discovery-popular-list]] - [status-im.i18n :refer [label]])) + [status-im.i18n :refer [label]] + [status-im.components.react :as r])) (defn page-width [] - (.-width (.get (.. js/React -Dimensions) "window"))) + (.-width (.get (.. r/react -Dimensions) "window"))) (defview popular [] [popular-tags [:get-popular-tags 3]] diff --git a/src/status_im/persistence/realm.cljs b/src/status_im/persistence/realm.cljs index a7d564f143..7056c11e9d 100644 --- a/src/status_im/persistence/realm.cljs +++ b/src/status_im/persistence/realm.cljs @@ -5,8 +5,6 @@ [status-im.utils.types :refer [to-string]]) (:refer-clojure :exclude [exists?])) -(set! js/window.Realm (js/require "realm")) - (def opts {:schema [{:name :contacts :primaryKey :whisper-identity :properties {:phone-number {:type "string" @@ -70,7 +68,9 @@ :objectType "tag"} :last-updated "date"}}]}) -(def realm (js/Realm. (clj->js opts))) +(def realm-class (js/require "realm")) + +(def realm (realm-class. (clj->js opts))) (def schema-by-name (->> (:schema opts) (mapv (fn [{:keys [name] :as schema}] From 3ea8b2cb828e92b0c6b1a4db1f6d9b7fd83ea9c8 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Sun, 29 May 2016 21:14:34 +0300 Subject: [PATCH 09/19] first unit test Former-commit-id: 1766b1af1295f6773f580a3a6d3a1afba3dbff0a --- .gitignore | 5 ++ project.clj | 15 ++-- src/status_im/android/core.cljs | 3 +- src/status_im/components/drawer/view.cljs | 84 +++++++++++------------ src/status_im/components/react.cljs | 60 +++++++++------- src/status_im/contacts/handlers.cljs | 2 +- src/status_im/handlers.cljs | 16 +++-- src/status_im/i18n.cljs | 9 ++- src/status_im/persistence/realm.cljs | 8 ++- src/status_im/utils/crypt.cljs | 7 +- src/status_im/utils/phone_number.cljs | 13 ++-- src/status_im/utils/sms_listener.cljs | 5 +- src/status_im/utils/utils.cljs | 5 ++ test/{ => clj}/status_im/appium.clj | 0 test/{ => clj}/status_im/console.clj | 0 test/cljs/status_im/test/handlers.cljs | 6 ++ test/cljs/status_im/test/runner.cljs | 5 ++ 17 files changed, 145 insertions(+), 98 deletions(-) rename test/{ => clj}/status_im/appium.clj (100%) rename test/{ => clj}/status_im/console.clj (100%) create mode 100644 test/cljs/status_im/test/handlers.cljs create mode 100644 test/cljs/status_im/test/runner.cljs diff --git a/.gitignore b/.gitignore index ea7f8f836b..3e79181fd8 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,8 @@ figwheel_server.log # Lein # .lein-failures + +## Doo +# +out +doo-index.html diff --git a/project.clj b/project.clj index d68172cc05..4007f3100d 100644 --- a/project.clj +++ b/project.clj @@ -8,7 +8,7 @@ [reagent "0.5.1" :exclusions [cljsjs/react]] [re-frame "0.6.0"] [prismatic/schema "1.0.4"] - ^{:voom {:repo "git@github.com:status-im/status-lib.git" + ^{:voom {:repo "git@github.com:status-im/status-lib.git" :branch "master"}} [status-im/protocol "0.1.1-20160525_083359-g53ab2c2"] [natal-shell "0.1.6"] @@ -20,11 +20,12 @@ ["do" "clean" ["with-profile" "prod" "cljsbuild" "once" "ios"] ["with-profile" "prod" "cljsbuild" "once" "android"]]} + :test-paths ["test/clj"] :figwheel {:nrepl-port 7888} :profiles {:dev {:dependencies [[figwheel-sidecar "0.5.0-2"] [com.cemerick/piggieback "0.2.1"] - [io.appium/java-client "3.4.1"] - ] + [io.appium/java-client "3.4.1"]] + :plugins [[lein-doo "0.1.6"]] :source-paths ["src" "env/dev"] :cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"] :figwheel true @@ -37,7 +38,13 @@ :compiler {:output-to "target/android/not-used.js" :main "env.android.main" :output-dir "target/android" - :optimizations :none}}}} + :optimizations :none}} + :test {:source-paths ["src" "test/cljs"] + :compiler + {:main status-im.test.runner + :output-to "target/test/test.js" + :optimizations :none + :target :nodejs}}}} :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}} :prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"] :compiler {:output-to "index.ios.js" diff --git a/src/status_im/android/core.cljs b/src/status_im/android/core.cljs index cf3c7d48e1..080a91fa54 100644 --- a/src/status_im/android/core.cljs +++ b/src/status_im/android/core.cljs @@ -60,5 +60,4 @@ (dispatch [:init-console-chat]) (dispatch [:init-chat]) (init-back-button-handler!) - ;(.registerComponent app-registry "StatusIm" #(r/reactify-component app-root)) - ) + (.registerComponent app-registry "StatusIm" #(r/reactify-component app-root))) diff --git a/src/status_im/components/drawer/view.cljs b/src/status_im/components/drawer/view.cljs index 0ac23a7dbb..61b7d698b6 100644 --- a/src/status_im/components/drawer/view.cljs +++ b/src/status_im/components/drawer/view.cljs @@ -2,18 +2,16 @@ (:require [clojure.string :as s] [re-frame.core :refer [subscribe dispatch dispatch-sync]] [reagent.core :as r] - [status-im.components.react :refer [android? - view - text - image - navigator - toolbar-android - drawer-layout-android - touchable-opacity]] + [status-im.components.react :as re :refer [view + text + image + navigator + toolbar-android + drawer-layout-android + touchable-opacity]] [status-im.resources :as res] [status-im.components.drawer.styles :as st] - [status-im.i18n :refer [label]] - [status-im.components.react :refer [react]])) + [status-im.i18n :refer [label]])) (defonce drawer-atom (atom)) @@ -30,7 +28,7 @@ :style st/user-photo}]) (defn menu-item [{:keys [name handler]}] - [touchable-opacity {:style st/menu-item-touchable + [touchable-opacity {:style st/menu-item-touchable :onPress (fn [] (close-drawer) (handler))} @@ -41,40 +39,40 @@ (let [username (subscribe [:get :username])] (fn [] [view st/drawer-menu - [view st/user-photo-container - [user-photo {}]] - [view st/name-container - [text {:style st/name-text} - @username]] - [view st/menu-items-container - [menu-item {:name (label :t/profile) - :handler #(dispatch [:navigate-to :my-profile])}] - [menu-item {:name (label :t/settings) - :handler (fn [] - ;; TODO not implemented - )}] - [menu-item {:name (label :t/discovery) - :handler #(dispatch [:navigate-to :discovery])}] - [menu-item {:name (label :t/contacts) - :handler #(dispatch [:show-contacts navigator])}] - [menu-item {:name (label :t/invite-friends) - :handler (fn [] - ;; TODO not implemented - )}] - [menu-item {:name (label :t/faq) - :handler (fn [])}]] - [view st/switch-users-container - [touchable-opacity {:onPress (fn [] - (close-drawer) - ;; TODO not implemented - )} - [text {:style st/switch-users-text} - (label :t/switch-users)]]]]))) + [view st/user-photo-container + [user-photo {}]] + [view st/name-container + [text {:style st/name-text} + @username]] + [view st/menu-items-container + [menu-item {:name (label :t/profile) + :handler #(dispatch [:navigate-to :my-profile])}] + [menu-item {:name (label :t/settings) + :handler (fn [] + ;; TODO not implemented + )}] + [menu-item {:name (label :t/discovery) + :handler #(dispatch [:navigate-to :discovery])}] + [menu-item {:name (label :t/contacts) + :handler #(dispatch [:show-contacts navigator])}] + [menu-item {:name (label :t/invite-friends) + :handler (fn [] + ;; TODO not implemented + )}] + [menu-item {:name (label :t/faq) + :handler (fn [])}]] + [view st/switch-users-container + [touchable-opacity {:onPress (fn [] + (close-drawer) + ;; TODO not implemented + )} + [text {:style st/switch-users-text} + (label :t/switch-users)]]]]))) (defn drawer-view [items] [drawer-layout-android {:drawerWidth 260 - :drawerPosition react.DrawerLayoutAndroid.positions.Left + :drawerPosition re/react.DrawerLayoutAndroild.positions.Left :render-navigation-view #(r/as-element [drawer-menu]) - :ref (fn [drawer] - (reset! drawer-atom drawer))} + :ref (fn [drawer] + (reset! drawer-atom drawer))} items]) diff --git a/src/status_im/components/react.cljs b/src/status_im/components/react.cljs index d79d7d4fa9..5daccaee88 100644 --- a/src/status_im/components/react.cljs +++ b/src/status_im/components/react.cljs @@ -1,29 +1,39 @@ (ns status-im.components.react (:require [reagent.core :as r] - [status-im.components.styles :as st])) + [status-im.components.styles :as st] + [status-im.utils.utils :as u])) (when (exists? js/window) (set! js/window.React (js/require "react-native"))) -(def react (js/require "react-native")) +(def react (u/require "react-native")) -(def app-registry (.-AppRegistry react)) -(def navigator (r/adapt-react-class (.-Navigator react))) -(def text (r/adapt-react-class (.-Text react))) -(def view (r/adapt-react-class (.-View react))) -(def image (r/adapt-react-class (.-Image react))) -(def touchable-highlight-class (r/adapt-react-class (.-TouchableHighlight react))) +(defn get-react-property [name] + (aget react name)) + +(defn adapt-class [class] + (when class (r/adapt-react-class class))) + +(defn get-class [name] + (adapt-class (get-react-property name))) + +(def app-registry (get-react-property "AppRegistry")) +(def navigator (get-class "Navigator")) +(def text (get-class "Text")) +(def view (get-class "View")) +(def image (get-class "Image")) +(def touchable-highlight-class (get-class "TouchableHighlight")) (defn touchable-highlight [props content] [touchable-highlight-class (merge {:underlay-color :transparent} props) content]) -(def toolbar-android (r/adapt-react-class (.-ToolbarAndroid react))) -(def list-view-class (r/adapt-react-class (.-ListView react))) +(def toolbar-android (get-class "ToolbarAndroid")) +(def list-view-class (get-class "ListView")) (defn list-view [props] [list-view-class (merge {:enableEmptySections true} props)]) -(def scroll-view (r/adapt-react-class (.-ScrollView react))) -(def touchable-without-feedback (r/adapt-react-class (.-TouchableWithoutFeedback react))) -(def text-input-class (r/adapt-react-class (.-TextInput react))) +(def scroll-view (get-class "ScrollView")) +(def touchable-without-feedback (get-class "TouchableWithoutFeedback")) +(def text-input-class (get-class "TextInput")) (defn text-input [props text] [text-input-class (merge {:underlineColorAndroid :transparent @@ -31,11 +41,13 @@ :placeholder "Type"} props) text]) -(def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid react))) -(def touchable-opacity (r/adapt-react-class (.-TouchableOpacity react))) -(def modal (r/adapt-react-class (.-Modal react))) -(def picker (r/adapt-react-class (.-Picker react))) -(def picker-item (r/adapt-react-class (.-Item (.-Picker react)))) +(def drawer-layout-android (get-class "DrawerLayoutAndroid")) +(def touchable-opacity (get-class "TouchableOpacity")) +(def modal (get-class "Modal")) +(def picker (get-class "Picker")) +(def picker-item + (when-let [picker (get-react-property "Picker")] + (adapt-class (.-Item picker)))) (defn icon @@ -44,20 +56,18 @@ [image {:source {:uri (keyword (str "icon_" (name n)))} :style style}])) -;(def react-linear-gradient (.-default (js/require "react-native-linear-gradient"))) -;(def linear-gradient (r/adapt-react-class react-linear-gradient)) - -(def linear-gradient-class (js/require "react-native-linear-gradient")) +(def linear-gradient-class (u/require "react-native-linear-gradient")) (defn linear-gradient [props] - (r/creacteElement linear-gradient-class + (r/create-element linear-gradient-class (clj->js (merge {:inverted true} props)))) -(def platform (.. react -Platform -OS)) +(def platform + (when-let [pl (.-Platform react)] (.-OS pl))) (def android? (= platform "android")) (defn list-item [component] (r/as-element component)) -(def dismiss-keyboard! (js/require "dismissKeyboard")) +(def dismiss-keyboard! (u/require "dismissKeyboard")) diff --git a/src/status_im/contacts/handlers.cljs b/src/status_im/contacts/handlers.cljs index 268b701815..bbb7fd8b7c 100644 --- a/src/status_im/contacts/handlers.cljs +++ b/src/status_im/contacts/handlers.cljs @@ -26,7 +26,7 @@ (register-handler :load-contacts load-contacts!) ;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45 -(def react-native-contacts (js/require "react-native-contacts")) +(def react-native-contacts #_(js/require "react-native-contacts")) (defn contact-name [contact] (->> contact diff --git a/src/status_im/handlers.cljs b/src/status_im/handlers.cljs index 4010049665..6aa74b5c5f 100644 --- a/src/status_im/handlers.cljs +++ b/src/status_im/handlers.cljs @@ -35,15 +35,19 @@ ;; -- Common -------------------------------------------------------------- +(defn set-el [db [_ k v]] + (assoc db k v)) + (register-handler :set - (debug - (fn [db [_ k v]] - (assoc db k v)))) + debug + set-el) + +(defn set-in [db [_ path v]] + (assoc-in db path v)) (register-handler :set-in - (debug - (fn [db [_ path v]] - (assoc-in db path v)))) + debug + set-in) (register-handler :initialize-db (fn [_ _] diff --git a/src/status_im/i18n.cljs b/src/status_im/i18n.cljs index 4a6157cc23..aff04c97b2 100644 --- a/src/status_im/i18n.cljs +++ b/src/status_im/i18n.cljs @@ -1,12 +1,15 @@ (ns status-im.i18n (:require - [status-im.translations.en :as en])) + [status-im.translations.en :as en] + [status-im.utils.utils :as u])) -(def i18n (js/require "react-native-i18n")) +(def i18n (u/require "react-native-i18n")) (set! (.-fallbacks i18n) true) (set! (.-defaultSeparator i18n) "/") (set! (.-translations i18n) (clj->js {:en en/translations})) (defn label [path & options] - (.t i18n (name path) (clj->js options))) + (if (exists? i18n.t) + (.t i18n (name path) (clj->js options)) + (name path))) diff --git a/src/status_im/persistence/realm.cljs b/src/status_im/persistence/realm.cljs index 7056c11e9d..5d304828fe 100644 --- a/src/status_im/persistence/realm.cljs +++ b/src/status_im/persistence/realm.cljs @@ -2,7 +2,8 @@ (:require [cljs.reader :refer [read-string]] [status-im.components.styles :refer [default-chat-color]] [status-im.utils.logging :as log] - [status-im.utils.types :refer [to-string]]) + [status-im.utils.types :refer [to-string]] + [status-im.utils.utils :as u]) (:refer-clojure :exclude [exists?])) (def opts {:schema [{:name :contacts @@ -68,9 +69,10 @@ :objectType "tag"} :last-updated "date"}}]}) -(def realm-class (js/require "realm")) +(def realm-class (u/require "realm")) -(def realm (realm-class. (clj->js opts))) +(def realm (when (cljs.core/exists? js/window) + (realm-class. (clj->js opts)))) (def schema-by-name (->> (:schema opts) (mapv (fn [{:keys [name] :as schema}] diff --git a/src/status_im/utils/crypt.cljs b/src/status_im/utils/crypt.cljs index 87730efe8c..0b3f2dd7d0 100644 --- a/src/status_im/utils/crypt.cljs +++ b/src/status_im/utils/crypt.cljs @@ -1,9 +1,10 @@ (ns status-im.utils.crypt (:require [goog.crypt :refer [byteArrayToHex]] - [clojure.string :as s]) + [clojure.string :as s] + [status-im.utils.utils :as u]) (:import goog.crypt.Sha256)) -(def random-bytes (js/require "react-native-randombytes")) +(def random-bytes (u/require "react-native-randombytes")) (def sha-256 (Sha256.)) @@ -19,7 +20,7 @@ (byteArrayToHex (.digest sha-256))) (defn gen-random-bytes [length cb] - (.randomBytes random-bytes length (fn [& [err buf]] + #_(.randomBytes random-bytes length (fn [& [err buf]] (if err (cb {:error err}) (cb {:buffer buf}))))) diff --git a/src/status_im/utils/phone_number.cljs b/src/status_im/utils/phone_number.cljs index 137a1c37b5..da0ada6733 100644 --- a/src/status_im/utils/phone_number.cljs +++ b/src/status_im/utils/phone_number.cljs @@ -1,16 +1,17 @@ -(ns status-im.utils.phone-number) +(ns status-im.utils.phone-number + (:require [status-im.utils.utils :as u])) -(def i18n (js/require "react-native-i18n")) -(def locale (.-locale i18n)) +(def i18n (u/require "react-native-i18n")) +(def locale (or (.-locale i18n) "___en")) (def country-code (subs locale 3 5)) -(set! js/PhoneNumber (js/require "awesome-phonenumber")) +(def awesome-phonenumber (u/require "awesome-phonenumber")) ;; todo check wrong numbers, .getNumber returns empty string (defn format-phone-number [number] - (str (.getNumber (js/PhoneNumber. number country-code "international")))) + (str (.getNumber (awesome-phonenumber. number country-code "international")))) (defn valid-mobile-number? [number] (when (string? number) - (let [number-obj (js/PhoneNumber. number country-code "international")] + (let [number-obj (awesome-phonenumber. number country-code "international")] (and (.isValid number-obj) (.isMobile number-obj))))) diff --git a/src/status_im/utils/sms_listener.cljs b/src/status_im/utils/sms_listener.cljs index f00d54b7e9..04204116a2 100644 --- a/src/status_im/utils/sms_listener.cljs +++ b/src/status_im/utils/sms_listener.cljs @@ -1,7 +1,8 @@ (ns status-im.utils.sms-listener - (:require [status-im.components.react :refer [android?]])) + (:require [status-im.components.react :refer [android?]] + [status-im.utils.utils :as u])) -(def sms-listener (.-default (js/require "react-native-android-sms-listener"))) +(def sms-listener (.-default (u/require "react-native-android-sms-listener"))) ;; Only android is supported! diff --git a/src/status_im/utils/utils.cljs b/src/status_im/utils/utils.cljs index 02d54d3f88..c20a6c1e2a 100644 --- a/src/status_im/utils/utils.cljs +++ b/src/status_im/utils/utils.cljs @@ -5,6 +5,11 @@ [natal-shell.toast-android :as toast]) (:require [status-im.constants :as const])) +(defn require [module] + (if (exists? js/window) + (js/require module) + #js {})) + (defn log [obj] (.log js/console obj)) diff --git a/test/status_im/appium.clj b/test/clj/status_im/appium.clj similarity index 100% rename from test/status_im/appium.clj rename to test/clj/status_im/appium.clj diff --git a/test/status_im/console.clj b/test/clj/status_im/console.clj similarity index 100% rename from test/status_im/console.clj rename to test/clj/status_im/console.clj diff --git a/test/cljs/status_im/test/handlers.cljs b/test/cljs/status_im/test/handlers.cljs new file mode 100644 index 0000000000..70f4ae44c6 --- /dev/null +++ b/test/cljs/status_im/test/handlers.cljs @@ -0,0 +1,6 @@ +(ns status-im.test.handlers + (:require [cljs.test :refer-macros [deftest is]] + [status-im.handlers :as h])) + +(deftest test-set-val + (is (= {:key :val} (h/set-el {} [nil :key :val])))) diff --git a/test/cljs/status_im/test/runner.cljs b/test/cljs/status_im/test/runner.cljs new file mode 100644 index 0000000000..14bda7de00 --- /dev/null +++ b/test/cljs/status_im/test/runner.cljs @@ -0,0 +1,5 @@ +(ns status-im.test.runner + (:require [doo.runner :refer-macros [doo-tests]] + [status-im.test.handlers])) + +(doo-tests 'status-im.test.handlers) From eedf38895d593a48843fd0890dcbdd644c1e2238 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Mon, 30 May 2016 10:22:29 +0300 Subject: [PATCH 10/19] doc for appium-test Former-commit-id: c8d0f590c21797dfed5f7deb74e022c65b3d2a2c --- test/clj/status_im/appium.clj | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/clj/status_im/appium.clj b/test/clj/status_im/appium.clj index 061ed3f4b4..d3a77bc435 100644 --- a/test/clj/status_im/appium.clj +++ b/test/clj/status_im/appium.clj @@ -59,7 +59,25 @@ (defn quit [driver] (.quit driver)) -(defmacro appium-test [name & body] +(defmacro appium-test + "Defines test which will create new appium session and will pass that + session as first argument to each command inside it's body. After execution + of all commands session will be closed. + + For instance, + + (appium-test my-test + (click :button) + (write :input \"oops\")) + + will be expanded to + + (deftest my-test + (let [session (init)] + (click session :button) + (write session :input \"oops\") + (quit session)))" + [name & body] (let [sym (gensym)] `(deftest ~name (let [~sym (init)] From c4d3436bfcc3e4900f080a83d3d614f6e9eaf339 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Mon, 30 May 2016 11:01:57 +0300 Subject: [PATCH 11/19] move js/React to cljsjs.react.cljs Former-commit-id: f30248e7fea10649bebf2b412ecef12f4920e663 --- src/cljsjs/react.cljs | 5 ++++- src/status_im/components/drawer/view.cljs | 17 +++++++++-------- src/status_im/components/react.cljs | 3 --- src/status_im/profile/screen.cljs | 22 +++++++++++----------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/cljsjs/react.cljs b/src/cljsjs/react.cljs index aac9de2f4b..582c4c83e0 100644 --- a/src/cljsjs/react.cljs +++ b/src/cljsjs/react.cljs @@ -1 +1,4 @@ -(ns cljsjs.react) \ No newline at end of file +(ns cljsjs.react) + +(when (exists? js/window) + (set! js/window.React (js/require "react-native"))) diff --git a/src/status_im/components/drawer/view.cljs b/src/status_im/components/drawer/view.cljs index 61b7d698b6..a98fb9d542 100644 --- a/src/status_im/components/drawer/view.cljs +++ b/src/status_im/components/drawer/view.cljs @@ -2,13 +2,14 @@ (:require [clojure.string :as s] [re-frame.core :refer [subscribe dispatch dispatch-sync]] [reagent.core :as r] - [status-im.components.react :as re :refer [view - text - image - navigator - toolbar-android - drawer-layout-android - touchable-opacity]] + [status-im.components.react :refer [react + view + text + image + navigator + toolbar-android + drawer-layout-android + touchable-opacity]] [status-im.resources :as res] [status-im.components.drawer.styles :as st] [status-im.i18n :refer [label]])) @@ -71,7 +72,7 @@ (defn drawer-view [items] [drawer-layout-android {:drawerWidth 260 - :drawerPosition re/react.DrawerLayoutAndroild.positions.Left + :drawerPosition js/React.DrawerLayoutAndroid.positions.Left :render-navigation-view #(r/as-element [drawer-menu]) :ref (fn [drawer] (reset! drawer-atom drawer))} diff --git a/src/status_im/components/react.cljs b/src/status_im/components/react.cljs index 5daccaee88..0ab2d2b755 100644 --- a/src/status_im/components/react.cljs +++ b/src/status_im/components/react.cljs @@ -3,9 +3,6 @@ [status-im.components.styles :as st] [status-im.utils.utils :as u])) -(when (exists? js/window) - (set! js/window.React (js/require "react-native"))) - (def react (u/require "react-native")) (defn get-react-property [name] diff --git a/src/status_im/profile/screen.cljs b/src/status_im/profile/screen.cljs index f2de5dcb41..bb0c52a1d8 100644 --- a/src/status_im/profile/screen.cljs +++ b/src/status_im/profile/screen.cljs @@ -2,14 +2,14 @@ (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch]] [status-im.components.react :refer [view - text - image - icon - scroll-view - touchable-highlight - touchable-opacity]] + text + image + icon + scroll-view + touchable-highlight + touchable-opacity]] [status-im.components.chat-icon.screen :refer [profile-icon - my-profile-icon]] + my-profile-icon]] [status-im.profile.styles :as st] [status-im.i18n :refer [label]])) @@ -60,11 +60,11 @@ [text {:style st/report-user-text} (label :t/report-user)]]]]]) (defview my-profile [] - [username [:get :username] - photo-path [:get :photo-path] + [username [:get :username] + photo-path [:get :photo-path] phone-number [:get :phone-number] - email [:get :email] - status [:get :status]] + email [:get :email] + status [:get :status]] [scroll-view {:style st/profile} [touchable-highlight {:style st/back-btn-touchable :on-press #(dispatch [:navigate-back])} From 0f6e15a8d055bf3648e644fdf4fbe2cf4424533c Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Mon, 30 May 2016 11:49:16 +0300 Subject: [PATCH 12/19] fix ids for chats created after receiving from unknown id Former-commit-id: b914493283e4b03415ba576533ff02f68c4ada81 --- src/status_im/chats_list/screen.cljs | 2 +- src/status_im/chats_list/views/chat_list_item.cljs | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs index a82849d7e6..572f0ac5a9 100644 --- a/src/status_im/chats_list/screen.cljs +++ b/src/status_im/chats_list/screen.cljs @@ -36,7 +36,7 @@ [drawer-view [view st/chats-container [chats-list-toolbar] - [list-view {:dataSource (to-datasource (vals @chats)) + [list-view {:dataSource (to-datasource @chats) :renderRow (fn [row _ _] (list-item [chat-list-item row])) :style st/list-container}] diff --git a/src/status_im/chats_list/views/chat_list_item.cljs b/src/status_im/chats_list/views/chat_list_item.cljs index 0c343f9b59..a7877e5e82 100644 --- a/src/status_im/chats_list/views/chat_list_item.cljs +++ b/src/status_im/chats_list/views/chat_list_item.cljs @@ -1,17 +1,18 @@ (ns status-im.chats-list.views.chat-list-item (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] [status-im.components.react :refer [view - text - image - touchable-highlight]] + text + image + touchable-highlight]] [status-im.components.styles :refer [font]] [status-im.chats-list.views.inner-item :refer [chat-list-item-inner-view]])) -(defn chat-list-item [{:keys [chat-id] :as chat}] +(defn chat-list-item [[chat-id chat]] [touchable-highlight {:on-press #(dispatch [:navigate-to :chat chat-id])} [view [chat-list-item-inner-view (merge chat ;; TODO stub data - {:new-messages-count 3 + {:chat-id chat-id + :new-messages-count 3 :online true})]]]) From 7fbbf8b4aabd9e17e21d88a288ca0811e76fbbfe Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Wed, 1 Jun 2016 14:09:43 +0300 Subject: [PATCH 13/19] remove println Former-commit-id: 2bfd90cec410750bd31b9e487cc236192ac8b7ae --- src/status_im/utils/subs.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/status_im/utils/subs.cljs b/src/status_im/utils/subs.cljs index 3be283c37e..60bb24c53b 100644 --- a/src/status_im/utils/subs.cljs +++ b/src/status_im/utils/subs.cljs @@ -5,7 +5,6 @@ "Creates subscrition that cheks if collection (map or set) contains element" [collection] (fn [db [_ element]] - (println "WWWWWWWWWW" (type db)) (-> (collection @db) (contains? element) (reaction)))) From 4d5c5755c6ab4b74c7ed5c5c35d7216404ac0629 Mon Sep 17 00:00:00 2001 From: Adrian Tiberius Date: Wed, 1 Jun 2016 14:44:04 +0300 Subject: [PATCH 14/19] fix translation pluralization Former-commit-id: a46f60c854a6d17d982da3ffdc62ae186a8fa981 --- src/status_im/chat/screen.cljs | 16 ++++++++-------- src/status_im/i18n.cljs | 3 +++ src/status_im/translations/en.cljs | 9 ++++++++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index 8c20bb1136..3ff250e238 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -3,12 +3,12 @@ (:require [re-frame.core :refer [subscribe dispatch]] [clojure.string :as s] [status-im.components.react :refer [view - text - image - icon - touchable-highlight - list-view - list-item]] + text + image + icon + touchable-highlight + list-view + list-item]] [status-im.components.chat-icon.screen :refer [chat-icon-view-action chat-icon-view-menu-item]] [status-im.chat.styles.screen :as st] @@ -18,7 +18,7 @@ [status-im.components.toolbar :refer [toolbar]] [status-im.chat.views.message :refer [chat-message]] [status-im.chat.views.new-message :refer [chat-message-new]] - [status-im.i18n :refer [label]])) + [status-im.i18n :refer [label label-pluralize]])) (defn contacts-by-identity [contacts] @@ -186,7 +186,7 @@ [icon :group st/group-icon] [text {:style st/members} (let [cnt (inc (count @contacts))] - (label :t/members {:count cnt}))]] + (label-pluralize cnt :t/members))]] ;; TODO stub data: last activity [text {:style st/last-activity} (label :t/last-active)])]))) diff --git a/src/status_im/i18n.cljs b/src/status_im/i18n.cljs index 9abde5c46e..de557041fc 100644 --- a/src/status_im/i18n.cljs +++ b/src/status_im/i18n.cljs @@ -11,6 +11,9 @@ (defn label [path & options] (.t js/I18n (name path) (clj->js options))) +(defn label-pluralize [count path & options] + (.p js/I18n count (name path) (clj->js options))) + (comment (defn deep-merge [& maps] (if (every? map? maps) diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index be71f9037b..cf3424d440 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -18,7 +18,8 @@ :and-you "and you" :search-chat "Search chat" :members {:one "1 member, 1 active" - :other "{{count}} members, {{count}} active"} + :other "{{count}} members, {{count}} active" + :zero "no members"} :last-active "Active a minute ago" ;profile @@ -70,6 +71,7 @@ ;contacts :contacts "Contacts" :no-name "Noname" + :new-contact "New Contact" ;group-settings :remove "Remove" @@ -112,4 +114,9 @@ :removed "removed" :You "You" + ;new-contact + :import-qr "Import from QR" + :contact-name "Contact Name" + :contact-address "Contact Address" + }) \ No newline at end of file From ce80c8a330f8f496cffb411966d347c0e2d78ecb Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Wed, 1 Jun 2016 19:42:38 +0300 Subject: [PATCH 15/19] fix exception at fetching of the contacts Former-commit-id: 084f067ae82eca5576f2fc84450c961b3b75cc2b --- src/status_im/contacts/handlers.cljs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/status_im/contacts/handlers.cljs b/src/status_im/contacts/handlers.cljs index bbb7fd8b7c..b3320db158 100644 --- a/src/status_im/contacts/handlers.cljs +++ b/src/status_im/contacts/handlers.cljs @@ -5,7 +5,8 @@ [clojure.string :as s] [status-im.utils.utils :refer [http-post]] [status-im.utils.phone-number :refer [format-phone-number]] - [status-im.utils.handlers :as u])) + [status-im.utils.handlers :as u] + [status-im.utils.utils :refer [require]])) (defn save-contact [_ [_ contact]] @@ -26,7 +27,7 @@ (register-handler :load-contacts load-contacts!) ;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45 -(def react-native-contacts #_(js/require "react-native-contacts")) +(def react-native-contacts (require "react-native-contacts")) (defn contact-name [contact] (->> contact From ed65ba0ba711714fcb142ddec5c4d6cb582a44fc Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Thu, 2 Jun 2016 11:51:44 +0200 Subject: [PATCH 16/19] update run-osx for unit tests and iTerm new release Former-commit-id: 058f470ea7fd00d50de7f6ef20642d5608b44831 --- .re-natal | 2 +- env/dev/env/android/main.cljs | 2 +- run-osx.sh | 13 ++++++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.re-natal b/.re-natal index b4f25ba62a..1455b14c43 100644 --- a/.re-natal +++ b/.re-natal @@ -1,7 +1,7 @@ { "name": "StatusIm", "interface": "reagent", - "androidHost": "10.0.3.2", + "androidHost": "localhost", "modules": [ "react-native-contacts", "react-native-invertible-scroll-view", diff --git a/env/dev/env/android/main.cljs b/env/dev/env/android/main.cljs index f0c3d96fca..1bf474e505 100644 --- a/env/dev/env/android/main.cljs +++ b/env/dev/env/android/main.cljs @@ -10,7 +10,7 @@ (def root-el (r/as-element [reloader])) (figwheel/watch-and-reload - :websocket-url "ws://10.0.3.2:3449/figwheel-ws" + :websocket-url "ws://localhost:3449/figwheel-ws" :heads-up-display false :jsload-callback #(swap! cnt inc)) diff --git a/run-osx.sh b/run-osx.sh index d02de2a3e1..64a86b653f 100755 --- a/run-osx.sh +++ b/run-osx.sh @@ -17,11 +17,13 @@ function tab () { fi osascript &>/dev/null < Date: Thu, 2 Jun 2016 14:23:28 +0300 Subject: [PATCH 17/19] fix contacts loading Former-commit-id: 9ae6e752d894170d65e8d8da813c5386796a3fe8 --- src/status_im/chat/handlers.cljs | 6 +++--- src/status_im/components/chat_icon/screen.cljs | 11 ++++++----- src/status_im/contacts/handlers.cljs | 10 +++++++--- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index 011749f25f..0d0af3a2f3 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -230,9 +230,9 @@ (sign-up-service/stop-listening-confirmation-code-sms db))) (register-handler :sign-up-confirm - (fn [db [_ confirmation-code]] - (server/sign-up-confirm confirmation-code sign-up-service/on-send-code-response) - db)) + (u/side-effect! + (fn [_ [_ confirmation-code]] + (server/sign-up-confirm confirmation-code sign-up-service/on-send-code-response)))) (register-handler :set-signed-up (fn [db [_ signed-up]] diff --git a/src/status_im/components/chat_icon/screen.cljs b/src/status_im/components/chat_icon/screen.cljs index e44d334e33..0d93e38cbb 100644 --- a/src/status_im/components/chat_icon/screen.cljs +++ b/src/status_im/components/chat_icon/screen.cljs @@ -6,7 +6,8 @@ image icon]] [status-im.components.chat-icon.styles :as st] - [status-im.components.styles :refer [color-purple]])) + [status-im.components.styles :refer [color-purple]] + [clojure.string :as s])) (defn default-chat-icon [name styles] [view (:default-chat-icon styles) @@ -26,10 +27,10 @@ (defview chat-icon-view [chat-id group-chat name online styles] [photo-path [:chat-photo chat-id]] [view (:container styles) - (if (and photo-path (not (empty? photo-path))) + (if-not (s/blank? photo-path) [chat-icon photo-path styles] [default-chat-icon name styles]) - (when (not group-chat) + (when-not group-chat [contact-online online styles])]) (defn chat-icon-view-chat-list [chat-id group-chat name color online] @@ -80,7 +81,7 @@ [contact [:contact]] (let [;; TODO stub data online true - color color-purple] + color color-purple] [profile-icon-view (:photo-path contact) (:name contact) color online])) (defview my-profile-icon [] @@ -88,5 +89,5 @@ photo-path [:get :photo-path]] (let [;; TODO stub data online true - color color-purple] + color color-purple] [profile-icon-view photo-path name color online])) diff --git a/src/status_im/contacts/handlers.cljs b/src/status_im/contacts/handlers.cljs index b3320db158..acb9be9b6c 100644 --- a/src/status_im/contacts/handlers.cljs +++ b/src/status_im/contacts/handlers.cljs @@ -92,10 +92,14 @@ (defn add-new-contacts [{:keys [contacts] :as db} [_ new-contacts]] (let [identities (set (map :whisper-identity contacts)) - new-contacts' (remove #(identities (:whisper-identity %)) new-contacts)] + new-contacts' (->> new-contacts + (remove #(identities (:whisper-identity %))) + (map #(vector (:whisper-identity %) %)) + (into {}))] + (println new-contacts') (-> db - (update :contacts concat new-contacts') - (assoc :new-contacts new-contacts')))) + (update :contacts merge new-contacts') + (assoc :new-contacts (vals new-contacts'))))) (register-handler :add-contacts (after save-contacts!) From 6756d023351db4c1ad79b5ee425f549d88b6f850 Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Wed, 8 Jun 2016 12:43:02 +0200 Subject: [PATCH 18/19] warn user if root before starting geth Former-commit-id: 1f0a4214b814da17d596f368c962c30152843327 --- .../main/java/com/statusim/MainActivity.java | 44 +++++++++++++++++-- .../src/main/java/com/statusim/RootUtil.java | 41 +++++++++++++++++ android/app/src/main/res/values/strings.xml | 7 ++- 3 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 android/app/src/main/java/com/statusim/RootUtil.java diff --git a/android/app/src/main/java/com/statusim/MainActivity.java b/android/app/src/main/java/com/statusim/MainActivity.java index 3d411d9213..eeb1c628e8 100644 --- a/android/app/src/main/java/com/statusim/MainActivity.java +++ b/android/app/src/main/java/com/statusim/MainActivity.java @@ -8,6 +8,10 @@ import com.facebook.react.shell.MainReactPackage; import com.rt2zz.reactnativecontacts.ReactNativeContacts; import android.os.Bundle; import android.os.Environment; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.DialogInterface.OnCancelListener; import com.github.ethereum.go_ethereum.cmd.Geth; import com.bitgo.randombytes.RandomBytesPackage; import com.BV.LinearGradient.LinearGradientPackage; @@ -18,20 +22,20 @@ 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); + protected void startStatus() { // Required for android-16 (???) System.loadLibrary("gethraw"); System.loadLibrary("geth"); - // Required because of crazy APN settings redirecting localhost + // Required because of crazy APN settings redirecting localhost (found in GB) Properties properties = System.getProperties(); properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1"); properties.setProperty("https.nonProxyHosts", "localhost|127.0.0.1"); @@ -50,6 +54,38 @@ public class MainActivity extends ReactActivity { }).start(); } + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if(!RootUtil.isDeviceRooted()) { + startStatus(); + } else { + AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).setMessage(getResources().getString(R.string.root_warning)) + .setPositiveButton(getResources().getString(R.string.root_okay), new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + startStatus(); + } + }).setNegativeButton(getResources().getString(R.string.root_cancel), new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + MainActivity.this.finishAffinity(); + } + }).setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + dialog.dismiss(); + MainActivity.this.finishAffinity(); + } + }).create(); + dialog.show(); + } + + } + /** * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. diff --git a/android/app/src/main/java/com/statusim/RootUtil.java b/android/app/src/main/java/com/statusim/RootUtil.java new file mode 100644 index 0000000000..c5b9e88df0 --- /dev/null +++ b/android/app/src/main/java/com/statusim/RootUtil.java @@ -0,0 +1,41 @@ +package com.statusim; + +import java.io.File; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** @author Kevin Kowalewski */ +public class RootUtil { + + public static boolean isDeviceRooted() { + return checkRootMethod1() || checkRootMethod2() || checkRootMethod3(); + } + + private static boolean checkRootMethod1() { + String buildTags = android.os.Build.TAGS; + return buildTags != null && buildTags.contains("test-keys"); + } + + private static boolean checkRootMethod2() { + String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", + "/system/bin/failsafe/su", "/data/local/su" }; + for (String path : paths) { + if (new File(path).exists()) return true; + } + return false; + } + + private static boolean checkRootMethod3() { + Process process = null; + try { + process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" }); + BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); + if (in.readLine() != null) return true; + return false; + } catch (Throwable t) { + return false; + } finally { + if (process != null) process.destroy(); + } + } +} diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index fb87cafc71..714ecb8518 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,3 +1,6 @@ - StatusIm - + Status + Your phone appears to be ROOTED, this is a serious security concern, continue only if you understand and accept the risks. + Continue + Exit + \ No newline at end of file From 4b43096ba8eab77be3186fb808b6adfe7d97c19b Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Wed, 8 Jun 2016 15:29:48 +0200 Subject: [PATCH 19/19] System.loadLibrary voodoo magic Former-commit-id: 97ff59f95bcdd80a57833263c5a8191223683be6 --- .re-natal | 2 +- android/app/src/main/java/com/statusim/MainActivity.java | 9 +++++---- env/dev/env/android/main.cljs | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.re-natal b/.re-natal index 1455b14c43..b4f25ba62a 100644 --- a/.re-natal +++ b/.re-natal @@ -1,7 +1,7 @@ { "name": "StatusIm", "interface": "reagent", - "androidHost": "localhost", + "androidHost": "10.0.3.2", "modules": [ "react-native-contacts", "react-native-invertible-scroll-view", diff --git a/android/app/src/main/java/com/statusim/MainActivity.java b/android/app/src/main/java/com/statusim/MainActivity.java index 1a7986b3c0..7d14e08627 100644 --- a/android/app/src/main/java/com/statusim/MainActivity.java +++ b/android/app/src/main/java/com/statusim/MainActivity.java @@ -35,10 +35,6 @@ public class MainActivity extends ReactActivity { final Handler handler = new Handler(); protected void startStatus() { - // Required for android-16 (???) - System.loadLibrary("gethraw"); - System.loadLibrary("geth"); - // Required because of crazy APN settings redirecting localhost (found in GB) Properties properties = System.getProperties(); properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1"); @@ -70,6 +66,11 @@ public class MainActivity extends ReactActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // Required for android-16 (???) + // Crash if put in startStatus() ? + System.loadLibrary("gethraw"); + System.loadLibrary("geth"); + if(!RootUtil.isDeviceRooted()) { startStatus(); } else { diff --git a/env/dev/env/android/main.cljs b/env/dev/env/android/main.cljs index 1bf474e505..f0c3d96fca 100644 --- a/env/dev/env/android/main.cljs +++ b/env/dev/env/android/main.cljs @@ -10,7 +10,7 @@ (def root-el (r/as-element [reloader])) (figwheel/watch-and-reload - :websocket-url "ws://localhost:3449/figwheel-ws" + :websocket-url "ws://10.0.3.2:3449/figwheel-ws" :heads-up-display false :jsload-callback #(swap! cnt inc))