Merge pull request #78 from status-im/group-chat
Group chat refactoring
This commit is contained in:
commit
416c9395c1
|
@ -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 [_]]
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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))))
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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]))
|
||||||
|
|
|
@ -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))))
|
|
@ -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}]]]))))
|
|
||||||
|
|
|
@ -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))))
|
|
@ -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]])
|
||||||
|
|
|
@ -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}]
|
||||||
|
|
|
@ -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]]
|
||||||
|
|
Loading…
Reference in New Issue