Group chat: basic features

Former-commit-id: e73de0a86d
This commit is contained in:
Roman Volosovskyi 2016-08-24 16:40:36 +03:00
parent 1321a85659
commit 34f62d3865
17 changed files with 105 additions and 86 deletions

View File

@ -82,10 +82,12 @@
(when needs-update?
(dispatch [:account-update]))))))
(defn initialize-account [db address]
(defn initialize-account [{:keys [accounts] :as db} address]
(let [is-login-screen? (= (:view-id db) :login)]
(dispatch [:set :login {}])
(dispatch [:set :current-account-id address])
(let [key (:public-key (accounts address))]
(dispatch [:set :current-public-key key]))
(dispatch [:initialize-account address])
(when is-login-screen? (dispatch [:navigate-to-clean default-view]))))

View File

@ -25,7 +25,7 @@
{:flex 1})))
(def account-list
{:margin-top 56
{:margin-top 20
:height 100})
(def row-separator

View File

@ -234,11 +234,6 @@
(after #(dispatch [:load-unviewed-messages!]))
((enrich initialize-chats) load-chats!))
(register-handler :group-received-msg
(u/side-effect!
(fn [_ [_ {chat-id :group-id :as msg}]]
(messages/save-message chat-id msg))))
(defmethod nav/preload-data! :chat
[{:keys [current-chat-id] :as db} [_ _ id]]
(let [chat-id (or id current-chat-id)

View File

@ -16,26 +16,37 @@
:rendered-preview rendered-preview))
message))
(defn store-message [{chat-id :from :as message}]
(defn store-message [{chat-id :chat-id :as message}]
(messages/save-message chat-id (dissoc message :rendered-preview :new?)))
(defn get-current-identity
[{:keys [current-account-id accounts]}]
(:public-key (accounts current-account-id)))
(defn receive-message
[db [_ {:keys [from group-id chat-id msg-id] :as message}]]
(let [same-message (messages/get-message msg-id)
current-identity (get-current-identity db)]
(when-not (or same-message (= from current-identity))
(let [group-chat? (not (nil? group-id))
chat-id' (or chat-id from)
previous-message (messages/get-last-message chat-id')
message' (assoc (->> message
(cu/check-author-direction previous-message)
(check-previev))
:delivery-status :pending
:chat-id chat-id')]
(store-message message')
(when-not (c/chat-exists? chat-id')
(dispatch [:add-chat chat-id' (when group-chat? {:group-chat true})]))
(dispatch [::add-message message'])
(when (= (:content-type message') content-type-command-request)
(dispatch [:add-request chat-id' message']))
(dispatch [:add-unviewed-message chat-id' msg-id])))))
(register-handler :received-message
(u/side-effect!
(fn [{:keys [chats] :as db} [_ {chat-id :from :keys [msg-id] :as message}]]
(let [same-message (messages/get-message msg-id)]
(when-not same-message
(let [message' (assoc (->> message
(cu/check-author-direction db chat-id)
(check-previev))
:delivery-status :pending)]
(store-message message')
(when-not (c/chat-exists? chat-id)
(dispatch [:add-chat chat-id]))
(dispatch [::add-message message'])
(when (= (:content-type message') content-type-command-request)
(dispatch [:add-request chat-id message']))
(dispatch [:add-unviewed-message chat-id msg-id])))))))
(u/side-effect! receive-message))
(register-handler ::add-message
(fn [db [_ {chat-id :from :keys [new?] :as message}]]
(fn [db [_ {:keys [chat-id new?] :as message}]]
(cu/add-message-to-db db chat-id message new?)))

View File

@ -20,25 +20,6 @@
:seen
:pending))
(defn prepare-message
[{:keys [identity current-chat-id] :as db} _]
(let [text (get-in db [:chats current-chat-id :input-text])
[command] (suggestions/check-suggestion db (str text " "))
message (cu/check-author-direction
db current-chat-id
{:msg-id (random/id)
:chat-id current-chat-id
:content text
:to current-chat-id
:from identity
:content-type text-content-type
:delivery-status (default-delivery-status current-chat-id)
:outgoing true
:timestamp (time/now-ms)})]
(if command
(commands/set-command-input db :commands command)
(assoc db :new-message (when-not (s/blank? text) message)))))
(defn prepare-command
[identity chat-id {:keys [preview preview-string content command to-message]}]
(let [content {:command (command :name)
@ -166,14 +147,15 @@
:timestamp (time/now-ms)})
params' (assoc params :message message')]
(dispatch [::add-message params'])
(dispatch [::save-message! params'])
(dispatch [::send-message! params'])))))
(dispatch [::save-message! params'])))))
(register-handler ::add-message
(fn [db [_ {:keys [chat-id message]}]]
(cu/add-message-to-db db chat-id message)))
(register-handler ::save-message!
(after (fn [_ [_ params]]
(dispatch [::send-message! params])))
(u/side-effect!
(fn [_ [_ {:keys [chat-id message]}]]
(messages/save-message chat-id message))))

View File

@ -207,7 +207,7 @@
(subscribe [:chat-properties [:group-chat :name :contacts :chat-id]])
show-actions (subscribe [:show-actions])
contact (subscribe [:get-in [:contacts @chat-id]])]
(fn []
(fn [platform-specific]
[view (st/chat-name-view @show-actions)
[text {:style st/chat-name-text
:platform-specific platform-specific
@ -241,15 +241,14 @@
[view st/action
[chat-icon]]]))))
(defn chat-toolbar [platform-specific]
(let [{:keys [group-chat name contacts]} (subscribe [:chat-properties [:group-chat :name :contacts]])
show-actions (subscribe [:show-actions])]
[view
[status-bar {:platform-specific platform-specific}]
[toolbar {:hide-nav? @show-actions
:custom-content [toolbar-content platform-specific]
:custom-action [toolbar-action]
:style (get-in platform-specific [:styles :components :toolbar])}]]))
(defview chat-toolbar [platform-specific]
[show-actions [:show-actions]]
[view
[status-bar {:platform-specific platform-specific}]
[toolbar {:hide-nav? show-actions
:custom-content [toolbar-content platform-specific]
:custom-action [toolbar-action]
:style (get-in platform-specific [:styles :components :toolbar])}]])
(defview messages-view [platform-specific group-chat]
[messages [:chat :messages]
@ -305,7 +304,8 @@
[chat-toolbar platform-specific]
[messages-container
[messages-view platform-specific @group-chat]]
(when @group-chat [typing-all platform-specific])
;; todo uncomment this
#_(when @group-chat [typing-all platform-specific])
[response-view]
(when-not @command? [suggestion-container])
[chat-message-new platform-specific]

View File

@ -52,8 +52,9 @@
(dispatch [:sign-up-confirm (second matches)])))
(defn start-listening-confirmation-code-sms [db]
(when (not (:confirmation-code-sms-listener db))
(assoc db :confirmation-code-sms-listener (add-sms-listener handle-sms))))
(if (not (:confirmation-code-sms-listener db))
(assoc db :confirmation-code-sms-listener (add-sms-listener handle-sms))
db))
(defn stop-listening-confirmation-code-sms [db]
(when-let [listener (:confirmation-code-sms-listener db)]

View File

@ -238,3 +238,8 @@
(fn [db]
(let [chat-id (subscribe [:get-current-chat-id])]
(reaction (get-in @db [:chats @chat-id :all-loaded?])))))
(register-sub :photo-path
(fn [_ [_ id]]
(let [contacts (subscribe [:get :contacts])]
(reaction (:photo-path (@contacts id))))))

View File

@ -15,13 +15,18 @@
true
new?))))))
(defn- check-message [previous-message {:keys [from outgoing] :as message}]
(merge message
{:same-author (if previous-message
(= (:from previous-message) from)
false)
:same-direction (if previous-message
(= (:outgoing previous-message) outgoing)
true)}))
(defn check-author-direction
[db chat-id {:keys [from outgoing] :as message}]
(let [previous-message (first (get-in db [:chats chat-id :messages]))]
(merge message
{:same-author (if previous-message
(= (:from previous-message) from)
true)
:same-direction (if previous-message
(= (:outgoing previous-message) outgoing)
true)})))
([previous-message message]
(check-message previous-message message))
([db chat-id message]
(let [previous-message (first (get-in db [:chats chat-id :messages]))]
(check-message previous-message message))))

View File

@ -159,7 +159,8 @@
:failed "Failed"
"Pending")]])
(defn member-photo [{:keys [photo-path]}]
(defview member-photo [from]
[photo-path [:photo-path from]]
[view st/photo-view
[image {:source (if (s/blank? photo-path)
res/user-no-photo
@ -167,7 +168,7 @@
:style st/photo}]])
(defn incoming-group-message-body
[{:keys [selected same-author] :as message} content platform-specific]
[{:keys [selected same-author from] :as message} content platform-specific]
(let [delivery-status :seen-by-everyone]
[view st/group-message-wrapper
(when selected
@ -177,7 +178,7 @@
"Mar 7th, 15:22"])
[view (st/incoming-group-message-body-st message)
[view st/message-author
(when (not same-author) [member-photo {}])]
(when (not same-author) [member-photo from])]
[view st/group-message-view
content
;; TODO show for last or selected

View File

@ -168,7 +168,7 @@
[view [icon :ok-purple st/add-members-icon]]]
[touchable-highlight {:style (st/chat-name-btn-edit-container true)
:on-press focus}
[text {:style st/chat-name-btn-edit-text} (label :t/edit)]])]
[view [text {:style st/chat-name-btn-edit-text} (label :t/edit)]]])]
(when (pos? (count validation-messages))
[text {:style st/chat-name-validation-message} (first validation-messages)])])

View File

@ -102,8 +102,7 @@
:opacity (if enabled? 1 0.3)})
(def chat-name-btn-edit-text
{:marginTop -1
:color text2-color
{:color text2-color
:fontFamily font
:fontSize 16
:lineHeight 20})
@ -118,7 +117,7 @@
:lineHeight 20})
(def add-members-icon
{:marginVertical 19
{:marginVertical -1
:marginLeft 19
:marginHorizontal 3
:width 17

View File

@ -59,7 +59,8 @@
(register-handler :initialize-db
(fn [_ _]
(realm/reset-account)
(assoc app-db :current-account-id nil)))
(assoc app-db :current-account-id nil
:current-public-key nil)))
(register-handler :initialize-account-db
(fn [db _]

View File

@ -76,3 +76,8 @@
(defn get-message [id]
(r/get-one-by-field :account :message :msg-id id))
(defn get-last-message [chat-id]
(-> (r/get-by-field :account :message :chat-id chat-id)
(r/sorted :timestamp :desc)
(r/single)
(js->clj :keywordize-keys true)))

View File

@ -4,7 +4,8 @@
[status-im.utils.handlers :refer [register-handler]]
[status-im.components.styles :refer [default-chat-color]]
[status-im.models.chats :as chats]
[clojure.string :as s]))
[clojure.string :as s]
[status-im.utils.handlers :as u]))
(defn deselect-contact
[db [_ id]]
@ -33,7 +34,7 @@
(defn prepare-chat
[{:keys [selected-contacts new-group-id] :as db} [_ group-name]]
(let [contacts (mapv #(hash-map :identity %) selected-contacts)
(let [contacts (mapv #(hash-map :identity %) selected-contacts)
chat-name (if-not (s/blank? group-name)
group-name
(group-name-from-contacts db))]
@ -87,7 +88,14 @@
; 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))))
(u/side-effect!
(fn [{:keys [current-public-key] :as 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)
(let [contacts (keep (fn [ident]
(when (not= ident current-public-key)
{:identity ident})) identities)]
(dispatch [:add-chat group-id {:name group-name
:group-chat true
:contacts contacts}]))))))

View File

@ -74,7 +74,7 @@
(u/side-effect!
(fn [_ [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))))
#_(joined-chat-msg group-id from ack-msg-id))))
(register-handler :participant-removed-from-group
(u/side-effect!

View File

@ -18,11 +18,14 @@
:initialized (let [{:keys [identity]} event]
(dispatch [:protocol-initialized identity]))
:new-msg (let [{:keys [from to payload]} event]
(dispatch [:received-message (assoc payload :from from :to to)]))
(dispatch [:received-message (assoc payload
:chat-id from
:from from
:to to)]))
:msg-acked (let [{:keys [msg-id from]} event]
(dispatch [:acked-msg from msg-id]))
:msg-seen (let [{:keys [msg-id from]} event]
(dispatch [:msg-seen from msg-id]))
(dispatch [:msg-seen from msg-id]))
:delivery-failed (let [{:keys [msg-id from]} event]
(dispatch [:msg-delivery-failed from msg-id]))
:new-group-chat (let [{:keys [from group-id identities group-name]} event]
@ -30,8 +33,9 @@
:new-group-msg (let [{from :from
group-id :group-id
payload :payload} event]
(dispatch [:group-received-msg (assoc payload :from from
:group-id group-id)]))
(dispatch [:received-message (assoc payload
:chat-id group-id
:from from)]))
: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 msg-id]} event]