From b54c9f337f8fc9ec0bea3dc5da04404a827e5c6c Mon Sep 17 00:00:00 2001 From: Gustavo Nunes Date: Wed, 8 Mar 2017 23:28:21 -0300 Subject: [PATCH] chat messages UI refresh --- src/status_im/android/platform.cljs | 4 - src/status_im/chat/screen.cljs | 12 +- src/status_im/chat/styles/datemark.cljs | 18 +-- src/status_im/chat/styles/message.cljs | 130 +++++++++--------- src/status_im/chat/styles/screen.cljs | 33 +++-- src/status_im/chat/subs.cljs | 8 ++ src/status_im/chat/views/message.cljs | 99 ++++++------- src/status_im/chat/views/request_message.cljs | 19 +-- src/status_im/chat/views/toolbar_content.cljs | 20 +-- src/status_im/components/styles.cljs | 1 + src/status_im/contacts/subs.cljs | 5 + src/status_im/ios/platform.cljs | 5 - src/status_im/translations/en.cljs | 4 +- 13 files changed, 163 insertions(+), 195 deletions(-) diff --git a/src/status_im/android/platform.cljs b/src/status_im/android/platform.cljs index 1f4efde63b..1dedaa4f0a 100644 --- a/src/status_im/android/platform.cljs +++ b/src/status_im/android/platform.cljs @@ -141,10 +141,6 @@ :height 56 :align-items :center :justify-content :center} - :toolbar-last-activity {:color styles/text2-color - :background-color :transparent - :top 0 - :font-size 12} :text-field-focus-line-height 2}) (def fonts diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index 37f4b6d666..d3f27a0c17 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -77,13 +77,14 @@ (list-item [chat-datemark value])) (defmethod message-row :default - [{:keys [contact-by-identity group-chat messages-count row index]}] + [{:keys [contact-by-identity group-chat messages-count row index last-outgoing?]}] (let [message (-> row (add-message-color contact-by-identity) (assoc :group-chat group-chat) (assoc :messages-count messages-count) (assoc :index index) - (assoc :last-message (= (js/parseInt index) (dec messages-count))))] + (assoc :last-message (= (js/parseInt index) (dec messages-count))) + (assoc :last-outgoing? last-outgoing?))] (list-item [chat-message message]))) (defn toolbar-action [] @@ -152,7 +153,9 @@ [messages [:chat :messages] contacts [:chat :contacts] message-extras [:get :message-extras] - loaded? [:all-messages-loaded?]] + loaded? [:all-messages-loaded?] + current-chat-id [:get-current-chat-id] + last-outgoing-message [:get-chat-last-outgoing-message @current-chat-id]] (let [contacts' (contacts-by-identity contacts) messages (messages-with-timemarks messages message-extras)] [list-view {:renderRow (fn [row _ index] @@ -160,7 +163,8 @@ :group-chat group-chat :messages-count (count messages) :row row - :index index})) + :index index + :last-outgoing? (= (:message-id last-outgoing-message) (:message-id row))})) :renderScrollComponent #(invertible-scroll-view (js->clj %)) :onEndReached (when-not loaded? #(dispatch [:load-more-messages])) :enableEmptySections true diff --git a/src/status_im/chat/styles/datemark.cljs b/src/status_im/chat/styles/datemark.cljs index c311ef4467..eb892ea66f 100644 --- a/src/status_im/chat/styles/datemark.cljs +++ b/src/status_im/chat/styles/datemark.cljs @@ -1,19 +1,15 @@ -(ns status-im.chat.styles.datemark) +(ns status-im.chat.styles.datemark + (:require [status-im.components.styles :as st])) (def datemark-wrapper {:flex 1 :align-items :center}) (def datemark - {:background-color "#bbc4cb33" - :padding-left 12 - :padding-right 12 - :margin-top 8 - :margin-bottom 8 - :border-radius 12 - :height 24}) + {:opacity 0.5 + :margin-top 20 + :height 20}) (def datemark-text - {:color "#838c93" - :top 4 - :font-size 12}) + {:color st/color-gray4 + :font-size 15}) diff --git a/src/status_im/chat/styles/message.cljs b/src/status_im/chat/styles/message.cljs index e45e0d223e..b322f187a9 100644 --- a/src/status_im/chat/styles/message.cljs +++ b/src/status_im/chat/styles/message.cljs @@ -1,18 +1,22 @@ (ns status-im.chat.styles.message + (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]]) (:require [status-im.components.styles :refer [color-white color-black color-blue + color-light-blue selected-message-color text1-color text2-color - color-gray]] + color-gray + color-gray4]] [status-im.constants :refer [text-content-type content-type-command]])) -(def style-message-text - {:fontSize 14 - :lineHeight 21 - :color text1-color}) +(defstyle style-message-text + {:fontSize 15 + :color text1-color + :android {:line-height 22} + :ios {:line-height 23}}) (def style-sub-text {:top -2 @@ -22,17 +26,17 @@ :height 16}) (defn message-padding-top - [{:keys [new-day same-author same-direction]}] + [{:keys [first-in-date? same-author same-direction]}] (cond - new-day 0 - same-author 4 - same-direction 20 - :else 10)) + first-in-date? 20 + same-author 8 + same-direction 16 + :else 24)) (defn last-message-padding [{:keys [last-message typing]}] (when (and last-message (not typing)) - {:paddingBottom 20})) + {:paddingBottom 16})) (def message-datemark {:margin-top 10 @@ -42,30 +46,21 @@ {:height 16}) (def message-body-base - {:padding-right 8 - :padding-left 8}) + {:padding-right 10 + :padding-left 10}) (defn message-body [{:keys [outgoing] :as message}] - (let [align (if outgoing :flex-end :flex-start)] + (let [align (if outgoing :flex-end :flex-start) + direction (if outgoing :row-reverse :row)] (merge message-body-base - {:flexDirection :column + {:flexDirection direction :width 260 :paddingTop (message-padding-top message) :alignSelf align :alignItems align} (last-message-padding message)))) -(defn incoming-group-message-body-st - [message] - (merge message-body-base - {:flexDirection :row - :alignSelf :flex-start - :marginTop (message-padding-top message) - :paddingRight 8 - :paddingLeft 8} - (last-message-padding message))) - (def selected-message {:marginTop 18 :marginLeft 40 @@ -75,75 +70,72 @@ (def group-message-wrapper {:flexDirection :column}) -(def group-message-view - {:flexDirection :column - :width 260 - :paddingLeft 8 - :alignItems :flex-start}) +(defn group-message-view + [{:keys [outgoing] :as message}] + (let [align (if outgoing :flex-end :flex-start)] + {:flexDirection :column + :width 260 + :padding-left 10 + :padding-right 10 + :alignItems align})) -(def message-author {:width 24}) +(def message-author + {:width 36 + :alignSelf :flex-start}) (def photo-view {:borderRadius 12}) (def photo {:borderRadius 12 - :width 24 - :height 24}) + :width 36 + :height 36}) (def delivery-view {:flexDirection :row - :marginTop 2}) + :marginTop 2 + :opacity 0.5}) -(def delivery-image - {:marginTop 6 - :width 9 - :height 7}) - -(def delivery-text - {:fontSize 12 - :color text2-color - :marginLeft 5}) +(defstyle delivery-text + {:color color-gray4 + :marginLeft 5 + :android {:font-size 13} + :ios {:font-size 14}}) (defn text-message [{:keys [outgoing group-chat incoming-group]}] (merge style-message-text - {:marginTop (if incoming-group - 4 - 0)} - (when (and outgoing group-chat) - {:color color-white}))) + {:marginTop (if incoming-group 4 0)})) -(defn message-view +(defnstyle message-view [{:keys [content-type outgoing group-chat selected]}] - (merge {:borderRadius 14 - :padding 12 - :backgroundColor color-white} + (merge {:padding 12 + :backgroundColor color-white + :android {:border-radius 4} + :ios {:border-radius 8}} (when (= content-type content-type-command) {:paddingTop 10 - :paddingBottom 14}) - (if outgoing - (when (and group-chat (= content-type text-content-type)) - {:backgroundColor color-blue}) - (when selected - {:backgroundColor selected-message-color})))) + :paddingBottom 14}))) -(def author - {:color color-gray}) +(defstyle author + {:color color-gray4 + :margin-bottom 5 + :android {:font-size 13} + :ios {:font-size 14}}) (def comand-request-view {:paddingRight 16}) (def command-request-message-view - {:borderRadius 14 - :padding 12 - :paddingRight 28 - :backgroundColor color-white}) + {:borderRadius 14 + :padding-vertical 10 + :paddingRight 28 + :backgroundColor color-white}) (def command-request-from-text (merge style-sub-text {:marginBottom 2})) -(defn command-request-image-touchable [top-offset?] +(defn command-request-image-touchable [] {:position :absolute - :top (if top-offset? 4 -1) + :top 0 :right -8 :alignItems :center :justifyContent :center @@ -177,14 +169,16 @@ :height 14}) (def content-command-view - {:flexDirection :column}) + {:flexDirection :column + :alignItems :flex-start}) (def command-container {:flexDirection :row + :margin-top 4 :marginRight 32}) (def command-image - {:margin-top 5 + {:margin-top 9 :width 12 :height 13 :tint-color :#a9a9a9cc}) diff --git a/src/status_im/chat/styles/screen.cljs b/src/status_im/chat/styles/screen.cljs index aa7a6229c5..b5528dfc32 100644 --- a/src/status_im/chat/styles/screen.cljs +++ b/src/status_im/chat/styles/screen.cljs @@ -1,9 +1,12 @@ (ns status-im.chat.styles.screen + (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]]) (:require [status-im.components.styles :refer [chat-background selected-message-color separator-color text1-color - text2-color]] + text2-color + text4-color + color-gray6]] [status-im.components.toolbar.styles :refer [toolbar-background1]])) (def chat-view @@ -41,16 +44,15 @@ :width 8 :height 14}) -(defn chat-name-view [show-actions] +(defnstyle chat-name-view [show-actions] {:flex 1 - :margin-bottom 2 :margin-left (if show-actions 16 0) - :align-items :flex-start - :justify-content :center}) + :justify-content :center + :android {:align-items :flex-start} + :ios {:align-items :center}}) (def chat-name-text - {:color text1-color - :margin-top 2 + {:color color-gray6 :fontSize 16}) (def group-icon @@ -63,14 +65,17 @@ {:width 14 :height 8}) -(def members - {:marginTop -0.5 - :marginLeft 4 - :fontSize 12 - :color text2-color}) +(defstyle members + {:color text4-color + :ios {:font-size 14 + :margin-top 4} + :android {:font-size 13}}) -(def last-activity - {:height 18}) +(defstyle last-activity-text + {:color text4-color + :ios {:font-size 14 + :margin-top 4} + :android {:font-size 13}}) (defn actions-wrapper [status-bar-height] {:backgroundColor toolbar-background1 diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index e2615a7821..41cca401ff 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -275,3 +275,11 @@ (let [last-message (subscribe [:get-last-message chat-id])] (reaction (get-in @db [:message-data :short-preview (:message-id @last-message)]))))) + +(register-sub :get-chat-last-outgoing-message + (fn [db [_ chat-id]] + (reaction + (->> (:messages (get-in @db [:chats chat-id])) + (filter :outgoing) + (sort-by :clock-value >) + (first))))) diff --git a/src/status_im/chat/views/message.cljs b/src/status_im/chat/views/message.cljs index fe0f9aec10..4daefe5a15 100644 --- a/src/status_im/chat/views/message.cljs +++ b/src/status_im/chat/views/message.cljs @@ -1,7 +1,6 @@ (ns status-im.chat.views.message (:require-macros [status-im.utils.views :refer [defview]]) - (:require [clojure.string :as s] - [re-frame.core :refer [subscribe dispatch]] + (:require [re-frame.core :refer [subscribe dispatch]] [reagent.core :as r] [status-im.i18n :refer [message-status-label]] [status-im.components.react :refer [view @@ -41,6 +40,14 @@ (def window-width (:width (get-dimensions "window"))) +(defview message-author-name [{:keys [outgoing from] :as message}] + [current-account [:get-current-account] + incoming-name [:contact-name-by-identity from]] + (if-let [name (if outgoing + (:name current-account) + (or incoming-name "Unknown contact"))] + [text {:style st/author} name])) + (defn message-content-status [_] (let [{:keys [chat-id group-chat name color]} (subscribe [:chat-properties [:chat-id :group-chat :name :color]]) members (subscribe [:current-chat-contacts])] @@ -143,28 +150,16 @@ :current-chat-id current-chat-id}]])) (defn message-view - [{:keys [username same-author index] :as message} content] + [{:keys [same-author index group-chat] :as message} content] [view (st/message-view message) - (when (and username (or (= 1 index) (not same-author))) - [text {:style st/author} username]) + (when group-chat [message-author-name message]) content]) -(defmulti message-content (fn [_ message _] - (message :content-type))) - -(defmethod message-content content-type-command-request - [wrapper message] - [wrapper message [message-content-command-request message]]) - -(defmethod message-content c/content-type-wallet-request - [wrapper message] - [wrapper message [message-content-command-request message]]) - (def replacements {"\\*[^*]+\\*" {:font-weight :bold} "~[^~]+~" {:font-style :italic}}) -(def regx (re-pattern (s/join "|" (map first replacements)))) +(def regx (re-pattern (str/join "|" (map first replacements)))) (defn get-style [string] (->> replacements @@ -179,7 +174,7 @@ ;; todo rewrite this, naive implementation (defn- parse-text [string] (if (string? string) - (let [general-text (s/split string regx) + (let [general-text (str/split string regx) general-text' (if (zero? (count general-text)) [nil] general-text) @@ -205,13 +200,23 @@ simple-text? (= (count parsed-text) 2)] (if simple-text? [autolink {:style (st/text-message message) - :font :default :text (apply str parsed-text) :onPress #(browse %)}] - [text {:style (st/text-message message) - :font :default} + [text {:style (st/text-message message)} (parse-text content)]))]) +(defmulti message-content (fn [_ message _] (message :content-type))) + +(defmethod message-content content-type-command-request + [wrapper message] + [wrapper message + [message-view message [message-content-command-request message]]]) + +(defmethod message-content c/content-type-wallet-request + [wrapper message] + [wrapper message + [message-view message [message-content-command-request message]]]) + (defmethod message-content text-content-type [wrapper message] [wrapper message [text-message message]]) @@ -251,11 +256,6 @@ (if (or (zero? (count user-statuses)) seen-by-everyone?) [view st/delivery-view - [image {:source (case status - :seen {:uri :icon_ok_small_copy_2} - :failed res/delivery-failed-icon - nil) - :style st/delivery-image}] [text {:style st/delivery-text :font :default} (message-status-label @@ -295,11 +295,6 @@ :else (or delivery-status message-status app-db-message-status-value :sending))] [view st/delivery-view - [image {:source (case status - :seen {:uri :icon_ok_small_copy_2} - :failed res/delivery-failed-icon - nil) - :style st/delivery-image}] [text {:style st/delivery-text :font :default} (message-status-label status)]])) @@ -307,37 +302,26 @@ (defview member-photo [from] [photo-path [:photo-path from]] [view st/photo-view - [image {:source {:uri (if (s/blank? photo-path) + [image {:source {:uri (if (str/blank? photo-path) (identicon from) photo-path)} :style st/photo}]]) -(defn incoming-group-message-body - [{:keys [selected same-author from index] :as message} content] +(defn message-body + [{:keys [last-outgoing? message-type same-author from index] :as message} content] (let [delivery-status :seen-by-everyone] [view st/group-message-wrapper - (when selected - [text {:style st/selected-message - :font :default} - "Mar 7th, 15:22"]) - [view (st/incoming-group-message-body-st message) + [view (st/message-body message) [view st/message-author - (when (or (= index 1) - (not same-author)) [member-photo from])] - [view st/group-message-view + (when (and (or (= index 1) (not same-author)) + (not= from "me")) + [member-photo from])] + [view (st/group-message-view message) content - ;; TODO show for last or selected - (when (and selected delivery-status) - [message-delivery-status message])]]])) - -(defn message-body - [{:keys [outgoing message-type] :as message} content] - [view (st/message-body message) - content - (when outgoing - (if (= (keyword message-type) :group-user-message) - [group-message-delivery-status message] - [message-delivery-status message]))]) + (when last-outgoing? + (if (= (keyword message-type) :group-user-message) + [group-message-delivery-status message] + [message-delivery-status message]))]]])) (defn message-container-animation-logic [{:keys [to-value val callback]}] (fn [_] @@ -399,8 +383,5 @@ #(share content (label :t/message)))} [view (let [incoming-group (and group-chat (not outgoing))] - [message-content - (if incoming-group - incoming-group-message-body - message-body) - (merge message {:incoming-group incoming-group})])]]])}))) + [message-content message-body (merge message + {:incoming-group incoming-group})])]]])}))) diff --git a/src/status_im/chat/views/request_message.cljs b/src/status_im/chat/views/request_message.cljs index 725b4c52b0..5903c61f65 100644 --- a/src/status_im/chat/views/request_message.cljs +++ b/src/status_im/chat/views/request_message.cljs @@ -41,7 +41,7 @@ (anim/start (button-animation val min-scale loop? answered?))))) -(defn request-button [message-id _ _ top-offset?] +(defn request-button [message-id _ _] (let [scale-anim-val (anim/create-value min-scale) answered? (subscribe [:is-request-answered? message-id]) loop? (r/atom true) @@ -60,7 +60,7 @@ [touchable-highlight {:on-press (when (and (not @answered?) status-initialized?) #(set-chat-command message-id command)) - :style (st/command-request-image-touchable top-offset?) + :style (st/command-request-image-touchable) :accessibility-label (id/chat-request-message-button (:name command))} [animated-view {:style (st/command-request-image-view command scale-anim-val)} (when command-icon @@ -68,8 +68,7 @@ (defn message-content-command-request [{:keys [message-id _ _ _]}] - (let [top-offset (r/atom {:specified? false}) - commands-atom (subscribe [:get-responses]) + (let [commands-atom (subscribe [:get-responses]) answered? (subscribe [:is-request-answered? message-id]) status-initialized? (subscribe [:get :status-module-initialized?]) preview (subscribe [:get-in [:message-data :preview message-id]])] @@ -85,19 +84,10 @@ {:on-press (when (and (not @answered?) @status-initialized?) #(set-chat-command message-id command))} [view st/command-request-message-view - (when incoming-group - [text {:style st/command-request-from-text - :font :default} - from]) (if (and @preview (not (string? @preview))) [view @preview] [text {:style st/style-message-text - :on-layout #(reset! top-offset {:specified? true - :value (-> (.-nativeEvent %) - (.-layout) - (.-height) 
 - (> 25))}) :font :default} (or @preview content)])]] (when (:request-text command) @@ -105,5 +95,4 @@ [text {:style st/style-sub-text :font :default} (:request-text command)]]) - (when (:specified? @top-offset) - [request-button message-id command @status-initialized? (:value @top-offset)])])))) + [request-button message-id command @status-initialized?]])))) diff --git a/src/status_im/chat/views/toolbar_content.cljs b/src/status_im/chat/views/toolbar_content.cljs index 999f896d79..ab704e362f 100644 --- a/src/status_im/chat/views/toolbar_content.cljs +++ b/src/status_im/chat/views/toolbar_content.cljs @@ -10,7 +10,6 @@ label label-pluralize]] [status-im.chat.styles.screen :as st] - [status-im.components.refreshable-text.view :refer [refreshable-text]] [status-im.utils.datetime :as time] [status-im.utils.platform :refer [platform-specific]] [status-im.utils.gfycat.core :refer [generate-gfy]] @@ -41,13 +40,11 @@ (defview last-activity [{:keys [online-text sync-state]}] [state [:get :sync-data]] - [refreshable-text {:style st/last-activity - :text-style (get-in platform-specific [:component-styles :toolbar-last-activity]) - :font :default - :value (case sync-state - :in-progress (in-progress-text state) - :synced (label :t/sync-synced) - online-text)}]) + [text {:style st/last-activity-text} + (case sync-state + :in-progress (in-progress-text state) + :synced (label :t/sync-synced) + online-text)]) (defn group-last-activity [{:keys [contacts sync-state public?]}] (if (or (= sync-state :in-progress) @@ -55,13 +52,10 @@ [last-activity {:sync-state sync-state}] (if public? [view {:flex-direction :row} - [text {:font :default - :style (get-in platform-specific [:component-styles :toolbar-last-activity])} + [text {:style (get-in platform-specific [:component-styles :toolbar-last-activity])} (label :t/public-group-status)]] [view {:flex-direction :row} - [icon :group st/group-icon] - [text {:style st/members - :font :medium} + [text {:style st/members} (if public? (label :t/public-group-status) (let [cnt (inc (count contacts))] diff --git a/src/status_im/components/styles.cljs b/src/status_im/components/styles.cljs index 84844787bb..142b2d7d28 100644 --- a/src/status_im/components/styles.cljs +++ b/src/status_im/components/styles.cljs @@ -10,6 +10,7 @@ (def color-gray3 "#00000040") (def color-gray4 "#939ba1") (def color-gray5 "#d9dae1") +(def color-gray6 "#212121") (def color-steel "#838b91") (def color-white "white") (def color-light-blue "#628fe3") diff --git a/src/status_im/contacts/subs.cljs b/src/status_im/contacts/subs.cljs index cabc09d707..565b23483e 100644 --- a/src/status_im/contacts/subs.cljs +++ b/src/status_im/contacts/subs.cljs @@ -156,6 +156,11 @@ (fn [db [_ identity]] (reaction (get-in @db [:contacts identity])))) +(register-sub :contact-name-by-identity + (fn [db [_ identity]] + (let [contacts (subscribe [:get-contacts])] + (reaction (:name (@contacts identity)))))) + (register-sub :all-new-contacts (fn [db _] (contacts-by-current-chat remove db))) diff --git a/src/status_im/ios/platform.cljs b/src/status_im/ios/platform.cljs index deecaafa11..0efffddf12 100644 --- a/src/status_im/ios/platform.cljs +++ b/src/status_im/ios/platform.cljs @@ -174,10 +174,6 @@ :toolbar-border {:height 1 :background-color styles/color-gray5 :opacity 0.5} - :toolbar-last-activity {:color styles/text2-color - :background-color :transparent - :top 0 - :font-size 14} :text-field-focus-line-height 1}) (def fonts @@ -223,4 +219,3 @@ :public-group-icon-container {:margin-top 2} :private-group-icon-container {:margin-top 2} :public-group-chat-hash-style {:top 6 :left 3}}) - diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index 8e5b1e8c20..b95cbc2392 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -25,8 +25,8 @@ :members {:one "1 member" :other "{{count}} members" :zero "no members"} - :members-active {:one "1 member, 1 active" - :other "{{count}} members, {{count}} active" + :members-active {:one "1 member" + :other "{{count}} members" :zero "no members"} :public-group-status "Public" :active-online "Online"