Merge pull request #78 from status-im/group-chat

Group chat refactoring
This commit is contained in:
Jarrad 2016-05-19 17:44:05 +02:00
commit 416c9395c1
14 changed files with 237 additions and 201 deletions

View File

@ -11,7 +11,6 @@
[syng-im.chat.sign-up :as sign-up-service] [syng-im.chat.sign-up :as sign-up-service]
[syng-im.models.chats :as chats] [syng-im.models.chats :as chats]
[syng-im.navigation.handlers :as nav] [syng-im.navigation.handlers :as nav]
[syng-im.models.chats :as c]
[syng-im.utils.handlers :as u])) [syng-im.utils.handlers :as u]))
(register-handler :set-show-actions (register-handler :set-show-actions
@ -70,20 +69,6 @@
(register-handler :set-chat-input-text (register-handler :set-chat-input-text
((enrich update-command) update-text)) ((enrich update-command) update-text))
(register-handler :send-group-chat-msg
(u/side-effect!
(fn [_ [_ chat-id 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}]
(messages/save-message chat-id msg)))))
(defn console? [s] (defn console? [s]
(= "console" s)) (= "console" s))
@ -168,10 +153,15 @@
(assoc-in db [:chats current-chat-id :staged-commands] [])) (assoc-in db [:chats current-chat-id :staged-commands] []))
(defn send-message! (defn send-message!
[{:keys [new-message current-chat-id]} _] [{:keys [new-message current-chat-id] :as db} _]
(when (and new-message (not-console? current-chat-id)) (when (and new-message (not-console? current-chat-id))
(api/send-user-msg {:to current-chat-id (let [{:keys [group-chat]} (get-in db [:chats current-chat-id])
:content (:content new-message)}))) content (:content new-message)]
(if group-chat
(api/send-group-user-msg {:group-id current-chat-id
:content content})
(api/send-user-msg {:to current-chat-id
:content content})))))
(defn save-message-to-realm! (defn save-message-to-realm!
[{:keys [new-message current-chat-id]} _] [{:keys [new-message current-chat-id]} _]
@ -204,8 +194,7 @@
(register-handler :unstage-command (register-handler :unstage-command
(fn [db [_ staged-command]] (fn [db [_ staged-command]]
(let [] (commands/unstage-command db staged-command)))
(commands/unstage-command db staged-command))))
(register-handler :set-chat-command (register-handler :set-chat-command
(fn [db [_ command-key]] (fn [db [_ command-key]]
@ -307,11 +296,7 @@
:group-chat false :group-chat false
:is-active true :is-active true
:timestamp (.getTime (js/Date.)) :timestamp (.getTime (js/Date.))
;; todo how to choose color? :contacts [{:identity contcat-id}]}]
;; todo do we need to have some color for not group chat?
:contacts [{:identity contcat-id
:text-color :#FFFFFF
:background-color :#AB7967}]}]
(assoc db :new-chat chat))) (assoc db :new-chat chat)))
(defn add-chat [{:keys [new-chat] :as db} [_ chat-id]] (defn add-chat [{:keys [new-chat] :as db} [_ chat-id]]
@ -331,8 +316,7 @@
(-> prepare-chat (-> prepare-chat
((enrich add-chat)) ((enrich add-chat))
((after save-chat!)) ((after save-chat!))
((after open-chat!)) ((after open-chat!))))
debug))
(register-handler :switch-command-suggestions (register-handler :switch-command-suggestions
(fn [db [_]] (fn [db [_]]

View File

@ -12,11 +12,7 @@
(defn send [chat input-message] (defn send [chat input-message]
(let [{:keys [group-chat chat-id]} chat] (let [{:keys [group-chat chat-id]} chat]
(if group-chat (dispatch [:send-chat-msg])))
;; todo how much are different both events? is there real reason
;; for differentiation here?
(dispatch [:send-group-chat-msg chat-id input-message])
(dispatch [:send-chat-msg]))))
(defn message-valid? [staged-commands message] (defn message-valid? [staged-commands message]
(or (and (pos? (count message)) (or (and (pos? (count message))

View File

@ -11,13 +11,13 @@
:identity "me" :identity "me"
:contacts [] :contacts []
:contacts-ids #{} :contacts-ids #{}
:selected-contacts #{}
:current-chat-id "console" :current-chat-id "console"
:chat {:command nil :chat {:command nil
:last-message nil} :last-message nil}
:chats {} :chats {}
:chats-updated-signal 0 :chats-updated-signal 0
:show-actions false :show-actions false
:new-group #{}
:new-participants #{} :new-participants #{}
:signed-up true :signed-up true
:view-id default-view :view-id default-view

View File

@ -31,7 +31,7 @@
(dispatch [:initialize-chats])) (dispatch [:initialize-chats]))
(register-handler :show-group-settings (register-handler :show-group-settings
(fn [db [action]] (fn [db _]
(let [chat-id (:current-chat-id db) (let [chat-id (:current-chat-id db)
chat-name (get-in db [:chats chat-id :name]) chat-name (get-in db [:chats chat-id :name])
chat-color (get-in db [:chats chat-id :color]) chat-color (get-in db [:chats chat-id :color])

View File

@ -1,7 +1,6 @@
(ns syng-im.group-settings.screen (ns syng-im.group-settings.screen
(:require-macros [syng-im.utils.views :refer [defview]]) (:require-macros [syng-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] (:require [re-frame.core :refer [subscribe dispatch]]
[syng-im.resources :as res]
[syng-im.components.react :refer [view [syng-im.components.react :refer [view
text-input text-input
text text
@ -13,12 +12,8 @@
scroll-view scroll-view
touchable-highlight]] touchable-highlight]]
[syng-im.components.toolbar :refer [toolbar]] [syng-im.components.toolbar :refer [toolbar]]
[syng-im.components.realm :refer [list-view]]
[syng-im.components.styles :refer [color-purple
text2-color]]
[syng-im.group-settings.styles.group-settings :as st] [syng-im.group-settings.styles.group-settings :as st]
[syng-im.group-settings.views.member :refer [member-view]] [syng-im.group-settings.views.member :refer [member-view]]))
[reagent.core :as r]))
(defn remove-member [{:keys [whisper-identity]}] (defn remove-member [{:keys [whisper-identity]}]
(dispatch [:chat-remove-member whisper-identity])) (dispatch [:chat-remove-member whisper-identity]))
@ -70,7 +65,7 @@
(dispatch [:set-chat-color])) (dispatch [:set-chat-color]))
(defview chat-color-picker [] (defview chat-color-picker []
[show-color-picker [:group-settings-show-color-picker] [show-color-picker [:get :group-settings-show-color-picker]
new-color [:get :new-chat-color]] new-color [:get :new-chat-color]]
[modal {:animated false [modal {:animated false
:transparent false :transparent false
@ -128,7 +123,7 @@
[name [:chat :name] [name [:chat :name]
color [:chat :color]] color [:chat :color]]
[view (st/chat-icon color) [view (st/chat-icon color)
[text {:style st/chat-icon-text} (nth name 0)]]) [text {:style st/chat-icon-text} (first name)]])
(defn new-group-toolbar [] (defn new-group-toolbar []
[toolbar {:title "Chat settings" [toolbar {:title "Chat settings"

View File

@ -34,11 +34,13 @@
nav-pop]] nav-pop]]
[syng-im.utils.crypt :refer [gen-random-bytes]] [syng-im.utils.crypt :refer [gen-random-bytes]]
[syng-im.utils.random :as random] [syng-im.utils.random :as random]
[syng-im.utils.handlers :as u]
syng-im.chat.handlers syng-im.chat.handlers
[syng-im.group-settings.handlers :refer [delete-chat]] [syng-im.group-settings.handlers :refer [delete-chat]]
[syng-im.navigation.handlers :as nav] syng-im.navigation.handlers
syng-im.discovery.handlers syng-im.discovery.handlers
syng-im.contacts.handlers)) syng-im.contacts.handlers
syng-im.new-group.handlers))
;; -- Middleware ------------------------------------------------------------ ;; -- Middleware ------------------------------------------------------------
;; ;;
@ -61,45 +63,37 @@
(fn [db [_ k v]] (fn [db [_ k v]]
(assoc db k v)))) (assoc db k v))))
(defn preload-data!
[{:keys [view-id] :as db} _]
(nav/preload-data! db [nil view-id]))
(register-handler :initialize-db (register-handler :initialize-db
(fn [_ _] (fn [_ _]
(assoc app-db (assoc app-db
:signed-up (storage/get kv/kv-store :signed-up)))) :signed-up (storage/get kv/kv-store :signed-up))))
(register-handler :set-loading
(fn [db [_ value]]
(assoc db :loading value)))
(register-handler :initialize-crypt (register-handler :initialize-crypt
(fn [db _] (u/side-effect!
(log/debug "initializing crypt") (fn [_ _]
(gen-random-bytes 1024 (fn [{:keys [error buffer]}] (log/debug "initializing crypt")
(if error (gen-random-bytes 1024 (fn [{:keys [error buffer]}]
(do (if error
(log/error "Failed to generate random bytes to initialize sjcl crypto") (do
(dispatch [:notify-user {:type :error (log/error "Failed to generate random bytes to initialize sjcl crypto")
:error error}])) (dispatch [:notify-user {:type :error
(do :error error}]))
(->> (.toString buffer "hex") (do
(.toBits (.. js/ecc -sjcl -codec -hex)) (->> (.toString buffer "hex")
(.addEntropy (.. js/ecc -sjcl -random))) (.toBits (.. js/ecc -sjcl -codec -hex))
(dispatch [:crypt-initialized]))))) (.addEntropy (.. js/ecc -sjcl -random)))
db)) (dispatch [:crypt-initialized]))))))))
(register-handler :crypt-initialized (register-handler :crypt-initialized
(fn [db _] (u/side-effect!
(log/debug "crypt initialized") (fn [_ _]
db)) (log/debug "crypt initialized"))))
(register-handler :load-commands (register-handler :load-commands
(fn [db [action]] (u/side-effect!
(log/debug action) (fn [_ [action]]
(load-commands) (log/debug action)
db)) (load-commands))))
(register-handler :set-commands (register-handler :set-commands
(fn [db [action commands]] (fn [db [action commands]]
@ -109,9 +103,9 @@
;; -- Protocol -------------------------------------------------------------- ;; -- Protocol --------------------------------------------------------------
(register-handler :initialize-protocol (register-handler :initialize-protocol
(fn [db [_]] (u/side-effect!
(init-protocol (make-handler db)) (fn [db [_]]
db)) (init-protocol (make-handler db)))))
(register-handler :protocol-initialized (register-handler :protocol-initialized
(fn [db [_ identity]] (fn [db [_ identity]]
@ -174,55 +168,62 @@
:content-type text-content-type})) :content-type text-content-type}))
(register-handler :group-chat-invite-acked (register-handler :group-chat-invite-acked
(fn [db [action from group-id ack-msg-id]] (u/side-effect!
(log/debug action from group-id ack-msg-id) (fn [_ [action from group-id ack-msg-id]]
(joined-chat-msg group-id from ack-msg-id))) (log/debug action from group-id ack-msg-id)
(joined-chat-msg group-id from ack-msg-id))))
(register-handler :participant-removed-from-group (register-handler :participant-removed-from-group
(fn [db [action from group-id identity msg-id]] (u/side-effect!
(log/debug action msg-id from group-id identity) (fn [_ [action from group-id identity msg-id]]
(chat-remove-participants group-id [identity]) (log/debug action msg-id from group-id identity)
(participant-removed-from-group-msg group-id identity from msg-id))) (chat-remove-participants group-id [identity])
(participant-removed-from-group-msg group-id identity from msg-id))))
(register-handler :you-removed-from-group (register-handler :you-removed-from-group
(fn [db [action from group-id msg-id]] (u/side-effect!
(log/debug action msg-id from group-id) (fn [_ [action from group-id msg-id]]
(you-removed-from-group-msg group-id from msg-id) (log/debug action msg-id from group-id)
(set-chat-active group-id false))) (you-removed-from-group-msg group-id from msg-id)
(set-chat-active group-id false))))
(register-handler :participant-left-group (register-handler :participant-left-group
(fn [db [action from group-id msg-id]] (u/side-effect!
(log/debug action msg-id from group-id) (fn [_ [action from group-id msg-id]]
(if (= (api/my-identity) from) (log/debug action msg-id from group-id)
db (when-not (= (api/my-identity) from)
(participant-left-group-msg group-id from msg-id)))) (participant-left-group-msg group-id from msg-id)))))
(register-handler :participant-invited-to-group (register-handler :participant-invited-to-group
(fn [db [action from group-id identity msg-id]] (u/side-effect!
(log/debug action msg-id from group-id identity) (fn [_ [action from group-id identity msg-id]]
(participant-invited-to-group-msg group-id identity from msg-id))) (log/debug action msg-id from group-id identity)
(participant-invited-to-group-msg group-id identity from msg-id))))
(register-handler :acked-msg (register-handler :acked-msg
(fn [db [action from msg-id]] (u/side-effect!
(log/debug action from msg-id) (fn [_ [action from msg-id]]
(update-message! {:msg-id msg-id (log/debug action from msg-id)
:delivery-status :delivered}))) (update-message! {:msg-id msg-id
:delivery-status :delivered}))))
(register-handler :msg-delivery-failed (register-handler :msg-delivery-failed
(fn [db [action msg-id]] (u/side-effect!
(log/debug action msg-id) (fn [_ [action msg-id]]
(update-message! {:msg-id msg-id (log/debug action msg-id)
:delivery-status :failed}))) (update-message! {:msg-id msg-id
:delivery-status :failed}))))
(register-handler :leave-group-chat (register-handler :leave-group-chat
(fn [db [action]] (u/side-effect!
(log/debug action) (fn [db [action]]
(let [chat-id (:current-chat-id db)] (log/debug action)
(api/leave-group-chat chat-id) (let [chat-id (:current-chat-id db)]
(set-chat-active chat-id false) (api/leave-group-chat chat-id)
(left-chat-msg chat-id) (set-chat-active chat-id false)
(delete-chat chat-id) (left-chat-msg chat-id)
(dispatch [:navigate-back])))) (delete-chat chat-id)
(dispatch [:navigate-back])))))
;; -- User data -------------------------------------------------------------- ;; -- User data --------------------------------------------------------------
(register-handler :load-user-phone-number (register-handler :load-user-phone-number
@ -288,29 +289,3 @@
(api/group-remove-participant chat-id identity) (api/group-remove-participant chat-id identity)
(removed-participant-msg chat-id identity) (removed-participant-msg chat-id identity)
db))) db)))
(defn update-new-group-selection [db identity add?]
(update-in db :new-group (fn [new-group]
(if add?
(conj new-group identity)
(disj new-group identity)))))
(register-handler :select-for-new-group
(fn [db [_ identity add?]]
(update-new-group-selection db identity add?)))
(register-handler :create-new-group
(fn [db [action group-name]]
(log/debug action)
(let [identities (vec (:new-group db))
group-id (api/start-group-chat identities group-name)
db (create-chat db group-id identities true group-name)]
(dispatch [:show-chat group-id :replace])
db)))
(register-handler :group-chat-invite-received
(fn [db [action from group-id identities group-name]]
(log/debug action from group-id identities)
(if (chat-exists? group-id)
(re-join-group-chat db group-id identities group-name)
(create-chat db group-id identities true group-name))))

View File

@ -44,8 +44,7 @@
(let [chat (assoc chat :last-msg-id (or last-msg-id ""))] (let [chat (assoc chat :last-msg-id (or last-msg-id ""))]
(r/write #(r/create :chats chat)))) (r/write #(r/create :chats chat))))
([db chat-id identities group-chat? chat-name] ([db chat-id identities group-chat? chat-name]
(if (chat-exists? chat-id) (when-not (chat-exists? chat-id)
db
(let [chat-name (or chat-name (let [chat-name (or chat-name
(get-chat-name chat-id identities)) (get-chat-name chat-id identities))
_ (log/debug "creating chat" chat-name)] _ (log/debug "creating chat" chat-name)]
@ -60,8 +59,7 @@
:timestamp (timestamp) :timestamp (timestamp)
:contacts contacts :contacts contacts
:last-msg-id ""})))) :last-msg-id ""}))))
(add-status-message chat-id) (add-status-message chat-id)))))
db))))
(defn chat-contacts [chat-id] (defn chat-contacts [chat-id]
(-> (r/get-by-field :chats :chat-id chat-id) (-> (r/get-by-field :chats :chat-id chat-id)

View File

@ -17,19 +17,24 @@
[s] [s]
(keywordize-keys (apply hash-map (split s #"[;=]")))) (keywordize-keys (apply hash-map (split s #"[;=]"))))
(def default-values
{:outgoing false
:to nil
:same-author false
:same-direction false})
(defn save-message (defn save-message
;; todo remove chat-id parameter ;; todo remove chat-id parameter
[chat-id {:keys [to msg-id content outgoing] [chat-id {:keys [msg-id content]
;; outgoing should be explicitely defined in handlers :as message}]
:or {outgoing false
to nil} :as message}]
(when-not (r/exists? :msgs :msg-id msg-id) (when-not (r/exists? :msgs :msg-id msg-id)
(r/write (r/write
(fn [] (fn []
(let [content' (if (string? content) (let [content' (if (string? content)
content content
(map-to-str content)) (map-to-str content))
message' (merge message message' (merge default-values
message
{:chat-id chat-id {:chat-id chat-id
:content content' :content content'
:timestamp (timestamp) :timestamp (timestamp)
@ -60,7 +65,7 @@
(defn clear-history [chat-id] (defn clear-history [chat-id]
(r/write (r/write
(fn [] (fn []
(r/delete (r/get-by-field :msgs :chat-id chat-id)))) (r/delete (r/get-by-field :msgs :chat-id chat-id))))
;; TODO temp. Update chat in db atom ;; TODO temp. Update chat in db atom
(dispatch [:initialize-chats])) (dispatch [:initialize-chats]))

View File

@ -0,0 +1,73 @@
(ns syng-im.new-group.handlers
(:require [syng-im.protocol.api :as api]
[re-frame.core :refer [register-handler after dispatch debug enrich]]
[syng-im.models.chats :as chats]
[clojure.string :as s]))
(defn deselect-contact
[db [_ id]]
(update db :selected-contacts disj id))
(register-handler :deselect-contact deselect-contact)
(defn select-contact
[db [_ id]]
(update db :selected-contacts conj id))
(register-handler :select-contact select-contact)
(defn start-group-chat!
[{:keys [selected-contacts] :as db} [_ group-name]]
(let [group-id (api/start-group-chat selected-contacts group-name)]
(assoc db :new-group-id group-id)))
(defn group-name-from-contacts
[{:keys [contacts selected-contacts username]}]
(->> (select-keys contacts selected-contacts)
vals
(map :name)
(cons username)
(s/join ", ")))
(defn prepare-chat
[{:keys [selected-contacts new-group-id] :as db} [_ group-name]]
(let [contacts (mapv #(hash-map :identity %) selected-contacts)
chat-name (if-not (s/blank? group-name)
group-name
(group-name-from-contacts db))]
(assoc db :new-chat {:chat-id new-group-id
:name chat-name
:group-chat true
:is-active true
:timestamp (.getTime (js/Date.))
:contacts contacts
:same-author false
:same-direction false})))
(defn add-chat
[{:keys [new-chat] :as db} _]
(-> db
(assoc-in [:chats (:chat-id new-chat)] new-chat)
(assoc :selected-contacts #{})))
(defn create-chat!
[{:keys [new-chat]} _]
(chats/create-chat new-chat))
(defn show-chat!
[{:keys [new-group-id]} _]
(dispatch [:show-chat new-group-id :replace]))
(register-handler :create-new-group
(-> start-group-chat!
((enrich prepare-chat))
((enrich add-chat))
((after create-chat!))
((after show-chat!))))
; todo rewrite
(register-handler :group-chat-invite-received
(fn [db [action from group-id identities group-name]]
(if (chats/chat-exists? group-id)
(chats/re-join-group-chat db group-id identities group-name)
(chats/create-chat db group-id identities true group-name))))

View File

@ -1,5 +1,6 @@
(ns syng-im.new-group.screen (ns syng-im.new-group.screen
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] (:require-macros [syng-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]]
[syng-im.resources :as res] [syng-im.resources :as res]
[syng-im.components.react :refer [view [syng-im.components.react :refer [view
text-input text-input
@ -16,43 +17,38 @@
[syng-im.new-group.styles :as st])) [syng-im.new-group.styles :as st]))
(defn new-group-toolbar [] (defview new-group-toolbar []
(let [group-name (subscribe [:get ::group-name])] [group-name [:get ::group-name]]
(fn [] [toolbar
[toolbar {:title "New group chat"
{:title "New group chat" :action {:image {:source res/v ;; {:uri "icon_search"}
:action {:image {:source res/v ;; {:uri "icon_search"} :style st/toolbar-icon}
:style st/toolbar-icon} :handler #(dispatch [:create-new-group group-name])}}])
:handler #(dispatch [:create-new-group @group-name])}}])))
(defn group-name-input [] (defview group-name-input []
(let [group-name (subscribe [:get ::group-name])] [group-name [:get ::group-name]]
(fn [] [text-input
[text-input {:underlineColorAndroid color-purple
{:underlineColorAndroid color-purple :style st/group-name-input
:style st/group-name-input :autoFocus true
:autoFocus true :placeholder "Group Name"
:placeholder "Group Name" :onChangeText #(dispatch [:set ::group-name %])}
:onChangeText #(dispatch [:set ::group-name %]) group-name])
:onSubmitEditing #(dispatch [:set ::group-name nil])}
@group-name])))
(defn new-group [] (defview new-group []
(let [contacts (subscribe [:all-contacts])] [contacts [:all-contacts]]
(fn [] [view st/new-group-container
(let [contacts-ds (to-datasource @contacts)] [new-group-toolbar]
[view st/new-group-container [view st/chat-name-container
[new-group-toolbar] [text {:style st/chat-name-text} "Chat name"]
[view st/chat-name-container [group-name-input]
[text {:style st/chat-name-text} "Chat name"] [text {:style st/members-text} "Members"]
[group-name-input] [touchable-highlight {:on-press (fn [])}
[text {:style st/members-text} "Members"] [view st/add-container
[touchable-highlight {:on-press (fn [])} [icon :add_gray st/add-icon]
[view st/add-container [text {:style st/add-text} "Add members"]]]
[icon :add_gray st/add-icon] [list-view
[text {:style st/add-text} "Add members"]]] {:dataSource (to-datasource contacts)
[list-view :renderRow (fn [row _ _]
{:dataSource contacts-ds (list-item [new-group-contact row]))
:renderRow (fn [row _ _] :style st/contacts-list}]]])
(list-item [new-group-contact row]))
:style st/contacts-list}]]]))))

View File

@ -0,0 +1,9 @@
(ns syng-im.new-group.subs
(:require-macros [reagent.ratom :refer [reaction]])
(:require [re-frame.core :refer [register-sub]]))
(register-sub :is-contact-selected?
(fn [db [_ id]]
(-> (:selected-contacts @db)
(contains? id)
(reaction))))

View File

@ -1,19 +1,22 @@
(ns syng-im.new-group.views.contact (ns syng-im.new-group.views.contact
(:require-macros [syng-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[syng-im.components.react :refer [view]] [syng-im.components.react :refer [view]]
[syng-im.contacts.views.contact-inner :refer [contact-inner-view]] [syng-im.contacts.views.contact-inner :refer [contact-inner-view]]
[syng-im.components.item-checkbox :refer [item-checkbox]] [syng-im.components.item-checkbox :refer [item-checkbox]]
[reagent.core :as r]
[syng-im.new-group.styles :as st])) [syng-im.new-group.styles :as st]))
(defn new-group-contact [{:keys [whisper-identity] :as contact}] (defn on-toggle [whisper-identity]
(let [checked (r/atom false)] (fn [checked?]
(fn [] (println checked?)
[view st/contact-container (let [action (if checked? :select-contact :deselect-contact)]
[item-checkbox (dispatch [action whisper-identity]))))
{:onToggle (fn [checked?]
(reset! checked checked?) (defview new-group-contact [{:keys [whisper-identity] :as contact}]
(dispatch [:select-for-new-group whisper-identity checked?])) [checked [:is-contact-selected? whisper-identity]]
:checked @checked [view st/contact-container
:size 30}] [item-checkbox
[contact-inner-view contact]]))) {:onToggle (on-toggle whisper-identity)
:checked checked
:size 30}]
[contact-inner-view contact]])

View File

@ -10,6 +10,7 @@
(defn make-handler [db] (defn make-handler [db]
{:ethereum-rpc-url ethereum-rpc-url {:ethereum-rpc-url ethereum-rpc-url
:identity (stored-identity db) :identity (stored-identity db)
;; :active-group-ids is never used in protocol
:active-group-ids (active-group-chats) :active-group-ids (active-group-chats)
:storage kv/kv-store :storage kv/kv-store
:handler (fn [{:keys [event-type] :as event}] :handler (fn [{:keys [event-type] :as event}]

View File

@ -4,7 +4,8 @@
syng-im.chat.subs syng-im.chat.subs
syng-im.group-settings.subs syng-im.group-settings.subs
syng-im.discovery.subs syng-im.discovery.subs
syng-im.contacts.subs)) syng-im.contacts.subs
syng-im.new-group.subs))
(register-sub :get (register-sub :get
(fn [db [_ k]] (fn [db [_ k]]