parent
fe23df8662
commit
e7e623c659
|
@ -10,6 +10,7 @@
|
|||
[syng-im.components.contact-list.contact-list :refer [contact-list]]
|
||||
[syng-im.components.chat :refer [chat]]
|
||||
[syng-im.components.login :refer [login-view]]
|
||||
[syng-im.components.sign-up-confirm :refer [sign-up-confirm-view]]
|
||||
|
||||
;; [syng-im.components.chat.chat :refer [chat]]
|
||||
[syng-im.components.nav :as nav]
|
||||
|
@ -42,7 +43,7 @@
|
|||
})
|
||||
:render-scene (fn [route nav]
|
||||
(log/debug "route" route)
|
||||
(when nav/*nav-render*
|
||||
(when true ;; nav/*nav-render*
|
||||
(let [{:keys [view-id]} (js->clj route :keywordize-keys true)
|
||||
view-id (keyword view-id)]
|
||||
(init-back-button-handler! nav)
|
||||
|
@ -50,7 +51,9 @@
|
|||
:contact-list (r/as-element [contact-list
|
||||
{:navigator nav}])
|
||||
:chat (r/as-element [chat {:navigator nav}])
|
||||
:login (r/as-element [login-view {:navigator nav}])))))}])
|
||||
:login (r/as-element [login-view {:navigator nav}])
|
||||
:sign-up-confirm (r/as-element [sign-up-confirm-view
|
||||
{:navigator nav}])))))}])
|
||||
|
||||
(defn init []
|
||||
(dispatch-sync [:initialize-db])
|
||||
|
|
|
@ -6,20 +6,18 @@
|
|||
[syng-im.components.spinner :refer [spinner]]
|
||||
[syng-im.components.nav :as nav]
|
||||
[syng-im.utils.utils :refer [log toast http-post]]
|
||||
[syng-im.utils.phone-number :refer [format-phone-number]]
|
||||
;; [messenger.android.sign-up-confirm :refer [sign-up-confirm]]
|
||||
))
|
||||
[syng-im.utils.phone-number :refer [format-phone-number]]))
|
||||
|
||||
(def nav-atom (atom nil))
|
||||
;; (def nav-atom (atom nil))
|
||||
|
||||
(defn show-confirm-view []
|
||||
(defn show-confirm-view [navigator]
|
||||
(dispatch [:set-loading false])
|
||||
;; TODO 'nav-replace
|
||||
(nav/nav-push @nav-atom {:view-id :chat}))
|
||||
(nav/nav-push navigator {:view-id :sign-up-confirm}))
|
||||
|
||||
(defn sign-up [user-phone-number user-identity]
|
||||
(defn sign-up [user-phone-number user-identity navigator]
|
||||
(dispatch [:set-loading true])
|
||||
(dispatch [:sign-up user-phone-number user-identity show-confirm-view]))
|
||||
(dispatch [:sign-up user-phone-number user-identity #(show-confirm-view navigator)]))
|
||||
|
||||
(defn update-phone-number [value]
|
||||
(let [formatted (format-phone-number value)]
|
||||
|
@ -30,7 +28,7 @@
|
|||
user-phone-number (subscribe [:get-user-phone-number])
|
||||
user-identity (subscribe [:get-user-identity])]
|
||||
(fn []
|
||||
(reset! nav-atom navigator)
|
||||
;; (reset! nav-atom navigator)
|
||||
[view {:style {:flex 1}}
|
||||
[view {:style {:flex 1
|
||||
:backgroundColor "white"}}
|
||||
|
@ -53,7 +51,7 @@
|
|||
:fontFamily "Avenir-Roman"
|
||||
:color "#9CBFC0"}}
|
||||
@user-phone-number]
|
||||
[touchable-highlight {:onPress #(sign-up @user-phone-number @user-identity)
|
||||
[touchable-highlight {:onPress #(sign-up @user-phone-number @user-identity navigator)
|
||||
:style {:alignSelf "center"
|
||||
:borderRadius 7
|
||||
:backgroundColor "#E5F5F6"
|
||||
|
@ -61,6 +59,5 @@
|
|||
[text {:style {:marginVertical 10
|
||||
:textAlign "center"}}
|
||||
"Sign up"]]]]
|
||||
;; (when (or loading (not user-identity))
|
||||
;; [spinner {:visible true}])
|
||||
])))
|
||||
(when (or @loading (not @user-identity))
|
||||
[spinner {:visible true}])])))
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
(ns syng-im.components.sign-up-confirm
|
||||
(:require-macros
|
||||
[natal-shell.core :refer [with-error-view]])
|
||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||
[syng-im.components.react :refer [view text image touchable-highlight list-view
|
||||
toolbar-android text-input]]
|
||||
[syng-im.components.resources :as res]
|
||||
[syng-im.components.spinner :refer [spinner]]
|
||||
[syng-im.components.nav :as nav]
|
||||
[syng-im.utils.utils :refer [log toast http-post]]))
|
||||
|
||||
(defn show-home-view [navigator]
|
||||
(dispatch [:set-loading false])
|
||||
(nav/nav-push navigator {:view-id :contact-list}))
|
||||
|
||||
(defn sync-contacts [navigator]
|
||||
(dispatch [:sync-contacts #(show-home-view navigator)]))
|
||||
|
||||
(defn on-send-code-response [navigator body]
|
||||
(log body)
|
||||
(toast (if (:confirmed body)
|
||||
"Confirmed"
|
||||
"Wrong code"))
|
||||
(if (:confirmed body)
|
||||
;; TODO user action required
|
||||
(sync-contacts navigator)
|
||||
(dispatch [:set-loading false])))
|
||||
|
||||
(defn code-valid? [code]
|
||||
(= 4 (count code)))
|
||||
|
||||
(defn send-code [code navigator]
|
||||
(when (code-valid? code)
|
||||
(dispatch [:set-loading true])
|
||||
(dispatch [:sign-up-confirm code (partial on-send-code-response navigator)])))
|
||||
|
||||
(defn update-code [value]
|
||||
(let [formatted value]
|
||||
(dispatch [:set-confirmation-code formatted])))
|
||||
|
||||
(defn sign-up-confirm-view [{:keys [navigator]}]
|
||||
(let [loading (subscribe [:get-loading])
|
||||
confirmation-code (subscribe [:get-confirmation-code])]
|
||||
(fn []
|
||||
[view {:style {:flex 1}}
|
||||
[view {:style {:flex 1
|
||||
:backgroundColor "white"}}
|
||||
[toolbar-android {:logo res/logo-icon
|
||||
:title "Confirm"
|
||||
:titleColor "#4A5258"
|
||||
:style {:backgroundColor "white"
|
||||
:height 56
|
||||
:elevation 2}}]
|
||||
[view {}
|
||||
[text-input {:underlineColorAndroid "#9CBFC0"
|
||||
:placeholder "Enter confirmation code"
|
||||
:keyboardType "number-pad"
|
||||
:maxLength 4
|
||||
:onChangeText (fn [value]
|
||||
(update-code value))
|
||||
:style {:flex 1
|
||||
:marginHorizontal 18
|
||||
:lineHeight 42
|
||||
:fontSize 14
|
||||
:fontFamily "Avenir-Roman"
|
||||
:color "#9CBFC0"}}
|
||||
@confirmation-code]
|
||||
(if (code-valid? @confirmation-code)
|
||||
[touchable-highlight {:onPress #(send-code @confirmation-code navigator)
|
||||
:style {:alignSelf "center"
|
||||
:borderRadius 7
|
||||
:backgroundColor "#E5F5F6"
|
||||
|
||||
:width 100}}
|
||||
[text {:style {:marginVertical 10
|
||||
:textAlign "center"}}
|
||||
"Confirm"]]
|
||||
[view {:style {:alignSelf "center"
|
||||
:borderRadius 7
|
||||
:backgroundColor "#AAB2B2"
|
||||
:width 100}}
|
||||
[text {:style {:marginVertical 10
|
||||
:textAlign "center"}}
|
||||
"Confirm"]])]]
|
||||
(when @loading
|
||||
[spinner {:visible true}])])))
|
|
@ -12,6 +12,7 @@
|
|||
[syng-im.models.messages :refer [save-message
|
||||
new-message-arrived]]
|
||||
[syng-im.handlers.server :as server]
|
||||
[syng-im.handlers.contacts :as contacts-service]
|
||||
[syng-im.utils.logging :as log]))
|
||||
|
||||
;; -- Middleware ------------------------------------------------------------
|
||||
|
@ -76,6 +77,20 @@
|
|||
(server/sign-up phone-number whisper-identity handler)
|
||||
db))
|
||||
|
||||
(register-handler :set-confirmation-code
|
||||
(fn [db [_ value]]
|
||||
(assoc db :confirmation-code value)))
|
||||
|
||||
(register-handler :sign-up-confirm
|
||||
(fn [db [_ confirmation-code handler]]
|
||||
(server/sign-up-confirm confirmation-code handler)
|
||||
db))
|
||||
|
||||
(register-handler :sync-contacts
|
||||
(fn [db [_ handler]]
|
||||
(contacts-service/sync-contacts handler)
|
||||
db))
|
||||
|
||||
;; -- Contacts --------------------------------------------------------------
|
||||
|
||||
(register-handler :load-syng-contacts
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
(ns syng-im.handlers.contacts
|
||||
(:require-macros [cljs.core.async.macros :refer [go]])
|
||||
(:require [clojure.string :as cstr]
|
||||
[cljs.core.async :as async :refer [chan put! <!]]
|
||||
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||
[syng-im.utils.utils :refer [log on-error http-post toast]]
|
||||
[syng-im.utils.crypt :refer [encrypt]]
|
||||
[syng-im.utils.phone-number :refer [format-phone-number]]
|
||||
[syng-im.models.contacts :as contacts-model]
|
||||
[syng-im.utils.logging :as log]))
|
||||
|
||||
(defn- get-contact-name [phone-contact]
|
||||
(cstr/join " "
|
||||
(filter #(not (cstr/blank? %))
|
||||
[(:givenName phone-contact)
|
||||
(:middleName phone-contact)
|
||||
(:familyName phone-contact)])))
|
||||
|
||||
(defn- to-syng-contacts [contacts-by-hash data]
|
||||
(map (fn [server-contact]
|
||||
(let [number-info (get contacts-by-hash
|
||||
(:phone-number-hash server-contact))
|
||||
phone-contact (:contact number-info)]
|
||||
{:phone-number (:number number-info)
|
||||
:whisper-identity (:whisper-identity server-contact)
|
||||
:name (get-contact-name phone-contact)
|
||||
:photo-path (:photo-path phone-contact)}))
|
||||
(js->clj (:contacts data))))
|
||||
|
||||
(defn- get-contacts-by-hash [contacts]
|
||||
(let [numbers-info (reduce (fn [numbers contact]
|
||||
(into numbers
|
||||
(map (fn [c]
|
||||
{:number (format-phone-number (:number c))
|
||||
:contact contact})
|
||||
(:phone-numbers contact))))
|
||||
'()
|
||||
contacts)]
|
||||
(reduce (fn [m number-info]
|
||||
(let [number (:number number-info)
|
||||
hash (encrypt number)]
|
||||
(assoc m hash number-info)))
|
||||
{}
|
||||
numbers-info)))
|
||||
|
||||
(defn- request-syng-contacts [contacts]
|
||||
(let [contacts-by-hash (get-contacts-by-hash contacts)
|
||||
data (keys contacts-by-hash)
|
||||
ch (chan)]
|
||||
(http-post "get-contacts" {:phone-number-hashes data}
|
||||
(fn [data]
|
||||
(put! ch
|
||||
(to-syng-contacts contacts-by-hash data))))
|
||||
ch))
|
||||
|
||||
(defn sync-contacts [handler]
|
||||
(go
|
||||
(let [result (<! (contacts-model/load-phone-contacts))]
|
||||
(if-let [error (:error result)]
|
||||
(on-error error)
|
||||
(let [syng-contacts (<! (request-syng-contacts (:contacts result)))]
|
||||
(contacts-model/save-syng-contacts syng-contacts)
|
||||
(dispatch [:load-syng-contacts])
|
||||
(handler))))))
|
|
@ -8,14 +8,13 @@
|
|||
[phone-number whisper-identity handler]
|
||||
(user-data/save-phone-number phone-number)
|
||||
(http-post "sign-up" {:phone-number phone-number
|
||||
:whisper-identity whisper-identity}
|
||||
:whisper-identity (:public whisper-identity)}
|
||||
(fn [body]
|
||||
(log body)
|
||||
(handler))))
|
||||
|
||||
(defn sign-up-confirm
|
||||
[state id {:keys [confirmation-code handler] :as args}]
|
||||
(log/info "handling " id " args = " args)
|
||||
[confirmation-code handler]
|
||||
(http-post "sign-up-confirm"
|
||||
{:code confirmation-code}
|
||||
handler))
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
[syng-im.utils.utils :refer [log toast]]
|
||||
[syng-im.persistence.realm :as realm]))
|
||||
|
||||
(def fake-contacts? true)
|
||||
;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45
|
||||
(def fake-phone-contacts? true)
|
||||
(def fake-contacts? false)
|
||||
|
||||
(def react-native-contacts (js/require "react-native-contacts"))
|
||||
|
||||
|
@ -22,7 +24,7 @@
|
|||
|
||||
(defn load-phone-contacts []
|
||||
(let [ch (chan)]
|
||||
(if fake-contacts?
|
||||
(if fake-phone-contacts?
|
||||
(put! ch {:error nil, :contacts (generate-contacts 10)})
|
||||
(.getAll react-native-contacts
|
||||
(fn [error raw-contacts]
|
||||
|
@ -32,7 +34,6 @@
|
|||
(when (not error)
|
||||
(log raw-contacts)
|
||||
(map (fn [contact]
|
||||
;; (toast (str contact))
|
||||
(merge contact
|
||||
(generate-contact 1)
|
||||
{:name (:givenName contact)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
:get-user-identity
|
||||
(fn [db _]
|
||||
(reaction
|
||||
(get @db :identity))))
|
||||
(get @db :user-identity))))
|
||||
|
||||
(register-sub
|
||||
:get-loading
|
||||
|
@ -27,6 +27,12 @@
|
|||
(reaction
|
||||
(get @db :loading))))
|
||||
|
||||
(register-sub
|
||||
:get-confirmation-code
|
||||
(fn [db _]
|
||||
(reaction
|
||||
(get @db :confirmation-code))))
|
||||
|
||||
(register-sub
|
||||
:get-contacts
|
||||
(fn [db _]
|
||||
|
|
Loading…
Reference in New Issue