parent
c1144e1d68
commit
b2d5321104
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -13,6 +13,7 @@
|
|||
[syng-im.components.sign-up-confirm :refer [sign-up-confirm-view]]
|
||||
[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.utils.logging :as log]
|
||||
[syng-im.navigation :as nav]
|
||||
[syng-im.utils.encryption]))
|
||||
|
@ -42,6 +43,7 @@
|
|||
view-id (keyword view-id)]
|
||||
(init-back-button-handler! nav)
|
||||
(case view-id
|
||||
:add-participants (r/as-element [new-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}])
|
||||
|
|
|
@ -45,18 +45,24 @@
|
|||
:backgroundColor "#eef2f5"}}
|
||||
(when android?
|
||||
;; TODO add IOS version
|
||||
[toolbar-android {:logo res/logo-icon
|
||||
:title (or (@chat :name)
|
||||
"Chat name")
|
||||
:titleColor "#4A5258"
|
||||
:subtitle "Last seen just now"
|
||||
:subtitleColor "#AAB2B2"
|
||||
:navIcon res/nav-back-icon
|
||||
:style {:backgroundColor "white"
|
||||
:height 56
|
||||
:elevation 2}
|
||||
:onIconClicked (fn []
|
||||
(nav-pop navigator))}])
|
||||
[toolbar-android {:logo res/logo-icon
|
||||
:title (or (@chat :name)
|
||||
"Chat name")
|
||||
:titleColor "#4A5258"
|
||||
:subtitle "Last seen just now"
|
||||
:subtitleColor "#AAB2B2"
|
||||
:navIcon res/nav-back-icon
|
||||
:style {:backgroundColor "white"
|
||||
:height 56
|
||||
:elevation 2}
|
||||
:actions [{:title "Add Contact to chat"
|
||||
:icon res/add-icon
|
||||
:showWithText true}]
|
||||
:onActionSelected (fn [position]
|
||||
(case position
|
||||
0 (dispatch [:show-add-participants navigator])))
|
||||
:onIconClicked (fn []
|
||||
(nav-pop navigator))}])
|
||||
[list-view {:dataSource datasource
|
||||
:renderScrollComponent (fn [props]
|
||||
(invertible-scroll-view nil))
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
(ns syng-im.components.chat.new-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 new-participants [{:keys [navigator]}]
|
||||
(let [contacts (subscribe [:all-new-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 "Add Participants"
|
||||
:titleColor "#4A5258"
|
||||
:style {:backgroundColor "white"
|
||||
:height 56
|
||||
:elevation 2}
|
||||
:actions [{:title "Add"
|
||||
:icon res/v
|
||||
:show "always"}]
|
||||
:onActionSelected (fn [position]
|
||||
(dispatch [:add-new-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"}}]]))))
|
|
@ -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]])))
|
|
@ -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])
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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)))))))
|
||||
|
|
Loading…
Reference in New Issue