From e73de0a86dd856cefbac0833645c68752ddc8271 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Wed, 24 Aug 2016 16:40:36 +0300 Subject: [PATCH] Group chat: basic features --- src/status_im/accounts/handlers.cljs | 4 +- src/status_im/accounts/styles.cljs | 2 +- src/status_im/chat/handlers.cljs | 5 --- .../chat/handlers/receive_message.cljs | 45 ++++++++++++------- src/status_im/chat/handlers/send_message.cljs | 24 ++-------- src/status_im/chat/screen.cljs | 22 ++++----- src/status_im/chat/sign_up.cljs | 5 ++- src/status_im/chat/subs.cljs | 5 +++ src/status_im/chat/utils.cljs | 23 ++++++---- src/status_im/chat/views/message.cljs | 7 +-- src/status_im/group_settings/screen.cljs | 2 +- .../group_settings/styles/group_settings.cljs | 5 +-- src/status_im/handlers.cljs | 3 +- src/status_im/models/messages.cljs | 5 +++ src/status_im/new_group/handlers.cljs | 20 ++++++--- src/status_im/protocol/handlers.cljs | 2 +- src/status_im/protocol/protocol_handler.cljs | 12 +++-- 17 files changed, 105 insertions(+), 86 deletions(-) diff --git a/src/status_im/accounts/handlers.cljs b/src/status_im/accounts/handlers.cljs index bfeece8859..edf7a7e8a8 100644 --- a/src/status_im/accounts/handlers.cljs +++ b/src/status_im/accounts/handlers.cljs @@ -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])))) diff --git a/src/status_im/accounts/styles.cljs b/src/status_im/accounts/styles.cljs index 91cbbb8b5f..56fe161755 100644 --- a/src/status_im/accounts/styles.cljs +++ b/src/status_im/accounts/styles.cljs @@ -25,7 +25,7 @@ {:flex 1}))) (def account-list - {:margin-top 56 + {:margin-top 20 :height 100}) (def row-separator diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index 3e747182c8..840eec291f 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -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) diff --git a/src/status_im/chat/handlers/receive_message.cljs b/src/status_im/chat/handlers/receive_message.cljs index 1ec61560a8..602375466c 100644 --- a/src/status_im/chat/handlers/receive_message.cljs +++ b/src/status_im/chat/handlers/receive_message.cljs @@ -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?))) diff --git a/src/status_im/chat/handlers/send_message.cljs b/src/status_im/chat/handlers/send_message.cljs index 966aefca5e..2e51ddccdf 100644 --- a/src/status_im/chat/handlers/send_message.cljs +++ b/src/status_im/chat/handlers/send_message.cljs @@ -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)))) diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index b87c2012c9..4b79753d99 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -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] diff --git a/src/status_im/chat/sign_up.cljs b/src/status_im/chat/sign_up.cljs index 6f42aafaca..9d0ef738c3 100644 --- a/src/status_im/chat/sign_up.cljs +++ b/src/status_im/chat/sign_up.cljs @@ -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)] diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index 81bdbc0c5d..cb1f467ec0 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -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)))))) diff --git a/src/status_im/chat/utils.cljs b/src/status_im/chat/utils.cljs index 66d2d0682d..6084c2e8b2 100644 --- a/src/status_im/chat/utils.cljs +++ b/src/status_im/chat/utils.cljs @@ -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)))) diff --git a/src/status_im/chat/views/message.cljs b/src/status_im/chat/views/message.cljs index 5b5772e941..e7d3ec3936 100644 --- a/src/status_im/chat/views/message.cljs +++ b/src/status_im/chat/views/message.cljs @@ -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 diff --git a/src/status_im/group_settings/screen.cljs b/src/status_im/group_settings/screen.cljs index ce71578906..488ba1831c 100644 --- a/src/status_im/group_settings/screen.cljs +++ b/src/status_im/group_settings/screen.cljs @@ -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)])]) diff --git a/src/status_im/group_settings/styles/group_settings.cljs b/src/status_im/group_settings/styles/group_settings.cljs index 81b0386c3d..6b7a79313e 100644 --- a/src/status_im/group_settings/styles/group_settings.cljs +++ b/src/status_im/group_settings/styles/group_settings.cljs @@ -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 diff --git a/src/status_im/handlers.cljs b/src/status_im/handlers.cljs index 53412a0640..3da9265766 100644 --- a/src/status_im/handlers.cljs +++ b/src/status_im/handlers.cljs @@ -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 _] diff --git a/src/status_im/models/messages.cljs b/src/status_im/models/messages.cljs index bbe240bac9..07db2bb75b 100644 --- a/src/status_im/models/messages.cljs +++ b/src/status_im/models/messages.cljs @@ -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))) diff --git a/src/status_im/new_group/handlers.cljs b/src/status_im/new_group/handlers.cljs index 3cba0c3db0..a35c964497 100644 --- a/src/status_im/new_group/handlers.cljs +++ b/src/status_im/new_group/handlers.cljs @@ -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}])))))) diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index a892b84e44..95ed883418 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -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! diff --git a/src/status_im/protocol/protocol_handler.cljs b/src/status_im/protocol/protocol_handler.cljs index 2658535fc1..1c5aecba98 100644 --- a/src/status_im/protocol/protocol_handler.cljs +++ b/src/status_im/protocol/protocol_handler.cljs @@ -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]