From a504c1b861c36602066d3e015978478470bea2ab Mon Sep 17 00:00:00 2001 From: michaelr Date: Sun, 3 Apr 2016 19:00:40 +0300 Subject: [PATCH] can create groups and send group messages Former-commit-id: a66105464e92a94dceb3712d3f6c7b37043d049c --- syng-im/src/syng_im/android/core.cljs | 3 +- syng-im/src/syng_im/components/chat.cljs | 6 +- .../components/chat/plain_message_input.cljs | 9 ++- .../syng_im/components/chats/new_group.cljs | 8 ++- syng-im/src/syng_im/db.cljs | 1 + syng-im/src/syng_im/handlers.cljs | 58 ++++++++++++++++--- syng-im/src/syng_im/models/chat.cljs | 2 + syng-im/src/syng_im/models/chats.cljs | 4 ++ syng-im/src/syng_im/models/contacts.cljs | 4 +- syng-im/src/syng_im/persistence/realm.cljs | 16 ++--- syng-im/src/syng_im/subs.cljs | 11 +++- syng-im/src/syng_im/utils/crypt.cljs | 8 +++ 12 files changed, 102 insertions(+), 28 deletions(-) diff --git a/syng-im/src/syng_im/android/core.cljs b/syng-im/src/syng_im/android/core.cljs index c7656accb9..f834a53c0c 100644 --- a/syng-im/src/syng_im/android/core.cljs +++ b/syng-im/src/syng_im/android/core.cljs @@ -34,7 +34,7 @@ (add-event-listener "hardwareBackPress" new-listener))))) (defn app-root [] - [navigator {:initial-route (clj->js {:view-id :new-group}) + [navigator {:initial-route (clj->js {:view-id :chat-list}) :render-scene (fn [route nav] (log/debug "route" route) (when true ;; nav/*nav-render* @@ -51,6 +51,7 @@ (defn init [] (dispatch-sync [:initialize-db]) + (dispatch [:initialize-crypt]) (dispatch [:initialize-protocol]) (dispatch [:load-user-phone-number]) (dispatch [:load-syng-contacts]) diff --git a/syng-im/src/syng_im/components/chat.cljs b/syng-im/src/syng_im/components/chat.cljs index 13ab983ee7..5804e557ab 100644 --- a/syng-im/src/syng_im/components/chat.cljs +++ b/syng-im/src/syng_im/components/chat.cljs @@ -19,7 +19,8 @@ (defn chat [{:keys [navigator]}] - (let [messages (subscribe [:get-chat-messages])] + (let [messages (subscribe [:get-chat-messages]) + chat (subscribe [:get-current-chat])] (fn [] (let [msgs @messages _ (log/debug "messages=" msgs) @@ -29,7 +30,8 @@ (when android? ;; TODO add IOS version [toolbar-android {:logo res/logo-icon - :title "Chat name" + :title (or (@chat :name) + "Chat name") :titleColor "#4A5258" :subtitle "Last seen just now" :subtitleColor "#AAB2B2" diff --git a/syng-im/src/syng_im/components/chat/plain_message_input.cljs b/syng-im/src/syng_im/components/chat/plain_message_input.cljs index 3a3d170c7c..df8d741cd0 100644 --- a/syng-im/src/syng_im/components/chat/plain_message_input.cljs +++ b/syng-im/src/syng_im/components/chat/plain_message_input.cljs @@ -11,8 +11,8 @@ [reagent.core :as r])) (defn plain-message-input-view [] - (let [text (r/atom "!") - chat-id (subscribe [:get-current-chat-id])] + (let [text (r/atom "!") + chat (subscribe [:get-current-chat])] (dispatch [:generate-suggestions @text]) (fn [] [view {:style {:flexDirection "column"}} @@ -42,7 +42,10 @@ (reset! text new-text) (r/flush)) :onSubmitEditing (fn [e] - (dispatch [:send-chat-msg @chat-id @text]) + (let [{:keys [group-chat chat-id]} @chat] + (if group-chat + (dispatch [:send-group-chat-msg chat-id @text]) + (dispatch [:send-chat-msg chat-id @text]))) (reset! text nil))}] [image {:source res/smile :style {:marginTop 11 diff --git a/syng-im/src/syng_im/components/chats/new_group.cljs b/syng-im/src/syng_im/components/chats/new_group.cljs index 97401387e1..c402ebd799 100644 --- a/syng-im/src/syng_im/components/chats/new_group.cljs +++ b/syng-im/src/syng_im/components/chats/new_group.cljs @@ -5,7 +5,8 @@ [syng-im.components.realm :refer [list-view]] [syng-im.utils.listview :refer [to-realm-datasource]] [syng-im.components.chats.new-group-contact :refer [new-group-contact]] - [reagent.core :as r])) + [reagent.core :as r] + [syng-im.navigation :refer [nav-pop]])) (defn new-group [{:keys [navigator]}] (let [contacts (subscribe [:all-contacts]) @@ -26,7 +27,10 @@ :icon res/v :show "always"}] :onActionSelected (fn [position] - (dispatch [:create-new-group navigator]))}]) + (dispatch [:create-new-group @group-name navigator])) + :navIcon res/nav-back-icon + :onIconClicked (fn [] + (nav-pop navigator))}]) [text-input {:underlineColorAndroid "#9CBFC0" :style {:marginLeft 5 :marginRight 5 diff --git a/syng-im/src/syng_im/db.cljs b/syng-im/src/syng_im/db.cljs index b3732ed26b..e265eb1386 100644 --- a/syng-im/src/syng_im/db.cljs +++ b/syng-im/src/syng_im/db.cljs @@ -25,3 +25,4 @@ (defn updated-chat-signal-path [chat-id] [:chats chat-id :chat-updated-signal]) (def new-group-path [:new-group]) + diff --git a/syng-im/src/syng_im/handlers.cljs b/syng-im/src/syng_im/handlers.cljs index ce37794b46..3f8f081234 100644 --- a/syng-im/src/syng_im/handlers.cljs +++ b/syng-im/src/syng_im/handlers.cljs @@ -26,7 +26,8 @@ [syng-im.utils.logging :as log] [syng-im.protocol.api :as api] [syng-im.constants :refer [text-content-type]] - [syng-im.navigation :refer [nav-push]])) + [syng-im.navigation :refer [nav-push]] + [syng-im.utils.crypt :refer [gen-random-bytes]])) ;; -- Middleware ------------------------------------------------------------ ;; @@ -52,6 +53,33 @@ (fn [db [_ value]] (assoc db :loading value))) +(register-handler :initialize-crypt + (fn [db _] + (log/debug "initializing crypt") + (gen-random-bytes 1024 (fn [{:keys [error buffer]}] + (if error + (do + (log/error "Failed to generate random bytes to initialize sjcl crypto") + (dispatch [:notify-user {:type :error + :error error}])) + (do + (->> (.toString buffer "hex") + (.toBits (.. js/ecc -sjcl -codec -hex)) + (.addEntropy (.. js/ecc -sjcl -random))) + (dispatch [:crypt-initialized]))))) + db)) + +(register-handler :crypt-initialized + (fn [db _] + (log/debug "crypt initialized") + db)) + +(register-handler :navigate-to + (fn [db [action navigator route]] + (log/debug action route) + (nav-push navigator route) + db)) + ;; -- Protocol -------------------------------------------------------------- (register-handler :initialize-protocol @@ -103,6 +131,21 @@ (save-message chat-id msg) (signal-chat-updated db chat-id)))) +(register-handler :send-group-chat-msg + (fn [db [action chat-id text]] + (log/debug action "chat-id" chat-id "text" text) + (let [{msg-id :msg-id + {from :from} :msg} (api/send-group-user-msg {:group-id chat-id + :content text}) + msg {:msg-id msg-id + :from from + :to nil + :content text + :content-type text-content-type + :outgoing true}] + (save-message chat-id msg) + (signal-chat-updated db chat-id)))) + ;; -- User data -------------------------------------------------------------- (register-handler :set-user-phone-number @@ -146,8 +189,9 @@ (register-handler :show-chat (fn [db [action chat-id navigator]] (log/debug action "chat-id" chat-id) - (nav-push navigator {:view-id :chat}) - (set-current-chat-id db chat-id))) + (let [db (set-current-chat-id db chat-id)] + (dispatch [:navigate-to navigator {:view-id :chat}]) + db))) ;; -- Chat -------------------------------------------------------------- @@ -177,20 +221,16 @@ (update-new-group-selection db identity add?))) (register-handler :create-new-group - (fn [db [action navigator]] + (fn [db [action group-name navigator]] (log/debug action) (let [identities (-> (new-group-selection db) (vec)) group-id (api/start-group-chat identities) - db (create-chat db group-id identities)] + db (create-chat db group-id identities group-name)] (dispatch [:show-chat group-id navigator]) db))) (comment - (.getProgress (.. js/ecc -sjcl -random)) - -(js/window.crypto ) - js/window ) diff --git a/syng-im/src/syng_im/models/chat.cljs b/syng-im/src/syng_im/models/chat.cljs index 732bb2c9a1..7a8b29d4ce 100644 --- a/syng-im/src/syng_im/models/chat.cljs +++ b/syng-im/src/syng_im/models/chat.cljs @@ -33,4 +33,6 @@ (swap! re-frame.db/app-db (fn [db] (signal-chat-updated db "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"))) + +(current-chat-id @re-frame.db/app-db) ) \ No newline at end of file diff --git a/syng-im/src/syng_im/models/chats.cljs b/syng-im/src/syng_im/models/chats.cljs index 3cac587328..914a1c2026 100644 --- a/syng-im/src/syng_im/models/chats.cljs +++ b/syng-im/src/syng_im/models/chats.cljs @@ -54,8 +54,12 @@ (-> (r/get-all :chats) (r/sorted :timestamp :desc))) +(defn chat-by-id [chat-id] + (-> (r/get-by-field :chats :chat-id chat-id) + (r/single-cljs))) (comment + (chat-by-id "1459693168208-31d4942e-ca3b-5c03-a397-cd7a29f777d4") (chats-list) (r/delete (chats-list)) diff --git a/syng-im/src/syng_im/models/contacts.cljs b/syng-im/src/syng_im/models/contacts.cljs index dad4c8b467..0250eb9183 100644 --- a/syng-im/src/syng_im/models/contacts.cljs +++ b/syng-im/src/syng_im/models/contacts.cljs @@ -94,12 +94,12 @@ (comment (r/write #(create-contact {:phone-number "0543072333" - :whisper-identity "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd" + :whisper-identity "0x04b6552945c18ebca487c8a829365d3812a246e1cd00d775f47248a21a61bad0912409b8bd18dc0604d1df494cea001cce85098906df231d2a431067734ecc5a21" :name "Mr. Bean" :photo-path ""})) (r/write #(create-contact {:phone-number "0544828649" - :whisper-identity "0x042fc4ef6525be53a6358da6db9d9019184e0fd04b5bd67a6faa252c3d0f4efdf57bdafc2c03b39daa2d0deabe49bb727c272c59ade8857f93a6ef27be77517e9e" + :whisper-identity "0x043d9e25c6cf89941849cf5e4439084a93002f757cfd49fef411d4793d888b408dfa5bc54ac5989f65da8d764dc332f06b646f3cfae194a0801f6090b272a0c56e" :name "Mr. Batman" :photo-path ""})) diff --git a/syng-im/src/syng_im/persistence/realm.cljs b/syng-im/src/syng_im/persistence/realm.cljs index 9a61b87d64..819c2839d9 100644 --- a/syng-im/src/syng_im/persistence/realm.cljs +++ b/syng-im/src/syng_im/persistence/realm.cljs @@ -23,7 +23,8 @@ :primaryKey :msg-id :properties {:msg-id "string" :from "string" - :to "string" + :to {:type "string" + :optional true} :content "string" ;; TODO make it ArrayBuffer :content-type "string" :timestamp "int" @@ -121,12 +122,12 @@ (write #(.create realm "msgs" (clj->js {:msg-id "12" :content "sdfd" - :from "sdfsd" - :chat-id "56" - :content-type "fg" - :timestamp 2 - :outgoing true - :to "sfs" + :from "sdfsd" + :chat-id "56" + :content-type "fg" + :timestamp 2 + :outgoing true + :to "sfs" :delivery-status "seen"}) true)) (.addListener realm "change" (fn [& args] @@ -137,5 +138,4 @@ ; ... ; }); - ) \ No newline at end of file diff --git a/syng-im/src/syng_im/subs.cljs b/syng-im/src/syng_im/subs.cljs index 55cbe86c19..20810ba6cf 100644 --- a/syng-im/src/syng_im/subs.cljs +++ b/syng-im/src/syng_im/subs.cljs @@ -5,7 +5,8 @@ [syng-im.models.chat :refer [current-chat-id chat-updated?]] [syng-im.models.chats :refer [chats-list - chats-updated?]] + chats-updated? + chat-by-id]] [syng-im.models.messages :refer [get-messages]] [syng-im.models.contacts :refer [contacts-list]])) @@ -47,6 +48,14 @@ (let [_ @chats-updated] (chats-list)))))) +(register-sub :get-current-chat + (fn [db _] + (let [current-chat-id (-> (current-chat-id @db) + (reaction))] + (-> (when-let [chat-id @current-chat-id] + (chat-by-id chat-id)) + (reaction))))) + ;; -- User data -------------------------------------------------------------- (register-sub diff --git a/syng-im/src/syng_im/utils/crypt.cljs b/syng-im/src/syng_im/utils/crypt.cljs index cb80de1a8d..ecf3ef7ff7 100644 --- a/syng-im/src/syng_im/utils/crypt.cljs +++ b/syng-im/src/syng_im/utils/crypt.cljs @@ -2,6 +2,8 @@ (:require [goog.crypt :refer [byteArrayToHex]]) (:import goog.crypt.Sha256)) +(set! js/window.RnRandomBytes (js/require "react-native-randombytes")) + (def sha-256 (Sha256.)) (defn bytes-to-str [arr] @@ -15,3 +17,9 @@ (.update sha-256 s) (-> (.digest sha-256) byteArrayToHex)) + +(defn gen-random-bytes [length cb] + (.randomBytes js/window.RnRandomBytes length (fn [& [err buf]] + (if err + (cb {:error err}) + (cb {:buffer buf})))))