From c1144e1d685e25ef33ebda2bdbf620eac302b1b2 Mon Sep 17 00:00:00 2001 From: michaelr Date: Thu, 7 Apr 2016 14:01:41 +0300 Subject: [PATCH 1/7] handle group chat invite acks Former-commit-id: ad4401a42eb4e9f2c021a92c8e8bf41a0de91906 --- src/syng_im/components/chat.cljs | 9 ++-- src/syng_im/components/chat/chat_message.cljs | 43 +++++++++---------- src/syng_im/handlers.cljs | 17 +++++++- src/syng_im/models/contacts.cljs | 4 ++ src/syng_im/protocol/protocol_handler.cljs | 4 +- 5 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/syng_im/components/chat.cljs b/src/syng_im/components/chat.cljs index 6ae060535a..8ddec07d9d 100644 --- a/src/syng_im/components/chat.cljs +++ b/src/syng_im/components/chat.cljs @@ -25,9 +25,12 @@ (into {}))) (defn add-msg-color [{:keys [from] :as msg} contact-by-identity] - (let [{:keys [text-color background-color]} (get contact-by-identity from)] - (assoc msg :text-color text-color - :background-color background-color))) + (if (= "system" from) + (assoc msg :text-color "#4A5258" + :background-color "#D3EEEF") + (let [{:keys [text-color background-color]} (get contact-by-identity from)] + (assoc msg :text-color text-color + :background-color background-color)))) (defn chat [{:keys [navigator]}] (let [messages (subscribe [:get-chat-messages]) diff --git a/src/syng_im/components/chat/chat_message.cljs b/src/syng_im/components/chat/chat_message.cljs index 8e2a3540c1..20ce00e755 100644 --- a/src/syng_im/components/chat/chat_message.cljs +++ b/src/syng_im/components/chat/chat_message.cljs @@ -86,28 +86,27 @@ content)]])) (defn message-content [{:keys [content-type content outgoing text-color background-color]}] - (let [_ (log/debug color)] - [view {:style (merge {:borderRadius 6} - (if (= content-type text-content-type) - {:paddingVertical 12 - :paddingHorizontal 16} - {:paddingVertical 14 - :paddingHorizontal 10}) - (if outgoing - {:backgroundColor "#D3EEEF"} - {:backgroundColor background-color}))} - (cond - (= content-type text-content-type) - [text {:style (merge {:fontSize 14 - :fontFamily "Avenir-Roman"} - (if outgoing - {:color "#4A5258"} - {:color text-color}))} - content] - (= content-type content-type-command) - [message-content-command content] - :else [message-content-audio {:content content - :content-type content-type}])])) + [view {:style (merge {:borderRadius 6} + (if (= content-type text-content-type) + {:paddingVertical 12 + :paddingHorizontal 16} + {:paddingVertical 14 + :paddingHorizontal 10}) + (if outgoing + {:backgroundColor "#D3EEEF"} + {:backgroundColor background-color}))} + (cond + (= content-type text-content-type) + [text {:style (merge {:fontSize 14 + :fontFamily "Avenir-Roman"} + (if outgoing + {:color "#4A5258"} + {:color text-color}))} + content] + (= content-type content-type-command) + [message-content-command content] + :else [message-content-audio {:content content + :content-type content-type}])]) (defn message-delivery-status [{:keys [delivery-status]}] [view {:style {:flexDirection "row" diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index fc462f3ea7..1d8ad2f762 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -110,6 +110,19 @@ (save-message chat-id msg) (signal-chat-updated db chat-id))) +(defn joined-chat-msg [chat-id from msg-id] + (let [contact-name (:name (contacts/contatct-by-identity from))] + (save-message chat-id {:from "system" + :msg-id msg-id + :content (str (or contact-name from) " received chat invitation") + :content-type text-content-type}))) + +(register-handler :group-chat-invite-acked + (fn [db [action from group-id ack-msg-id]] + (log/debug action from group-id ack-msg-id) + (joined-chat-msg group-id from ack-msg-id) + (signal-chat-updated db group-id))) + (register-handler :acked-msg (fn [db [_ from msg-id]] (update-message! {:msg-id msg-id @@ -128,7 +141,7 @@ (log/debug action "chat-id" chat-id "text" text) (let [msg (if (= chat-id "console") (sign-up-service/send-console-msg text) - (let [{msg-id :msg-id + (let [{msg-id :msg-id {from :from to :to} :msg} (api/send-user-msg {:to chat-id :content text})] @@ -147,7 +160,7 @@ (let [msg (if (= chat-id "console") (sign-up-service/send-console-command command content) ;; TODO handle command, now sends as plain message - (let [{msg-id :msg-id + (let [{msg-id :msg-id {from :from to :to} :msg} (api/send-user-msg {:to chat-id :content content})] diff --git a/src/syng_im/models/contacts.cljs b/src/syng_im/models/contacts.cljs index 41cbd2742e..be6c25ffc7 100644 --- a/src/syng_im/models/contacts.cljs +++ b/src/syng_im/models/contacts.cljs @@ -91,6 +91,10 @@ (-> (r/get-all :contacts) (r/sorted :name :asc))) +(defn contatct-by-identity [identity] + (-> (r/get-by-field :contacts :whisper-identity identity) + (r/single-cljs))) + (comment (r/write #(create-contact {:phone-number "0543072333" diff --git a/src/syng_im/protocol/protocol_handler.cljs b/src/syng_im/protocol/protocol_handler.cljs index 9b1ab11206..dd40a08d2c 100644 --- a/src/syng_im/protocol/protocol_handler.cljs +++ b/src/syng_im/protocol/protocol_handler.cljs @@ -28,8 +28,8 @@ payload :payload} event] (dispatch [:group-received-msg (assoc payload :from from :group-id group-id)])) - ;:group-chat-invite-acked (let [{:keys [from group-id]} event] - ; (add-to-chat "group-chat" ":" (str "Received ACK for group chat invitation from " from " for group-id: " group-id))) + :group-chat-invite-acked (let [{:keys [from group-id ack-msg-id]} event] + (dispatch [:group-chat-invite-acked from group-id ack-msg-id])) ;:group-new-participant (let [{:keys [group-id identity from]} event] ; (add-to-chat "group-chat" ":" (str (shorten from) " added " (shorten identity) " to group chat")) ; (add-identity-to-group-list identity)) From b2d53211042cac62bb9b44159be066556c1cb8f5 Mon Sep 17 00:00:00 2001 From: michaelr Date: Thu, 7 Apr 2016 14:21:02 +0300 Subject: [PATCH 2/7] add participant to group chat Former-commit-id: 19547048c322d2951b26cb89b258daf82c14666f --- images/add.png | Bin 0 -> 2068 bytes src/syng_im/android/core.cljs | 2 + src/syng_im/components/chat.cljs | 30 ++++++++------ .../components/chat/new_participants.cljs | 36 +++++++++++++++++ .../chats/new_participant_contact.cljs | 24 +++++++++++ src/syng_im/db.cljs | 6 ++- src/syng_im/handlers.cljs | 38 ++++++++++++++++-- src/syng_im/models/chat.cljs | 20 +++++++-- src/syng_im/models/chats.cljs | 24 ++++++++++- src/syng_im/models/contacts.cljs | 26 ++++++++++-- src/syng_im/models/messages.cljs | 7 +++- src/syng_im/persistence/realm.cljs | 6 ++- src/syng_im/protocol/protocol_handler.cljs | 4 +- src/syng_im/resources.cljs | 1 + src/syng_im/subs.cljs | 17 +++++++- 15 files changed, 210 insertions(+), 31 deletions(-) create mode 100644 images/add.png create mode 100644 src/syng_im/components/chat/new_participants.cljs create mode 100644 src/syng_im/components/chats/new_participant_contact.cljs diff --git a/images/add.png b/images/add.png new file mode 100644 index 0000000000000000000000000000000000000000..59eebce4046ac12c32046997ca173afae8e56f68 GIT binary patch literal 2068 zcmV+v2Ye-XX9LK-sc=GIQU{Ppdjw~pYAh#}Nrb&_d$_Nq~LJHX; zf{axrU0(PHu`FZMn+P*d3yiMhD=!pY%IxAa=mHTH(;*YV3A?D%=l>!d-saqPwzG5E z2LyLHzvp|tJLfsK-}8GYgaE_C!{qz-?-&>uK!1Nfj7B5OW;5(|JM4BlY&ILl#>T+1 zEaY-IIF19yafpeDfl{eNe0)6O>Vm;wfWctEpFe+i zi=B{=0F_DwwOWm|v@}FTMFo8wgVvzK;UJxzooH%m!rQlR;dD9!-X_B^NJ~pYPEHQe z)6*f7$%3-J0dHh@c$hqT^axL$Jb~3}4RmvEQ79D1%gcjCqX~Ey5wPH9vzgS@)#2sK zmlzux3sf^+!?G+69z2MGf&#?E!~|shc@H`i7sJ z2!(}(IC0_xFIz3+ZveB|OirCTg}%N%e?tjMZEY?3`ubotn~A@DtzQfG_V$v}(o&3! zjQA5Kq*%3T6)Gz$p;D=Q_J;O#!S?ocQe0dtDMJBZWMl-z#l`68=peqv@aflRY-}VI z6&0A8n)0>XkS8J{0v9h{L~d@b*B*Jjz~je{NmW&qw~L9El9CeS<>h(hlUKWcb8|Df zdGn@sszgpzRTWxWTfOQEmi-HKcXyMsXU_)ZnmyED7zTR19w{j)%kpbkU;6Rm2hnP^ zu-onasS`0A$Dz8q8k;t4^5~hz^Hi(VN(u`L|7k-3z;3tW(xpqVTCGH(P%LR|gr{IM zO_v!A2L9BE7>mUMlgWhk_V)jl`reWUs%Ouhk(QPgewBGaQBe`zy?eLduc)Xz3Qk7d5rJyPLdv^(tVZq(Dnc3qE}KuxK~1VE3Pznj-o6`GHp@0rYx3rlzI{P1AF_ zfdyM?TU#4`{rVL=Wg_P1&!6b%=veUn0#j>iYl9+4DlF#L98=%Fe^0)B`xZ1oQsB#% zFAMtCIi|jN@glg2B*J{(T&7yBR?^wo8FWEXprfM$R;$&uwYp4w{rYuCJ)aj7V`F1z zYio18cA47T+$@M7sWAI;o(BFVK=k(Z3MNPj^z`(=>2wlc+SIRKzlL{xKXEu5m^pKz z0U&&9j~`}yqygab=g)$QkqR>jB{Tq0yZSLlam-690YALnS|CNDFy}xK#z`&3avv@jE;_i;p>q}QBe`JS}iZJJfYQU zd2g$_x*9b#HGapj+wGu3IfYz|*lae?|9X-H-`MST-}6($xQFIAPG}91g5x;QGMP+h z9g;#WmxGbZ<-7!|sj1=R=s6pAXB2!LsRIGWaiF83qJ-8VDWamHK*zF^y;V!^OSe8X*W~S@4%T$FzL8Ygs3nEJF zWMpJu_JFlH_froYIuv|G5@5b>b4*Q1NuiRGl7cEo>}=Vx1v_`{TzViyVPRqL6iI-^ z{90gYW@cvivUQnk+_(`L85s-SUtlUt)09r93yLVQqtodye+(7iX2f4=YAUsV|Ng+M z5-|r39B^Ay!R^yjolb}FL&3$7%jGz8=8W6V-I^K`6GNRoeL5hb#7=Q>@shF z_pcns;p)|^9t{PSS(j?_=FQZ#YuEnS2ZRj6pt7=ZS(SbOFN%GorlwM5Wo14K6Dt%& zp{%S7yLRnbb`3AD64bJ@v#Imv&wH;-#GE^K4p~`QUX`T_7f^IVPzxx|(AL&Qu3Wi- z@$qqALxe0W%c8uz9DDcf^~oQepjNA?`ucjwKYsj3Zrr#bs$rQ42?;1E zDZ!2%J3^}@{cI*CCdk8w4{`tg{g58+E|bY{?AS5n=jXeg*Yicdrui5g93*vhb!cpC z45>2&mSvHfn~Q>i0<2xTRvgoO%x8Fbm^3sr;OWz+f=@_u`0!z9G#ac~vqqc~(#*%< zaFF))b~H6Lp{uJaD1(d{hQaRLyOEQVgN%#}=}eup7#53#ym|8mJv}|>?d|3DwxUw0 zgj%hJTCK*OJ$tZnclj row :keywordize-keys true) navigator])) + :style {:backgroundColor "white"}}]])))) diff --git a/src/syng_im/components/chats/new_participant_contact.cljs b/src/syng_im/components/chats/new_participant_contact.cljs new file mode 100644 index 0000000000..97985c6468 --- /dev/null +++ b/src/syng_im/components/chats/new_participant_contact.cljs @@ -0,0 +1,24 @@ +(ns syng-im.components.chats.new-participant-contact + (:require [syng-im.resources :as res] + [re-frame.core :refer [subscribe dispatch dispatch-sync]] + [syng-im.components.react :refer [view]] + [syng-im.components.contact-list.contact-inner :refer [contact-inner-view]] + [syng-im.components.item-checkbox :refer [item-checkbox]] + [syng-im.utils.logging :as log] + [reagent.core :as r])) + +(defn new-participant-contact [{:keys [whisper-identity] :as contact} navigator] + (let [checked (r/atom false)] + (fn [] + [view {:style {:flexDirection "row" + :marginTop 5 + :marginBottom 5 + :paddingLeft 15 + :paddingRight 15 + :height 75}} + [item-checkbox {:onToggle (fn [checked?] + (reset! checked checked?) + (dispatch [:select-new-participant whisper-identity checked?])) + :checked @checked + :size 30}] + [contact-inner-view contact]]))) diff --git a/src/syng_im/db.cljs b/src/syng_im/db.cljs index 3f404f3b33..b34cfcd49e 100644 --- a/src/syng_im/db.cljs +++ b/src/syng_im/db.cljs @@ -9,10 +9,11 @@ :identity-password "replace-me-with-user-entered-password" :contacts [] :chat {:current-chat-id "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd" - :command nil} + :command nil} :chats {} :chats-updated-signal 0 - :new-group #{}}) + :new-group #{} + :new-participants #{}}) (def protocol-initialized-path [:protocol-initialized]) @@ -28,3 +29,4 @@ (defn chat-command-content-path [chat-id] [:chats chat-id :command-input :content]) (def new-group-path [:new-group]) +(def new-participants-path [:new-participants]) diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index 1d8ad2f762..17f845784c 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -18,13 +18,18 @@ set-chat-command-content]] [syng-im.handlers.sign-up :as sign-up-service] - [syng-im.models.chats :refer [create-chat]] + [syng-im.models.chats :refer [create-chat + chat-add-participants]] [syng-im.models.chat :refer [signal-chat-updated set-current-chat-id + current-chat-id update-new-group-selection + update-new-participants-selection clear-new-group + clear-new-participants new-group-selection - set-chat-input-text]] + set-chat-input-text + new-participants-selection]] [syng-im.utils.logging :as log] [syng-im.protocol.api :as api] [syng-im.constants :refer [text-content-type]] @@ -124,13 +129,15 @@ (signal-chat-updated db group-id))) (register-handler :acked-msg - (fn [db [_ from msg-id]] + (fn [db [action from msg-id]] + (log/debug action from msg-id) (update-message! {:msg-id msg-id :delivery-status :delivered}) (signal-chat-updated db from))) (register-handler :msg-delivery-failed - (fn [db [_ msg-id]] + (fn [db [action msg-id]] + (log/debug action from msg-id) (update-message! {:msg-id msg-id :delivery-status :failed}) (let [{:keys [chat-id]} (message-by-id msg-id)] @@ -261,6 +268,29 @@ (nav-push navigator {:view-id :contact-list}) db)) +(register-handler :select-new-participant + (fn [db [action identity add?]] + (log/debug action identity add?) + (update-new-participants-selection db identity add?))) + +(register-handler :show-add-participants + (fn [db [action navigator]] + (log/debug action) + (nav-push navigator {:view-id :add-participants}) + (clear-new-participants db))) + +(register-handler :add-new-participants + (fn [db [action navigator]] + (log/debug action) + (let [identities (-> (new-participants-selection db) + (vec)) + chat-id (current-chat-id db)] + (chat-add-participants chat-id identities) + (dispatch [:show-chat chat-id navigator]) + (doseq [ident identities] + (api/group-add-participant chat-id ident)) + db))) + (register-handler :show-group-new (fn [db [action navigator]] (log/debug action) diff --git a/src/syng_im/models/chat.cljs b/src/syng_im/models/chat.cljs index 0abed387e5..d522c440fb 100644 --- a/src/syng_im/models/chat.cljs +++ b/src/syng_im/models/chat.cljs @@ -19,9 +19,15 @@ (defn update-new-group-selection [db identity add?] (update-in db db/new-group-path (fn [new-group] - (if add? - (conj new-group identity) - (disj new-group identity))))) + (if add? + (conj new-group identity) + (disj new-group identity))))) + +(defn update-new-participants-selection [db identity add?] + (update-in db db/new-participants-path (fn [new-participants] + (if add? + (conj new-participants identity) + (disj new-participants identity))))) (defn new-group-selection [db] (get-in db db/new-group-path)) @@ -29,6 +35,12 @@ (defn clear-new-group [db] (assoc-in db db/new-group-path #{})) +(defn new-participants-selection [db] + (get-in db db/new-participants-path)) + +(defn clear-new-participants [db] + (assoc-in db db/new-participants-path #{})) + (defn set-chat-input-text [db text] (assoc-in db (db/chat-input-text-path (current-chat-id db)) text)) @@ -37,5 +49,5 @@ (swap! re-frame.db/app-db (fn [db] (signal-chat-updated db "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"))) -(current-chat-id @re-frame.db/app-db) + (current-chat-id @re-frame.db/app-db) ) diff --git a/src/syng_im/models/chats.cljs b/src/syng_im/models/chats.cljs index 8aef29e8a0..9c3d3cfcac 100644 --- a/src/syng_im/models/chats.cljs +++ b/src/syng_im/models/chats.cljs @@ -61,8 +61,30 @@ (r/single-cljs) (r/list-to-array :contacts))) -(comment +(defn chat-add-participants [chat-id identities] + (r/write + (fn [] + (let [chat (-> (r/get-by-field :chats :chat-id chat-id) + (r/single)) + contacts (aget chat "contacts") + contacts-count (aget contacts "length") + colors (drop contacts-count group-chat-colors) + new-contacts (mapv (fn [ident {:keys [background text]}] + {:identity ident + :background-color background + :text-color text}) identities colors)] + (doseq [contact new-contacts] + (.push contacts (clj->js contact))))))) +(defn active-group-chats [] + (let [results (-> (r/get-all :chats) + (r/filtered "group-chat = true"))] + (->> (.map results (fn [object index collection] + (aget object "chat-id"))) + (js->clj)))) + +(comment + (active-group-chats) (-> (r/get-by-field :chats :chat-id "0x04ed4c3797026cddeb7d64a54ca58142e57ea03cda21072358d67455b506db90c56d95033e3d221992f70d01922c3d90bf0697c49e4be118443d03ae4a1cd3c15c") diff --git a/src/syng_im/models/contacts.cljs b/src/syng_im/models/contacts.cljs index be6c25ffc7..f3cce7ed0c 100644 --- a/src/syng_im/models/contacts.cljs +++ b/src/syng_im/models/contacts.cljs @@ -3,7 +3,8 @@ [re-frame.core :refer [subscribe dispatch dispatch-sync]] [syng-im.utils.utils :refer [log toast]] [syng-im.persistence.realm :as realm] - [syng-im.persistence.realm :as r])) + [syng-im.persistence.realm :as r] + [clojure.string :as s])) ;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45 (def fake-phone-contacts? true) @@ -91,6 +92,15 @@ (-> (r/get-all :contacts) (r/sorted :name :asc))) +(defn contacts-list-exclude [exclude-idents] + (let [exclude-query (->> exclude-idents + (map (fn [ident] + (str "whisper-identity != '" ident "'"))) + (s/join " && "))] + (-> (r/get-all :contacts) + (r/filtered exclude-query) + (r/sorted :name :asc)))) + (defn contatct-by-identity [identity] (-> (r/get-by-field :contacts :whisper-identity identity) (r/single-cljs))) @@ -98,15 +108,25 @@ (comment (r/write #(create-contact {:phone-number "0543072333" - :whisper-identity "0x04ed4c3797026cddeb7d64a54ca58142e57ea03cda21072358d67455b506db90c56d95033e3d221992f70d01922c3d90bf0697c49e4be118443d03ae4a1cd3c15c" + :whisper-identity "0x045326d94f999c3e17d11d6a09e13cf9a34b30f62687a970053887b8f8d1fefac3f185e6ba6f02f8217b6947227c7dbfa8d4ee3a4a2864b0cac9968c819ba9c17c" :name "Mr. Bean" :photo-path ""})) (r/write #(create-contact {:phone-number "0544828649" - :whisper-identity "0x0498bcce41dbe05c6d4776ef50d12c2ef1a00d9d7f7144d174ece3dce85ca3428bf0900352abcccdc463bd2cfa4ec319cda46c2079152c4cb14d1cad9a00dd7571" + :whisper-identity "0x0496152b9bb6640fddb3a156747baa961792762264ab459c8d7c9ac179ddceb2abb701357a9b6691ef858ef8ce2eb306754825b8267add96e7a01d854a576b9fda" :name "Mr. Batman" :photo-path ""})) + (r/write #(create-contact {:phone-number "0522222222" + :whisper-identity "0x04ef1f45303a14cb30af0458fabc2c7b1fd1bc9bb69fae5bb4ec63ae5b52cd53c2a194398b6674cc335899bbf6a24bfe48813a134ce9b8b85877690c1a99f0b19f" + :name "Mr. Eagle" + :photo-path ""})) + + (r/write #(create-contact {:phone-number "0533333333" + :whisper-identity "0x04e9e31a92ab16dbac9cdce47f59545ac646175087f4eeb6e4442e36d37b09e20dcb6239ac743ddd3f1fa17377c1789dc60a1ebb8774d247f3df69ebd0082d46fe" + :name "Mr. PiggyBear" + :photo-path ""})) + (contacts-list) (:new-group @re-frame.db/app-db) diff --git a/src/syng_im/models/messages.cljs b/src/syng_im/models/messages.cljs index da53dad990..9517d14783 100644 --- a/src/syng_im/models/messages.cljs +++ b/src/syng_im/models/messages.cljs @@ -7,6 +7,7 @@ (defn save-message [chat-id {:keys [from to msg-id content content-type outgoing] :or {outgoing false to nil} :as msg}] + (log/debug "save-message" chat-id msg) (when-not (r/exists? :msgs :msg-id msg-id) (r/write (fn [] @@ -28,10 +29,12 @@ (-> (r/get-by-field :msgs :msg-id msg-id) (r/single-cljs))) -(defn update-message! [msg] +(defn update-message! [{:keys [msg-id] :as msg}] + (log/debug "update-message!" msg) (r/write (fn [] - (r/create :msgs msg true)))) + (when (r/exists? :msgs :msg-id msg-id) + (r/create :msgs msg true))))) (comment diff --git a/src/syng_im/persistence/realm.cljs b/src/syng_im/persistence/realm.cljs index 694ff7af16..ec83186df7 100644 --- a/src/syng_im/persistence/realm.cljs +++ b/src/syng_im/persistence/realm.cljs @@ -41,7 +41,8 @@ :primaryKey :chat-id :properties {:chat-id "string" :name "string" - :group-chat "bool" + :group-chat {:type "bool" + :indexed true} :timestamp "int" :contacts {:type "list" :objectType "chat-contact"}}}]}) @@ -92,6 +93,9 @@ false true))) +(defn filtered [results filter-query] + (.filtered results filter-query)) + (defn page [results from to] (js/Array.prototype.slice.call results from to)) diff --git a/src/syng_im/protocol/protocol_handler.cljs b/src/syng_im/protocol/protocol_handler.cljs index dd40a08d2c..cd0c64cfa8 100644 --- a/src/syng_im/protocol/protocol_handler.cljs +++ b/src/syng_im/protocol/protocol_handler.cljs @@ -3,12 +3,14 @@ [syng-im.constants :refer [ethereum-rpc-url]] [re-frame.core :refer [dispatch]] [syng-im.models.protocol :refer [stored-identity]] - [syng-im.persistence.simple-kv-store :as kv])) + [syng-im.persistence.simple-kv-store :as kv] + [syng-im.models.chats :refer [active-group-chats]])) (defn make-handler [db] {:ethereum-rpc-url ethereum-rpc-url :identity (stored-identity db) + :active-group-ids (active-group-chats) :storage kv/kv-store :handler (fn [{:keys [event-type] :as event}] (log/info "Event:" (clj->js event)) diff --git a/src/syng_im/resources.cljs b/src/syng_im/resources.cljs index 52a956d3f6..75b8e89b19 100644 --- a/src/syng_im/resources.cljs +++ b/src/syng_im/resources.cljs @@ -13,3 +13,4 @@ (def smile (js/require "./images/smile.png")) (def att (js/require "./images/att.png")) (def v (js/require "./images/v.png")) +(def add-icon (js/require "./images/add.png")) diff --git a/src/syng_im/subs.cljs b/src/syng_im/subs.cljs index 2b13739689..083db77cea 100644 --- a/src/syng_im/subs.cljs +++ b/src/syng_im/subs.cljs @@ -8,7 +8,8 @@ chats-updated? chat-by-id]] [syng-im.models.messages :refer [get-messages]] - [syng-im.models.contacts :refer [contacts-list]] + [syng-im.models.contacts :refer [contacts-list + contacts-list-exclude]] [syng-im.handlers.suggestions :refer [get-suggestions]])) ;; -- Chat -------------------------------------------------------------- @@ -99,3 +100,17 @@ (fn [db _] (reaction (contacts-list)))) + +(register-sub :all-new-contacts + (fn [db _] + (let [current-chat-id (-> (current-chat-id @db) + (reaction)) + chat (-> (when-let [chat-id @current-chat-id] + (chat-by-id chat-id)) + (reaction))] + (reaction + (when @chat + (let [current-participants (->> @chat + :contacts + (map :identity))] + (contacts-list-exclude current-participants))))))) From 7db7f9be5d720355ecbdb95ee0064df6f1f6faa0 Mon Sep 17 00:00:00 2001 From: michaelr Date: Mon, 11 Apr 2016 16:45:01 +0300 Subject: [PATCH 3/7] participant added to chat Former-commit-id: 16f00678fa9efa89a8cb75ed0e2101f7aba9ab76 --- src/syng_im/handlers.cljs | 18 ++++++++++++++++-- src/syng_im/models/contacts.cljs | 10 +++++----- src/syng_im/protocol/protocol_handler.cljs | 5 ++--- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index 17f845784c..fb2962851b 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -116,18 +116,32 @@ (signal-chat-updated db chat-id))) (defn joined-chat-msg [chat-id from msg-id] - (let [contact-name (:name (contacts/contatct-by-identity from))] + (let [contact-name (:name (contacts/contact-by-identity from))] (save-message chat-id {:from "system" :msg-id msg-id :content (str (or contact-name from) " received chat invitation") :content-type text-content-type}))) +(defn participant-invited-to-group-msg [chat-id identity from msg-id] + (let [inviter-name (:name (contacts/contact-by-identity from)) + invitee-name (:name (contacts/contact-by-identity identity))] + (save-message chat-id {:from "system" + :msg-id msg-id + :content (str (or inviter-name from) " invited " (or invitee-name identity)) + :content-type text-content-type}))) + (register-handler :group-chat-invite-acked (fn [db [action from group-id ack-msg-id]] (log/debug action from group-id ack-msg-id) (joined-chat-msg group-id from ack-msg-id) (signal-chat-updated db group-id))) +(register-handler :participant-invited-to-group + (fn [db [action from group-id identity msg-id]] + (log/debug action msg-id from group-id identity) + (participant-invited-to-group-msg group-id identity from msg-id) + (signal-chat-updated db group-id))) + (register-handler :acked-msg (fn [db [action from msg-id]] (log/debug action from msg-id) @@ -137,7 +151,7 @@ (register-handler :msg-delivery-failed (fn [db [action msg-id]] - (log/debug action from msg-id) + (log/debug action msg-id) (update-message! {:msg-id msg-id :delivery-status :failed}) (let [{:keys [chat-id]} (message-by-id msg-id)] diff --git a/src/syng_im/models/contacts.cljs b/src/syng_im/models/contacts.cljs index f3cce7ed0c..02b501eb2a 100644 --- a/src/syng_im/models/contacts.cljs +++ b/src/syng_im/models/contacts.cljs @@ -101,29 +101,29 @@ (r/filtered exclude-query) (r/sorted :name :asc)))) -(defn contatct-by-identity [identity] +(defn contact-by-identity [identity] (-> (r/get-by-field :contacts :whisper-identity identity) (r/single-cljs))) (comment (r/write #(create-contact {:phone-number "0543072333" - :whisper-identity "0x045326d94f999c3e17d11d6a09e13cf9a34b30f62687a970053887b8f8d1fefac3f185e6ba6f02f8217b6947227c7dbfa8d4ee3a4a2864b0cac9968c819ba9c17c" + :whisper-identity "0x043e3a8344049fb48fef030084212a9d41577a5dea18aeb4c8f285c16f783aa84e43f84c32eb8601e22827b12d5f93f14e545f9023034a0521dc18484bbbc44704" :name "Mr. Bean" :photo-path ""})) (r/write #(create-contact {:phone-number "0544828649" - :whisper-identity "0x0496152b9bb6640fddb3a156747baa961792762264ab459c8d7c9ac179ddceb2abb701357a9b6691ef858ef8ce2eb306754825b8267add96e7a01d854a576b9fda" + :whisper-identity "0x04e9b01298dd12c4d8f0393d7890302b25762966d825158d1fdffe124703c0efcd7f23a6cf71c466ca50b2af3d54264ea5f224a19ba7775779c1ddbcb237258c5c" :name "Mr. Batman" :photo-path ""})) (r/write #(create-contact {:phone-number "0522222222" - :whisper-identity "0x04ef1f45303a14cb30af0458fabc2c7b1fd1bc9bb69fae5bb4ec63ae5b52cd53c2a194398b6674cc335899bbf6a24bfe48813a134ce9b8b85877690c1a99f0b19f" + :whisper-identity "0x0487954e7fa746d8cf787403c2c491aadad540b9bb1f0f7b8184792e91c33b6a394079295f5777ec6d4af9ad5ba24794b3ff1ec8be9ff6a708c85a163733192665" :name "Mr. Eagle" :photo-path ""})) (r/write #(create-contact {:phone-number "0533333333" - :whisper-identity "0x04e9e31a92ab16dbac9cdce47f59545ac646175087f4eeb6e4442e36d37b09e20dcb6239ac743ddd3f1fa17377c1789dc60a1ebb8774d247f3df69ebd0082d46fe" + :whisper-identity "0x04e43e861a6dd99ad9eee7bd58af89dcaa430188ebec8698de7b7bad54573324fff4ac5cb9bb277af317efd7abfc917b91bf48cc41e40bf70062fd79400016a1f9" :name "Mr. PiggyBear" :photo-path ""})) diff --git a/src/syng_im/protocol/protocol_handler.cljs b/src/syng_im/protocol/protocol_handler.cljs index cd0c64cfa8..24f8a564af 100644 --- a/src/syng_im/protocol/protocol_handler.cljs +++ b/src/syng_im/protocol/protocol_handler.cljs @@ -32,9 +32,8 @@ :group-id group-id)])) :group-chat-invite-acked (let [{:keys [from group-id ack-msg-id]} event] (dispatch [:group-chat-invite-acked from group-id ack-msg-id])) - ;:group-new-participant (let [{:keys [group-id identity from]} event] - ; (add-to-chat "group-chat" ":" (str (shorten from) " added " (shorten identity) " to group chat")) - ; (add-identity-to-group-list identity)) + :group-new-participant (let [{:keys [group-id identity from msg-id]} event] + (dispatch [:participant-invited-to-group from group-id identity msg-id])) ;:group-removed-participant (let [{:keys [group-id identity from]} event] ; (add-to-chat "group-chat" ":" (str (shorten from) " removed " (shorten identity) " from group chat")) ; (remove-identity-from-group-list identity)) From d0b8b20ca993f0a7752d3e28c4486cb34d5592f9 Mon Sep 17 00:00:00 2001 From: michaelr Date: Mon, 11 Apr 2016 19:20:58 +0300 Subject: [PATCH 4/7] remove participants Former-commit-id: b8ace7d0ced1469aaf064c71f06ed6994a3d987e --- src/syng_im/android/core.cljs | 2 + src/syng_im/components/chat.cljs | 6 ++- .../components/chat/remove_participants.cljs | 36 +++++++++++++ .../components/chats/chat_list_item.cljs | 2 +- src/syng_im/handlers.cljs | 50 +++++++++++++++---- src/syng_im/models/chats.cljs | 36 +++++++++---- src/syng_im/models/contacts.cljs | 15 ++++-- src/syng_im/persistence/realm.cljs | 3 +- src/syng_im/persistence/realm_queries.cljs | 19 +++++++ src/syng_im/persistence/simple_kv_store.cljs | 7 +-- src/syng_im/resources.cljs | 1 + src/syng_im/subs.cljs | 17 ++++++- 12 files changed, 162 insertions(+), 32 deletions(-) create mode 100644 src/syng_im/components/chat/remove_participants.cljs create mode 100644 src/syng_im/persistence/realm_queries.cljs diff --git a/src/syng_im/android/core.cljs b/src/syng_im/android/core.cljs index 7a29cbcc74..3ffb47945e 100644 --- a/src/syng_im/android/core.cljs +++ b/src/syng_im/android/core.cljs @@ -14,6 +14,7 @@ [syng-im.components.chats.chats-list :refer [chats-list]] [syng-im.components.chats.new-group :refer [new-group]] [syng-im.components.chat.new-participants :refer [new-participants]] + [syng-im.components.chat.remove-participants :refer [remove-participants]] [syng-im.utils.logging :as log] [syng-im.navigation :as nav] [syng-im.utils.encryption])) @@ -44,6 +45,7 @@ (init-back-button-handler! nav) (case view-id :add-participants (r/as-element [new-participants {:navigator nav}]) + :remove-participants (r/as-element [remove-participants {:navigator nav}]) :chat-list (r/as-element [chats-list {:navigator nav}]) :new-group (r/as-element [new-group {:navigator nav}]) :contact-list (r/as-element [contact-list {:navigator nav}]) diff --git a/src/syng_im/components/chat.cljs b/src/syng_im/components/chat.cljs index 709137006d..71c78f83e0 100644 --- a/src/syng_im/components/chat.cljs +++ b/src/syng_im/components/chat.cljs @@ -57,10 +57,14 @@ :elevation 2} :actions [{:title "Add Contact to chat" :icon res/add-icon + :showWithText true} + {:title "Remove Contact from chat" + :icon res/trash-icon :showWithText true}] :onActionSelected (fn [position] (case position - 0 (dispatch [:show-add-participants navigator]))) + 0 (dispatch [:show-add-participants navigator]) + 1 (dispatch [:show-remove-participants navigator]))) :onIconClicked (fn [] (nav-pop navigator))}]) [list-view {:dataSource datasource diff --git a/src/syng_im/components/chat/remove_participants.cljs b/src/syng_im/components/chat/remove_participants.cljs new file mode 100644 index 0000000000..1620ac3757 --- /dev/null +++ b/src/syng_im/components/chat/remove_participants.cljs @@ -0,0 +1,36 @@ +(ns syng-im.components.chat.remove-participants + (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] + [syng-im.resources :as res] + [syng-im.components.react :refer [view toolbar-android android? text-input]] + [syng-im.components.realm :refer [list-view]] + [syng-im.utils.listview :refer [to-realm-datasource]] + [syng-im.components.chats.new-participant-contact :refer [new-participant-contact]] + [reagent.core :as r] + [syng-im.navigation :refer [nav-pop]])) + +(defn remove-participants [{:keys [navigator]}] + (let [contacts (subscribe [:current-chat-contacts])] + (fn [] + (let [contacts-ds (to-realm-datasource @contacts)] + [view {:style {:flex 1 + :backgroundColor "white"}} + (when android? + ;; TODO add IOS version + [toolbar-android {:logo res/logo-icon + :title "Remove Participants" + :titleColor "#4A5258" + :style {:backgroundColor "white" + :height 56 + :elevation 2} + :actions [{:title "Remove" + :icon res/trash-icon + :show "always"}] + :onActionSelected (fn [position] + (dispatch [:remove-selected-participants navigator])) + :navIcon res/nav-back-icon + :onIconClicked (fn [] + (nav-pop navigator))}]) + [list-view {:dataSource contacts-ds + :renderRow (fn [row section-id row-id] + (r/as-element [new-participant-contact (js->clj row :keywordize-keys true) navigator])) + :style {:backgroundColor "white"}}]])))) diff --git a/src/syng_im/components/chats/chat_list_item.cljs b/src/syng_im/components/chats/chat_list_item.cljs index 0a7c3e3902..3f1d76fd3d 100644 --- a/src/syng_im/components/chats/chat_list_item.cljs +++ b/src/syng_im/components/chats/chat_list_item.cljs @@ -9,7 +9,7 @@ (defn chat-list-item [chat-obj navigator] [touchable-highlight {:on-press (fn [] - (dispatch [:show-chat (aget chat-obj "chat-id") navigator]))} + (dispatch [:show-chat (aget chat-obj "chat-id") navigator :push]))} [view {:style {:flexDirection "row" :width 260 :marginVertical 5}} diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index fb2962851b..a30f0bc35a 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -19,7 +19,8 @@ [syng-im.handlers.sign-up :as sign-up-service] [syng-im.models.chats :refer [create-chat - chat-add-participants]] + chat-add-participants + chat-remove-participants]] [syng-im.models.chat :refer [signal-chat-updated set-current-chat-id current-chat-id @@ -33,8 +34,11 @@ [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.utils.crypt :refer [gen-random-bytes]])) + [syng-im.navigation :refer [nav-push + nav-replace + nav-pop]] + [syng-im.utils.crypt :refer [gen-random-bytes]] + [syng-im.utils.random :as random])) ;; -- Middleware ------------------------------------------------------------ ;; @@ -82,9 +86,11 @@ db)) (register-handler :navigate-to - (fn [db [action navigator route]] + (fn [db [action navigator route nav-type]] (log/debug action route) - (nav-push navigator route) + (case nav-type + :push (nav-push navigator route) + :replace (nav-replace navigator route)) db)) ;; -- Protocol -------------------------------------------------------------- @@ -130,6 +136,13 @@ :content (str (or inviter-name from) " invited " (or invitee-name identity)) :content-type text-content-type}))) +(defn removed-participant-msg [chat-id identity] + (let [contact-name (:name (contacts/contact-by-identity identity))] + (save-message chat-id {:from "system" + :msg-id (random/id) + :content (str "You've removed " (or contact-name identity)) + :content-type text-content-type}))) + (register-handler :group-chat-invite-acked (fn [db [action from group-id ack-msg-id]] (log/debug action from group-id ack-msg-id) @@ -250,10 +263,10 @@ ;; -- Chats -------------------------------------------------------------- (register-handler :show-chat - (fn [db [action chat-id navigator]] + (fn [db [action chat-id navigator nav-type]] (log/debug action "chat-id" chat-id) (let [db (set-current-chat-id db chat-id)] - (dispatch [:navigate-to navigator {:view-id :chat}]) + (dispatch [:navigate-to navigator {:view-id :chat} nav-type]) db))) (register-handler :set-sign-up-chat @@ -287,6 +300,25 @@ (log/debug action identity add?) (update-new-participants-selection db identity add?))) +(register-handler :show-remove-participants + (fn [db [action navigator]] + (log/debug action) + (nav-push navigator {:view-id :remove-participants}) + (clear-new-participants db))) + +(register-handler :remove-selected-participants + (fn [db [action navigator]] + (log/debug action) + (let [identities (-> (new-participants-selection db) + (vec)) + chat-id (current-chat-id db)] + (chat-remove-participants chat-id identities) + (nav-pop navigator) + (doseq [ident identities] + (api/group-remove-participant chat-id ident) + (removed-participant-msg chat-id ident)) + (signal-chat-updated db chat-id)))) + (register-handler :show-add-participants (fn [db [action navigator]] (log/debug action) @@ -300,7 +332,7 @@ (vec)) chat-id (current-chat-id db)] (chat-add-participants chat-id identities) - (dispatch [:show-chat chat-id navigator]) + (nav-pop navigator) (doseq [ident identities] (api/group-add-participant chat-id ident)) db))) @@ -323,7 +355,7 @@ (vec)) group-id (api/start-group-chat identities group-name) db (create-chat db group-id identities true group-name)] - (dispatch [:show-chat group-id navigator]) + (dispatch [:show-chat group-id navigator :replace]) db))) (register-handler :group-chat-invite-received diff --git a/src/syng_im/models/chats.cljs b/src/syng_im/models/chats.cljs index 9c3d3cfcac..13c36096cd 100644 --- a/src/syng_im/models/chats.cljs +++ b/src/syng_im/models/chats.cljs @@ -4,7 +4,8 @@ [clojure.string :refer [join blank?]] [syng-im.db :as db] [syng-im.utils.logging :as log] - [syng-im.constants :refer [group-chat-colors]])) + [syng-im.constants :refer [group-chat-colors]] + [syng-im.persistence.realm-queries :refer [include-query]])) (defn signal-chats-updated [db] (update-in db db/updated-chats-signal-path (fn [current] @@ -64,18 +65,33 @@ (defn chat-add-participants [chat-id identities] (r/write (fn [] - (let [chat (-> (r/get-by-field :chats :chat-id chat-id) - (r/single)) - contacts (aget chat "contacts") - contacts-count (aget contacts "length") - colors (drop contacts-count group-chat-colors) - new-contacts (mapv (fn [ident {:keys [background text]}] - {:identity ident - :background-color background - :text-color text}) identities colors)] + (let [contacts (-> (r/get-by-field :chats :chat-id chat-id) + (r/single) + (aget "contacts")) + colors-in-use (->> (.map contacts (fn [object index collection] + {:text-color (aget object "text-color") + :background-color (aget object "background-color")})) + (set)) + colors (->> group-chat-colors + (filter (fn [color] + (not (contains? colors-in-use color))))) + new-contacts (mapv (fn [ident {:keys [background text]}] + {:identity ident + :background-color background + :text-color text}) identities colors)] (doseq [contact new-contacts] (.push contacts (clj->js contact))))))) +(defn chat-remove-participants [chat-id identities] + (r/write + (fn [] + (let [query (include-query :identity identities) + chat (-> (r/get-by-field :chats :chat-id chat-id) + (r/single))] + (-> (aget chat "contacts") + (r/filtered query) + (r/delete)))))) + (defn active-group-chats [] (let [results (-> (r/get-all :chats) (r/filtered "group-chat = true"))] diff --git a/src/syng_im/models/contacts.cljs b/src/syng_im/models/contacts.cljs index 02b501eb2a..478f1a5e0e 100644 --- a/src/syng_im/models/contacts.cljs +++ b/src/syng_im/models/contacts.cljs @@ -4,6 +4,8 @@ [syng-im.utils.utils :refer [log toast]] [syng-im.persistence.realm :as realm] [syng-im.persistence.realm :as r] + [syng-im.persistence.realm-queries :refer [include-query + exclude-query]] [clojure.string :as s])) ;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45 @@ -93,12 +95,15 @@ (r/sorted :name :asc))) (defn contacts-list-exclude [exclude-idents] - (let [exclude-query (->> exclude-idents - (map (fn [ident] - (str "whisper-identity != '" ident "'"))) - (s/join " && "))] + (let [query (exclude-query :whisper-identity exclude-idents)] (-> (r/get-all :contacts) - (r/filtered exclude-query) + (r/filtered query) + (r/sorted :name :asc)))) + +(defn contacts-list-include [include-indents] + (let [query (include-query :whisper-identity include-indents)] + (-> (r/get-all :contacts) + (r/filtered query) (r/sorted :name :asc)))) (defn contact-by-identity [identity] diff --git a/src/syng_im/persistence/realm.cljs b/src/syng_im/persistence/realm.cljs index ec83186df7..3020efeb31 100644 --- a/src/syng_im/persistence/realm.cljs +++ b/src/syng_im/persistence/realm.cljs @@ -115,8 +115,7 @@ (read-string value)) (defn delete [obj] - (write (fn [] - (.delete realm obj)))) + (.delete realm obj)) (defn exists? [schema-name field value] (> (.-length (get-by-field schema-name field value)) diff --git a/src/syng_im/persistence/realm_queries.cljs b/src/syng_im/persistence/realm_queries.cljs new file mode 100644 index 0000000000..3b8309b329 --- /dev/null +++ b/src/syng_im/persistence/realm_queries.cljs @@ -0,0 +1,19 @@ +(ns syng-im.persistence.realm-queries + (:require [clojure.string :as s] + [syng-im.utils.types :refer [to-string]])) + +(defn include-query [field-name values] + (->> values + (map (fn [val] + (str (to-string field-name) " == " (if (string? val) + (str "'" val "'") + val)))) + (s/join " || "))) + +(defn exclude-query [field-name values] + (->> values + (map (fn [val] + (str (to-string field-name) " != " (if (string? val) + (str "'" val "'") + val)))) + (s/join " && "))) \ No newline at end of file diff --git a/src/syng_im/persistence/simple_kv_store.cljs b/src/syng_im/persistence/simple_kv_store.cljs index 15ea802465..3781154d60 100644 --- a/src/syng_im/persistence/simple_kv_store.cljs +++ b/src/syng_im/persistence/simple_kv_store.cljs @@ -17,8 +17,9 @@ (contains-key? [_ key] (r/exists? :kv-store :key key)) (delete [_ key] - (-> (r/get-by-field :kv-store :key key) - (r/single) - (r/delete)))) + (r/write (fn [] + (-> (r/get-by-field :kv-store :key key) + (r/single) + (r/delete)))))) (def kv-store (->SimpleKvStore)) diff --git a/src/syng_im/resources.cljs b/src/syng_im/resources.cljs index 75b8e89b19..aa3b31e2e1 100644 --- a/src/syng_im/resources.cljs +++ b/src/syng_im/resources.cljs @@ -14,3 +14,4 @@ (def att (js/require "./images/att.png")) (def v (js/require "./images/v.png")) (def add-icon (js/require "./images/add.png")) +(def trash-icon (js/require "./images/trash.png")) diff --git a/src/syng_im/subs.cljs b/src/syng_im/subs.cljs index 083db77cea..7718291632 100644 --- a/src/syng_im/subs.cljs +++ b/src/syng_im/subs.cljs @@ -9,7 +9,8 @@ chat-by-id]] [syng-im.models.messages :refer [get-messages]] [syng-im.models.contacts :refer [contacts-list - contacts-list-exclude]] + contacts-list-exclude + contacts-list-include]] [syng-im.handlers.suggestions :refer [get-suggestions]])) ;; -- Chat -------------------------------------------------------------- @@ -114,3 +115,17 @@ :contacts (map :identity))] (contacts-list-exclude current-participants))))))) + +(register-sub :current-chat-contacts + (fn [db _] + (let [current-chat-id (-> (current-chat-id @db) + (reaction)) + chat (-> (when-let [chat-id @current-chat-id] + (chat-by-id chat-id)) + (reaction))] + (reaction + (when @chat + (let [current-participants (->> @chat + :contacts + (map :identity))] + (contacts-list-include current-participants))))))) From 16bf960e3c372a83834777ce32c22f5c42090789 Mon Sep 17 00:00:00 2001 From: michaelr Date: Mon, 11 Apr 2016 19:44:02 +0300 Subject: [PATCH 5/7] participant removed from chat Former-commit-id: 2da99899ccadb85c3ce237fef3deb1dda2e54093 --- images/trash.png | Bin 0 -> 1923 bytes src/syng_im/handlers.cljs | 15 +++++++++++++++ src/syng_im/protocol/protocol_handler.cljs | 5 ++--- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 images/trash.png diff --git a/images/trash.png b/images/trash.png new file mode 100644 index 0000000000000000000000000000000000000000..0d83bb9685f406964f478a24185b9bf19043d3e6 GIT binary patch literal 1923 zcmV-}2YmR6P)u&Ni=Z*3sEDX(Xt_N=?`G#A8=vf zM~o2-A8|wY39MWjmPS^@7@J^a!BP@8xBx;hF<3~-xRUpsVcO2zkLTW*&e_d`xzD|a zGv_|{xicLDicqiDowckh>PY03@&03SboJa_K(>(^u?132M1l}ynT}e5~BC__g%+Vu3VuA>x+?*5!bP|Z?Zr_^q)U}T*tB|z98_% zmbFmwf`sS<3DIOoh$ccpG!YV_iC{c=^2CuHWPN?zbzCl&F*Y_PJFG9ZwzhC^aNs&u ztJS2(H6|t|q!XPWu?{jML=zz)nh0$RJMZ7Wciz5zOWBvmqgt(Ed3o8F)3%Dfc=4jV z9>o-$IBQFEsZ^5EnK+{pXNjT(B2hFEm=s+o6ku7Fln%ueOo}#5)9CN-m(roQf=SUp z;?rTlq-Y@V>9Al{bh%s>-kG=}lgXg3udnR_u;T+Xq7?n<(JQ|3=plA{P+~401(=@yOBnFwH zy{*I<8rVP(_O% zI>|Z$AeBlP`Fx(MLvhVIgen>kU+>UC(b{=5z;7Q())5e*6|Exc5WNF#nr7g7JsHtn zKeQ~%$Ye5HZH9r29q^!a4nU!G0JJ{sXH~q44#SBu>i}qpma#D#hLfIAv<#xPRJ5NT zMxAIa745eQqfGI7#-mj$+Ap2t%{rtgnwMxlMXSy_cxxR}h)$=|2G6bDYPE2DeC*l@ zSLxBsX45%6J>_asigf_du6L-cMFSy;=A95#R`68TIRIist9-FjM&&NdbBRh7O<7nH zT~I0(i?D4w@Fz}`dbCPKQ>JzRv7+NN8HVK|$vPMzRnekXhY8Vw8uubjS%=mh9jB}# zQXZXT9c_@!W(^({#%VH?s%U^u)hdY=Z5>h-4eagb&t?Jnh(a&^fujtd$Q#6}R@||$M9dO5C|BR#diU!oI4n@BtM55@vzCNyB z_|k!B>g6}U_&r0BnTLw3gL?T5FcQu4*$@@4ScoQ?W&GrdR`FtIBt064Ua3^%i=4S! z4(W6{RGkCRz@wvgLczF2i`1kMMXfzsK zugm3fxPAM!>)gi1Mj&0Nd(7bj0R#rRkD0+K) zn`w|oM@Lv+UuTLL9vjjVyS^%uMv? z=%`Vv)tCcE4TVAhGcz;H*K>VC@9ER0%$^k`7>0pYuU?^8EHc>!z)AGLz<{y5yd3L^ z(XuQ&d-e>qT8)`xfU&6L#qRE|v#_v$FJHchXiggp4-ez{^XIs8=MFbdLWur{Z{NN- zA3l6QqtU?L-kz{e*ij*sN}*gXa-kp9 Date: Mon, 11 Apr 2016 22:57:20 +0300 Subject: [PATCH 6/7] removed from chat & leave chat Former-commit-id: dd4f55e11fd40793796f6d51f8c5f170a234f729 --- images/leave.png | Bin 0 -> 1719 bytes src/syng_im/components/chat.cljs | 23 +++++++++------ src/syng_im/handlers.cljs | 32 ++++++++++++++++++++- src/syng_im/models/chats.cljs | 10 ++++++- src/syng_im/persistence/realm.cljs | 19 +----------- src/syng_im/protocol/protocol_handler.cljs | 4 +-- src/syng_im/resources.cljs | 1 + src/syng_im/subs.cljs | 9 ++++-- 8 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 images/leave.png diff --git a/images/leave.png b/images/leave.png new file mode 100644 index 0000000000000000000000000000000000000000..17df8fc16bf09fda32bfbcfafa89f086e86d9e09 GIT binary patch literal 1719 zcmV;o21xmdP)Pe>F|9LK*iYyN9#QOxM13ppDk)J2epK)hs!{#+C#MbhXH zHE5*Ugr#*G0qDot@d;H*emy z?{jp1``&No5bS$(`=O491;D!F&>9@^X6 z@$1(wt8+@p!omX8@`Ax2nVp@5rfG1y-DqxZ=C-98N}8CMARQeY`0?Whi+ps6Mx)fq z@_N0btE=muOS9MO#k+U!$i991xDzGo9f-wZWO#U(jE#-iE(ieD*Vn0(Gd(>`#>dCE z^_?p#E4X;^A_9Q`-AB+Z zNF)qncoX$cCwc$=ee&SJgRBa2I-PL2TvU?UiX=&>t*yntzyPYNt8?zu4<9~k`oz0j zF5J3x3w3pMwhku#R_^!vNl#A?e*gY$>VrJ9g~A$jAt;T)83@ zf}l<8?xSP?n3$L_6@2~rb+oj!6pWm$*eOc>_U#*a@#2MH;Much(bUvbkb*X`OO!k} zH)l93-Me=$Iy*ZVrNlROh?33pMcv)qC@Co^=vK59)}rKKFql3-mT~mxQ5L!66)Z)` zpFVv`8=xo(TrQVrMJZqg(%r*381pF(yF@u8>|*(IR8&;iQs?7 zN>Rc9MK(n(FE3LSB_vTM91cTORjQ(dBnzM|N=UK@nxcdx3!x<{qaR1+N+1v* zpeYEjp-=kXxq9^~PMkPFwciyji6T}A0sy(VxHxSGjYk=fTbV+klk*#R99DL762-uKRT3RYyxNyPL z2O^OO1_uYBsw(mMe54SD=XMGLk~UuK@9!r*pD&{VcJAB>kH>?`%1Z3owTo(U08m_9 z43Ecy=H_M;6%{evcoDE)5Rf#%Ix;eX?(S}U{`}c=0j%z$-oAZnc^%2{AP7jBV6CXA zkZ#_*38&L(S3bI!*)7csl4S0j^CAdHF$=CJ3YVfHkqDJ?%K_JNWYD3!AJ`VCFu~3}t0y($Aki$>Yb5F*7rRNF)Nc+l}`2 zcGTC`b0-K$8iJ=|eSMugefktno;*Py5U?_*lr%LpVRUqq%adp|e*mED3f91&kwE|e N002ovPDHLkV1l#&CsF_a literal 0 HcmV?d00001 diff --git a/src/syng_im/components/chat.cljs b/src/syng_im/components/chat.cljs index 71c78f83e0..18efbb4b3b 100644 --- a/src/syng_im/components/chat.cljs +++ b/src/syng_im/components/chat.cljs @@ -55,16 +55,22 @@ :style {:backgroundColor "white" :height 56 :elevation 2} - :actions [{:title "Add Contact to chat" - :icon res/add-icon - :showWithText true} - {:title "Remove Contact from chat" - :icon res/trash-icon - :showWithText true}] + :actions (when (and (:group-chat @chat) + (:is-active @chat)) + [{:title "Add Contact to chat" + :icon res/add-icon + :showWithText true} + {:title "Remove Contact from chat" + :icon res/trash-icon + :showWithText true} + {:title "Leave Chat" + :icon res/leave-icon + :showWithText true}]) :onActionSelected (fn [position] (case position 0 (dispatch [:show-add-participants navigator]) - 1 (dispatch [:show-remove-participants navigator]))) + 1 (dispatch [:show-remove-participants navigator]) + 2 (dispatch [:leave-group-chat navigator]))) :onIconClicked (fn [] (nav-pop navigator))}]) [list-view {:dataSource datasource @@ -75,4 +81,5 @@ (add-msg-color contact-by-identity))] (r/as-element [chat-message msg]))) :style {:backgroundColor "white"}}] - [chat-message-new]])))) + (when (:is-active @chat) + [chat-message-new])])))) diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index 882653c19f..a4b6878830 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -20,7 +20,8 @@ [syng-im.models.chats :refer [create-chat chat-add-participants - chat-remove-participants]] + chat-remove-participants + set-chat-active]] [syng-im.models.chat :refer [signal-chat-updated set-current-chat-id current-chat-id @@ -144,6 +145,13 @@ :content (str (or remover-name from) " removed " (or removed-name identity)) :content-type text-content-type}))) +(defn you-removed-from-group-msg [chat-id from msg-id] + (let [remover-name (:name (contacts/contact-by-identity from))] + (save-message chat-id {:from "system" + :msg-id msg-id + :content (str (or remover-name from) " removed you from group chat") + :content-type text-content-type}))) + (defn removed-participant-msg [chat-id identity] (let [contact-name (:name (contacts/contact-by-identity identity))] (save-message chat-id {:from "system" @@ -151,6 +159,12 @@ :content (str "You've removed " (or contact-name identity)) :content-type text-content-type}))) +(defn left-chat-msg [chat-id] + (save-message chat-id {:from "system" + :msg-id (random/id) + :content "You left this chat" + :content-type text-content-type})) + (register-handler :group-chat-invite-acked (fn [db [action from group-id ack-msg-id]] (log/debug action from group-id ack-msg-id) @@ -164,6 +178,13 @@ (participant-removed-from-group-msg group-id identity from msg-id) (signal-chat-updated db group-id))) +(register-handler :you-removed-from-group + (fn [db [action from group-id msg-id]] + (log/debug action msg-id from group-id) + (you-removed-from-group-msg group-id from msg-id) + (set-chat-active group-id false) + (signal-chat-updated db group-id))) + (register-handler :participant-invited-to-group (fn [db [action from group-id identity msg-id]] (log/debug action msg-id from group-id identity) @@ -203,6 +224,15 @@ (save-message chat-id msg) (signal-chat-updated db chat-id)))) +(register-handler :leave-group-chat + (fn [db [action navigator]] + (log/debug action) + (let [chat-id (current-chat-id db)] + (api/leave-group-chat chat-id) + (set-chat-active chat-id false) + (left-chat-msg chat-id) + (signal-chat-updated db chat-id)))) + (register-handler :send-chat-command (fn [db [action chat-id command content]] (log/debug action "chat-id" chat-id "command" command "content" content) diff --git a/src/syng_im/models/chats.cljs b/src/syng_im/models/chats.cljs index 13c36096cd..12caa0ecce 100644 --- a/src/syng_im/models/chats.cljs +++ b/src/syng_im/models/chats.cljs @@ -47,6 +47,7 @@ :background-color background :text-color text}) identities group-chat-colors)] (r/create :chats {:chat-id chat-id + :is-active true :name chat-name :group-chat group-chat? :timestamp (timestamp) @@ -94,11 +95,18 @@ (defn active-group-chats [] (let [results (-> (r/get-all :chats) - (r/filtered "group-chat = true"))] + (r/filtered "group-chat = true && is-active = true"))] (->> (.map results (fn [object index collection] (aget object "chat-id"))) (js->clj)))) + +(defn set-chat-active [chat-id active?] + (r/write (fn [] + (-> (r/get-by-field :chats :chat-id chat-id) + (r/single) + (aset "is-active" active?))))) + (comment (active-group-chats) diff --git a/src/syng_im/persistence/realm.cljs b/src/syng_im/persistence/realm.cljs index 3020efeb31..e6fd6990e5 100644 --- a/src/syng_im/persistence/realm.cljs +++ b/src/syng_im/persistence/realm.cljs @@ -43,6 +43,7 @@ :name "string" :group-chat {:type "bool" :indexed true} + :is-active "bool" :timestamp "int" :contacts {:type "list" :objectType "chat-contact"}}}]}) @@ -130,22 +131,4 @@ (comment - (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" - :delivery-status "seen"}) true)) - - (.addListener realm "change" (fn [& args] - (log/debug args))) - - ;realm.addListener('change', () => { - ; // Update UI - ; ... - ; }); - ) \ No newline at end of file diff --git a/src/syng_im/protocol/protocol_handler.cljs b/src/syng_im/protocol/protocol_handler.cljs index 2eacd6f4a7..c6556b4864 100644 --- a/src/syng_im/protocol/protocol_handler.cljs +++ b/src/syng_im/protocol/protocol_handler.cljs @@ -36,8 +36,8 @@ (dispatch [:participant-invited-to-group from group-id identity msg-id])) :group-removed-participant (let [{:keys [group-id identity from msg-id]} event] (dispatch [:participant-removed-from-group from group-id identity msg-id])) - ;:removed-from-group (let [{:keys [group-id from]} event] - ; (add-to-chat "group-chat" ":" (str (shorten from) " removed you from group chat"))) + :removed-from-group (let [{:keys [group-id from msg-id]} event] + (dispatch [:you-removed-from-group from group-id msg-id])) ;:participant-left-group (let [{:keys [group-id from]} event] ; (add-to-chat "group-chat" ":" (str (shorten from) " left group chat"))) ;(add-to-chat "chat" ":" (str "Don't know how to handle " event-type)) diff --git a/src/syng_im/resources.cljs b/src/syng_im/resources.cljs index aa3b31e2e1..956fd46c28 100644 --- a/src/syng_im/resources.cljs +++ b/src/syng_im/resources.cljs @@ -15,3 +15,4 @@ (def v (js/require "./images/v.png")) (def add-icon (js/require "./images/add.png")) (def trash-icon (js/require "./images/trash.png")) +(def leave-icon (js/require "./images/leave.png")) diff --git a/src/syng_im/subs.cljs b/src/syng_im/subs.cljs index 7718291632..7239a549b3 100644 --- a/src/syng_im/subs.cljs +++ b/src/syng_im/subs.cljs @@ -60,10 +60,13 @@ (register-sub :get-current-chat (fn [db _] (let [current-chat-id (-> (current-chat-id @db) + (reaction)) + chat-updated (-> (chat-updated? @db @current-chat-id) (reaction))] - (-> (when-let [chat-id @current-chat-id] - (chat-by-id chat-id)) - (reaction))))) + (reaction + (let [_ @chat-updated] + (when-let [chat-id @current-chat-id] + (chat-by-id chat-id))))))) ;; -- User data -------------------------------------------------------------- From a31231554ee524dd630740490bf240df81479aab Mon Sep 17 00:00:00 2001 From: michaelr Date: Mon, 11 Apr 2016 23:12:47 +0300 Subject: [PATCH 7/7] participant left group Former-commit-id: 49645421460dfb1a1658d5b7b96f1feb325cff36 --- src/syng_im/handlers.cljs | 13 +++++++++++++ src/syng_im/protocol/protocol_handler.cljs | 8 +++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index a4b6878830..76077ab3b6 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -152,6 +152,13 @@ :content (str (or remover-name from) " removed you from group chat") :content-type text-content-type}))) +(defn participant-left-group-msg [chat-id from msg-id] + (let [left-name (:name (contacts/contact-by-identity from))] + (save-message chat-id {:from "system" + :msg-id msg-id + :content (str (or left-name from) " left") + :content-type text-content-type}))) + (defn removed-participant-msg [chat-id identity] (let [contact-name (:name (contacts/contact-by-identity identity))] (save-message chat-id {:from "system" @@ -185,6 +192,12 @@ (set-chat-active group-id false) (signal-chat-updated db group-id))) +(register-handler :participant-left-group + (fn [db [action from group-id msg-id]] + (log/debug action msg-id from group-id) + (participant-left-group-msg group-id from msg-id) + (signal-chat-updated db group-id))) + (register-handler :participant-invited-to-group (fn [db [action from group-id identity msg-id]] (log/debug action msg-id from group-id identity) diff --git a/src/syng_im/protocol/protocol_handler.cljs b/src/syng_im/protocol/protocol_handler.cljs index c6556b4864..8bb19c8f09 100644 --- a/src/syng_im/protocol/protocol_handler.cljs +++ b/src/syng_im/protocol/protocol_handler.cljs @@ -38,8 +38,6 @@ (dispatch [:participant-removed-from-group from group-id identity msg-id])) :removed-from-group (let [{:keys [group-id from msg-id]} event] (dispatch [:you-removed-from-group from group-id msg-id])) - ;:participant-left-group (let [{:keys [group-id from]} event] - ; (add-to-chat "group-chat" ":" (str (shorten from) " left group chat"))) - ;(add-to-chat "chat" ":" (str "Don't know how to handle " event-type)) - (log/info "Don't know how to handle" event-type) - ))}) + :participant-left-group (let [{:keys [group-id from msg-id]} event] + (dispatch [:participant-left-group from group-id msg-id])) + (log/info "Don't know how to handle" event-type)))})