commit
8419be3e8f
|
@ -8,7 +8,7 @@
|
|||
(:require [om.next :as om :refer-macros [defui]]
|
||||
[re-natal.support :as sup]
|
||||
[messenger.state :as state]
|
||||
[messenger.android.resources :as res]))
|
||||
[messenger.utils.resources :as res]))
|
||||
|
||||
(set! js/InvertibleScrollView (js/require "react-native-invertible-scroll-view"))
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
(ns messenger.android.contacts
|
||||
(:require [messenger.state :as state]
|
||||
[messenger.android.utils :refer [log toast http-post]]
|
||||
[messenger.android.database :as db]))
|
||||
|
||||
(def fake-contacts? true)
|
||||
|
||||
(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 [on-success on-error]
|
||||
(if fake-contacts?
|
||||
(on-success (generate-contacts 10))
|
||||
(.getAll react-native-contacts
|
||||
(fn [error raw-contacts]
|
||||
(if (not error)
|
||||
(let [contacts (map (fn [contact]
|
||||
(merge (generate-contact 1)
|
||||
{:name (:givenName contact)
|
||||
:photo-path (:thumbnailPath contact)
|
||||
:phone-numbers (:phoneNumbers contact)}))
|
||||
(js->clj raw-contacts :keywordize-keys true))]
|
||||
(on-success contacts))
|
||||
(when on-error
|
||||
(on-error error)))))))
|
||||
|
||||
(defn load-whisper-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)}))
|
||||
(db/get-contacts)))
|
|
@ -2,15 +2,13 @@
|
|||
(:require-macros
|
||||
[natal-shell.components :refer [view text image touchable-highlight list-view
|
||||
toolbar-android]]
|
||||
[natal-shell.data-source :refer [data-source clone-with-rows]]
|
||||
[natal-shell.core :refer [with-error-view]]
|
||||
[natal-shell.alert :refer [alert]])
|
||||
[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.android.utils :refer [log toast http-post]]
|
||||
[messenger.android.resources :as res]
|
||||
[messenger.android.contacts :as contacts]
|
||||
[messenger.utils.utils :refer [log toast http-post]]
|
||||
[messenger.utils.resources :as res]
|
||||
[messenger.comm.intercom :as intercom]
|
||||
[messenger.android.chat :refer [chat]]))
|
||||
|
||||
(def fake-contacts? true)
|
||||
|
@ -137,9 +135,7 @@
|
|||
{:nav nav})))
|
||||
|
||||
(defn load-contacts []
|
||||
(let [contacts (contacts/load-whisper-contacts)]
|
||||
(swap! state/app-state update :contacts-ds
|
||||
#(clone-with-rows % contacts))))
|
||||
(intercom/load-syng-contacts))
|
||||
|
||||
(defui ContactsList
|
||||
static om/IQuery
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
(:require [om.next :as om :refer-macros [defui]]
|
||||
[re-natal.support :as sup]
|
||||
[messenger.state :as state]
|
||||
[messenger.utils.utils :refer [log toast]]
|
||||
[messenger.android.login :refer [login]]
|
||||
[messenger.android.contacts-list :refer [contacts-list]]
|
||||
[messenger.android.chat :refer [chat]]
|
||||
[messenger.comm.pubsub :as pubsub]
|
||||
[messenger.comm.intercom :refer [load-user-phone-number]]))
|
||||
[messenger.comm.intercom :as intercom :refer [load-user-phone-number
|
||||
load-user-whisper-identity]]))
|
||||
|
||||
(def app-registry (.-AppRegistry js/React))
|
||||
|
||||
|
@ -34,20 +36,20 @@
|
|||
(defui AppRoot
|
||||
static om/IQuery
|
||||
(query [this]
|
||||
'[:page :contacts-ds :user-phone-number :confirmation-code])
|
||||
'[:contacts-ds :user-phone-number :confirmation-code])
|
||||
Object
|
||||
(render [this]
|
||||
(let [{:keys [page]} (om/props this)]
|
||||
(navigator
|
||||
{:initialRoute {:component login}
|
||||
:renderScene (fn [route nav]
|
||||
(when state/*nav-render*
|
||||
(init-back-button-handler! nav)
|
||||
(let [{:keys [component]}
|
||||
(js->clj route :keywordize-keys true)]
|
||||
(component (om/computed (om/props this)
|
||||
{:nav nav})))))}))))
|
||||
(navigator
|
||||
{:initialRoute {:component login}
|
||||
:renderScene (fn [route nav]
|
||||
(when state/*nav-render*
|
||||
(init-back-button-handler! nav)
|
||||
(let [{:keys [component]}
|
||||
(js->clj route :keywordize-keys true)]
|
||||
(component (om/computed (om/props this)
|
||||
{:nav nav})))))})))
|
||||
|
||||
;; TODO to service?
|
||||
(swap! state/app-state assoc :contacts-ds
|
||||
(data-source {:rowHasChanged (fn [row1 row2]
|
||||
(not= row1 row2))}))
|
||||
|
@ -59,5 +61,6 @@
|
|||
(defn init []
|
||||
(pubsub/setup-pub-sub)
|
||||
(load-user-phone-number)
|
||||
(load-user-whisper-identity)
|
||||
(om/add-root! state/reconciler AppRoot 1)
|
||||
(.registerComponent app-registry "Messenger" (fn [] app-root)))
|
||||
|
|
|
@ -2,93 +2,42 @@
|
|||
(: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]])
|
||||
[natal-shell.core :refer [with-error-view]])
|
||||
(:require [om.next :as om :refer-macros [defui]]
|
||||
[re-natal.support :as sup]
|
||||
[syng-im.protocol.web3 :as whisper]
|
||||
[messenger.state :as state]
|
||||
[messenger.android.utils :refer [log toast http-post]]
|
||||
[messenger.android.resources :as res]
|
||||
[messenger.comm.intercom :as intercom :refer [set-user-phone-number]]
|
||||
[messenger.utils.utils :refer [log toast http-post]]
|
||||
[messenger.utils.resources :as res]
|
||||
[messenger.android.sign-up-confirm :refer [sign-up-confirm]]))
|
||||
|
||||
(def nav-atom (atom nil))
|
||||
|
||||
(set! js/PhoneNumber (js/require "awesome-phonenumber"))
|
||||
(def country-code "US")
|
||||
(def ethereum-rpc-url "http://localhost:8545")
|
||||
|
||||
(defn show-confirm-view []
|
||||
(binding [state/*nav-render* false]
|
||||
(.replace @nav-atom (clj->js {:component sign-up-confirm
|
||||
:name "sign-up-confirm"}))))
|
||||
|
||||
(defn sign-in [phone-number whisper-identity]
|
||||
;; (toast (str "TODO: send number: " phone-number ", "
|
||||
;; (subs whisper-identity 0 2) ".."
|
||||
;; (subs whisper-identity (- (count whisper-identity) 2)
|
||||
;; (count whisper-identity))))
|
||||
(http-post "sign-up"
|
||||
{:phone-number phone-number
|
||||
:whisper-identity whisper-identity}
|
||||
(fn [body]
|
||||
(log body)
|
||||
(show-confirm-view))))
|
||||
|
||||
(defn identity-handler [error result]
|
||||
(if error
|
||||
(do (toast (str error))
|
||||
(.log js/console "error")
|
||||
(.log js/console error))
|
||||
(toast (str result))))
|
||||
|
||||
(defn get-identity [handler]
|
||||
(let [web3 (whisper/make-web3 ethereum-rpc-url)]
|
||||
(str (.newIdentity (whisper/whisper web3) handler))))
|
||||
|
||||
|
||||
(defn get-whisper-identity-handler [phone-number]
|
||||
(fn [identity]
|
||||
;; TODO to test newIdentity. Change to 'identity' to use saved identity.
|
||||
(if false ;; identity
|
||||
(sign-in phone-number identity)
|
||||
(get-identity (fn [error identity]
|
||||
(if (not error)
|
||||
(do (set-item "user-whisper-identity" identity)
|
||||
(swap! state/app-state assoc :user-whisper-identity identity)
|
||||
(sign-in phone-number identity))
|
||||
(toast (str "error" error))))))))
|
||||
|
||||
(defn load-user-whisper-identity [handler]
|
||||
(get-item "user-whisper-identity"
|
||||
(fn [error value]
|
||||
(if (not error)
|
||||
(let [whisper-identity (when value (str value))]
|
||||
(swap! state/app-state assoc :user-whisper-identity whisper-identity)
|
||||
(handler whisper-identity))
|
||||
(toast (str "error" error))))))
|
||||
|
||||
(defn handle-phone-number [phone-number]
|
||||
(when phone-number
|
||||
(load-user-whisper-identity (get-whisper-identity-handler phone-number))))
|
||||
|
||||
(defn save-phone-number []
|
||||
(let [phone-number (:user-phone-number @state/app-state)]
|
||||
(set-item "user-phone-number" phone-number)
|
||||
(handle-phone-number phone-number)))
|
||||
(defn sign-up []
|
||||
(let [app-state (state/state)
|
||||
phone-number (:user-phone-number app-state)
|
||||
whisper-identity (:user-whisper-identity app-state)]
|
||||
(intercom/sign-up phone-number whisper-identity show-confirm-view)))
|
||||
|
||||
(defn update-phone-number [value]
|
||||
(let [formatted (str (.getNumber (js/PhoneNumber. value country-code "international")))]
|
||||
(swap! state/app-state assoc :user-phone-number
|
||||
formatted)))
|
||||
(set-user-phone-number formatted)))
|
||||
|
||||
(defui Login
|
||||
static om/IQuery
|
||||
(query [this]
|
||||
'[:user-phone-number])
|
||||
'[:user-phone-number :user-whisper-identity])
|
||||
Object
|
||||
(render [this]
|
||||
(let [{:keys [user-phone-number]} (om/props this)
|
||||
(let [{:keys [user-phone-number user-whisper-identity]} (om/props this)
|
||||
{:keys [nav]} (om/get-computed this)]
|
||||
(reset! nav-atom nav)
|
||||
(view
|
||||
|
@ -114,13 +63,13 @@
|
|||
:fontFamily "Avenir-Roman"
|
||||
:color "#9CBFC0"}}
|
||||
user-phone-number)
|
||||
(touchable-highlight {:onPress #(save-phone-number)
|
||||
(touchable-highlight {:onPress #(sign-up)
|
||||
:style {:alignSelf "center"
|
||||
:borderRadius 7
|
||||
:backgroundColor "#E5F5F6"
|
||||
:width 100}}
|
||||
(text {:style {:marginVertical 10
|
||||
:textAlign "center"}}
|
||||
"Sign in")))))))
|
||||
"Sign up")))))))
|
||||
|
||||
(def login (om/factory Login))
|
||||
|
|
|
@ -5,16 +5,13 @@
|
|||
[natal-shell.async-storage :refer [get-item set-item]]
|
||||
[natal-shell.core :refer [with-error-view]]
|
||||
[natal-shell.alert :refer [alert]])
|
||||
(:require [clojure.string :as cstr]
|
||||
[om.next :as om :refer-macros [defui]]
|
||||
(:require [om.next :as om :refer-macros [defui]]
|
||||
[re-natal.support :as sup]
|
||||
[syng-im.protocol.web3 :as whisper]
|
||||
[messenger.state :as state]
|
||||
[messenger.android.utils :refer [log toast http-post]]
|
||||
[messenger.android.crypt :refer [encrypt]]
|
||||
[messenger.android.resources :as res]
|
||||
[messenger.android.database :as db]
|
||||
[messenger.android.contacts :as contacts]
|
||||
[messenger.utils.utils :refer [log toast]]
|
||||
[messenger.utils.resources :as res]
|
||||
[messenger.comm.intercom :as intercom :refer [set-confirmation-code]]
|
||||
[messenger.android.contacts-list :refer [contacts-list]]))
|
||||
|
||||
(def nav-atom (atom nil))
|
||||
|
@ -24,76 +21,28 @@
|
|||
(.replace @nav-atom (clj->js {:component contacts-list
|
||||
:name "contacts-list"}))))
|
||||
|
||||
(defn get-contact-name [phone-contact]
|
||||
(cstr/join " "
|
||||
(filter #(not (cstr/blank? %))
|
||||
[(:givenName phone-contact)
|
||||
(:middleName phone-contact)
|
||||
(:familyName phone-contact)])))
|
||||
(defn sync-contacts []
|
||||
(intercom/sync-contacts show-home-view))
|
||||
|
||||
(defn handle-load-contacts-identities-response [contacts-by-hash data]
|
||||
(let [contacts (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)))]
|
||||
(db/add-contacts contacts)
|
||||
(show-home-view)))
|
||||
|
||||
(defn get-contacts-by-hash [contacts]
|
||||
(let [numbers-info (reduce (fn [numbers contact]
|
||||
(into numbers
|
||||
(map (fn [c]
|
||||
{: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 send-load-contacts-identities [contacts]
|
||||
(let [contacts-by-hash (get-contacts-by-hash contacts)
|
||||
data (keys contacts-by-hash)]
|
||||
(http-post "get-contacts" {:phone-number-hashes data}
|
||||
(partial handle-load-contacts-identities-response contacts-by-hash)
|
||||
(fn [error]
|
||||
(toast (str error))))))
|
||||
|
||||
(defn load-contacts []
|
||||
(contacts/load-phone-contacts
|
||||
send-load-contacts-identities
|
||||
(fn [error]
|
||||
(toast (str error)))))
|
||||
|
||||
(defn handle-send-code-response [body]
|
||||
(defn on-send-code-response [body]
|
||||
(log body)
|
||||
(toast (if (:confirmed body)
|
||||
"Confirmed"
|
||||
"Wrong code"))
|
||||
(when (:confirmed body)
|
||||
(load-contacts)))
|
||||
;; TODO user action required
|
||||
(sync-contacts)))
|
||||
|
||||
(defn code-valid? [code]
|
||||
(= 4 (count code)))
|
||||
|
||||
(defn send-code [code]
|
||||
(when (code-valid? code)
|
||||
(http-post "sign-up-confirm"
|
||||
{:code code}
|
||||
handle-send-code-response)))
|
||||
(intercom/sign-up-confirm code on-send-code-response)))
|
||||
|
||||
(defn update-code [value]
|
||||
(let [formatted value]
|
||||
(swap! state/app-state assoc :confirmation-code formatted)))
|
||||
(set-confirmation-code formatted)))
|
||||
|
||||
(defui SignUpConfirm
|
||||
static om/IQuery
|
||||
|
@ -134,7 +83,7 @@
|
|||
:style {:alignSelf "center"
|
||||
:borderRadius 7
|
||||
:backgroundColor "#E5F5F6"
|
||||
|
||||
|
||||
:width 100}}
|
||||
(text {:style {:marginVertical 10
|
||||
:textAlign "center"}}
|
||||
|
|
|
@ -11,9 +11,44 @@
|
|||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;; 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 load-user-whisper-identity []
|
||||
(publish! :service [:user-data :user-data/load-whisper-identity 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]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
(ns messenger.comm.services
|
||||
(:require
|
||||
[syng-im.utils.logging :as log]
|
||||
[messenger.services.user-data :refer [user-data-handler]]))
|
||||
[messenger.services.user-data :refer [user-data-handler]]
|
||||
[messenger.services.server :refer [server-handler]]
|
||||
[messenger.services.contacts :refer [contacts-handler]]))
|
||||
|
||||
(defmulti service (fn [state service-id args]
|
||||
service-id))
|
||||
|
@ -10,6 +12,14 @@
|
|||
[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))
|
||||
|
||||
(defn services-handler [state service-id args]
|
||||
(log/info "handling " service-id " args = " args)
|
||||
(service state service-id args))
|
||||
(service state service-id args))
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
(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.utils.database :as db]))
|
||||
|
||||
(def fake-contacts? true)
|
||||
|
||||
(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 (generate-contact 1)
|
||||
{:name (:givenName contact)
|
||||
:photo-path (:thumbnailPath contact)
|
||||
:phone-numbers (:phoneNumbers contact)}))
|
||||
(js->clj raw-contacts :keywordize-keys true)))}))))
|
||||
ch))
|
||||
|
||||
(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)}))
|
||||
(db/get-contacts))]
|
||||
(swap! state/app-state update :contacts-ds
|
||||
#(clone-with-rows % contacts))))
|
||||
|
||||
(defn save-syng-contacts [syng-contacts]
|
||||
(db/add-contacts syng-contacts))
|
|
@ -1,16 +1,55 @@
|
|||
(ns messenger.models.user-data
|
||||
(:require-macros
|
||||
[natal-shell.async-storage :refer [get-item set-item]]
|
||||
[natal-shell.alert :refer [alert]])
|
||||
(:require [messenger.state :as state]))
|
||||
[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]]))
|
||||
|
||||
(def ethereum-rpc-url "http://localhost:8545")
|
||||
|
||||
(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
|
||||
(alert (str "error" error))
|
||||
(on-error error)
|
||||
(swap! state/app-state assoc :user-phone-number (when value
|
||||
(str value)))))))
|
||||
|
||||
(defn save-whisper-identity [identity]
|
||||
(set-item "user-whisper-identity" identity)
|
||||
(swap! state/app-state assoc :user-whisper-identity identity))
|
||||
|
||||
(defn load-whisper-identity []
|
||||
(let [ch (chan)]
|
||||
(get-item "user-whisper-identity"
|
||||
(fn [error value]
|
||||
(log (str "load whisper identity: " value))
|
||||
(put! ch
|
||||
{:error error
|
||||
:value (let [whisper-identity (when value (str value))]
|
||||
(swap! state/app-state assoc :user-whisper-identity
|
||||
whisper-identity)
|
||||
whisper-identity)})))
|
||||
ch))
|
||||
|
||||
(defn new-whisper-identity []
|
||||
(let [ch (chan)]
|
||||
(let [web3 (web3/make-web3 ethereum-rpc-url)]
|
||||
(.newIdentity (web3/whisper web3)
|
||||
(fn [error value]
|
||||
(log (str "new whisper identity: " value))
|
||||
(swap! state/app-state assoc :user-whisper-identity value)
|
||||
(put! ch {:error error
|
||||
:value value}))))
|
||||
ch))
|
||||
|
||||
(defn set-confirmation-code [code]
|
||||
(swap! state/app-state assoc :confirmation-code code))
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
(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]]
|
||||
[messenger.utils.crypt :refer [encrypt]]
|
||||
[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 (: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)
|
||||
;; TODO handle 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 "user notification: " args)
|
||||
(contacts state id args))
|
|
@ -0,0 +1,31 @@
|
|||
(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 "user notification: " args)
|
||||
(server state id args))
|
|
@ -1,15 +1,52 @@
|
|||
(ns messenger.services.user-data
|
||||
(:require [messenger.models.user-data :refer [load-phone-number]]
|
||||
(: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
|
||||
save-whisper-identity
|
||||
load-whisper-identity
|
||||
new-whisper-identity
|
||||
set-confirmation-code]]
|
||||
[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/info "handling " id "args = " args)
|
||||
(log/info "handling " id " args = " args)
|
||||
(load-phone-number))
|
||||
|
||||
(defmethod user-data :user-data/load-whisper-identity
|
||||
[state id args]
|
||||
(log/info "handling " id " args = " args)
|
||||
(go
|
||||
(let [result (<! (load-whisper-identity))]
|
||||
(if-let [error (:error result)]
|
||||
(on-error error)
|
||||
(when (not (:value result))
|
||||
(let [result (<! (new-whisper-identity))]
|
||||
(if-let [error (:error result)]
|
||||
(on-error error)
|
||||
(save-whisper-identity (:value result)))))))))
|
||||
|
||||
(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/info "user notification: " args)
|
||||
(user-data state id args))
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
[om.next :as om]
|
||||
[re-natal.support :as sup]))
|
||||
|
||||
(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
|
||||
|
@ -11,9 +15,6 @@
|
|||
:confirmation-code nil
|
||||
:channels {:pub-sub-publisher (chan)
|
||||
:pub-sub-publication nil}}))
|
||||
(def ^{:dynamic true :private true} *nav-render*
|
||||
"Flag to suppress navigator re-renders from outside om when pushing/popping."
|
||||
true)
|
||||
|
||||
(defmulti read om/dispatch)
|
||||
(defmethod read :default
|
||||
|
@ -37,4 +38,4 @@
|
|||
(def pub-sub-path [:channels :pub-sub-publication])
|
||||
(def user-notification-path [:user-notification])
|
||||
|
||||
(defn pub-sub-publisher [app] (get-in app pub-sub-bus-path))
|
||||
(defn pub-sub-publisher [app] (get-in app pub-sub-bus-path))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(ns messenger.android.crypt
|
||||
(ns messenger.utils.crypt
|
||||
(:require [goog.crypt :refer [byteArrayToHex]])
|
||||
(:import goog.crypt.Sha256))
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
(ns messenger.android.database
|
||||
(:require [messenger.android.utils :refer [log toast http-post]]))
|
||||
(ns messenger.utils.database
|
||||
(:require [messenger.utils.utils :refer [log toast http-post]]))
|
||||
|
||||
(set! js/Realm (js/require "realm"))
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
(ns messenger.android.resources)
|
||||
(ns messenger.utils.resources)
|
||||
|
||||
(def logo-icon (js/require "./images/logo.png"))
|
||||
(def nav-back-icon (js/require "./images/nav-back.png"))
|
|
@ -1,10 +1,11 @@
|
|||
(ns messenger.android.utils
|
||||
(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))
|
||||
|
@ -12,6 +13,9 @@
|
|||
(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))
|
Loading…
Reference in New Issue