diff --git a/src/status_im/chat/styles/message/message.cljs b/src/status_im/chat/styles/message/message.cljs index e32ae99052..7ea47ffa4c 100644 --- a/src/status_im/chat/styles/message/message.cljs +++ b/src/status_im/chat/styles/message/message.cljs @@ -1,10 +1,10 @@ (ns status-im.chat.styles.message.message (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]]) (:require [status-im.ui.components.styles :as styles] + [status-im.chat.styles.photos :as photos] [status-im.ui.components.colors :as colors] [status-im.constants :as constants])) -(def photo-size 36) (defstyle style-message-text {:font-size 15 @@ -48,13 +48,18 @@ :align-self align :align-items align}))) -(def message-timestamp - {:margin-left 5 - :margin-right 5 - :margin-bottom -2 - :color colors/gray - :opacity 0.5 - :align-self :flex-end}) +(defn message-timestamp [justify-timestamp?] + (merge {:color colors/gray + :font-size 10 + :align-self :flex-end + :opacity 0.5} + (when justify-timestamp? {:position :absolute + :bottom 10 + :right 12}))) + +(def message-timestamp-placeholder + (assoc (message-timestamp false) + :color styles/color-white)) (def selected-message {:margin-top 18 @@ -83,14 +88,9 @@ :padding-right 22}) (def message-author - {:width photo-size + {:width photos/photo-size :align-self :flex-end}) -(def photo - {:border-radius (/ photo-size 2) - :width photo-size - :height photo-size}) - (def delivery-view {:flex-direction :row :margin-top 2 @@ -136,8 +136,10 @@ (defn message-view [{:keys [content-type outgoing group-chat selected]}] - (merge {:padding 12 - :border-radius 8} + (merge {:padding-top 6 + :padding-horizontal 12 + :padding-bottom 8 + :border-radius 8} (when-not (= content-type constants/content-type-emoji) {:background-color styles/color-white}) (when (= content-type constants/content-type-command) diff --git a/src/status_im/chat/styles/photos.cljs b/src/status_im/chat/styles/photos.cljs new file mode 100644 index 0000000000..d8f47c90b7 --- /dev/null +++ b/src/status_im/chat/styles/photos.cljs @@ -0,0 +1,8 @@ +(ns status-im.chat.styles.photos) + +(def photo-size 36) + +(def photo + {:border-radius (/ photo-size 2) + :width photo-size + :height photo-size}) diff --git a/src/status_im/chat/styles/screen.cljs b/src/status_im/chat/styles/screen.cljs index fd9d9f954e..01b847e5a5 100644 --- a/src/status_im/chat/styles/screen.cljs +++ b/src/status_im/chat/styles/screen.cljs @@ -12,7 +12,8 @@ :background-color component.styles/chat-background}) (def toolbar-container - {}) + {:flex 1 + :flex-direction :row}) (def messages-container {:flex 1 diff --git a/src/status_im/chat/views/message/message.cljs b/src/status_im/chat/views/message/message.cljs index 358bf26ae5..4eda4f1eb8 100644 --- a/src/status_im/chat/views/message/message.cljs +++ b/src/status_im/chat/views/message/message.cljs @@ -13,6 +13,7 @@ [status-im.chat.styles.message.message :as style] [status-im.chat.styles.message.command-pill :as pill-style] [status-im.chat.views.message.request-message :as request-message] + [status-im.chat.views.photos :as photos] [status-im.constants :as constants] [status-im.ui.components.chat-icon.screen :as chat-icon.screen] [status-im.utils.core :as utils] @@ -22,8 +23,7 @@ [status-im.i18n :as i18n] [status-im.ui.components.colors :as colors] [clojure.string :as string] - [status-im.chat.events.console :as console] - [status-im.react-native.resources :as resources])) + [status-im.chat.events.console :as console])) (def window-width (:width (react/get-dimensions "window"))) @@ -81,10 +81,14 @@ :font :default} (or preview (str params))])]))) +(defview message-timestamp [t justify-timestamp?] + [react/text {:style (style/message-timestamp justify-timestamp?)} t]) + (defn message-view - [{:keys [group-chat] :as message} content] + [{:keys [timestamp-str] :as message} content {:keys [justify-timestamp?]}] [react/view (style/message-view message) - content]) + content + [message-timestamp timestamp-str justify-timestamp?]]) (def replacements {"\\*[^*]+\\*" {:font-weight :bold} @@ -162,18 +166,22 @@ (autolink string event-on-press))) text-seq)))) +; We can't use CSS as nested Text element don't accept margins nor padding +; so we pad the invisible placeholder with some spaces to avoid having too +; close to the text. +(defn timestamp-with-padding [t] + (str " " t)) + (def cached-parse-text (memoize parse-text)) (defn text-message - [{:keys [content] :as message}] + [{:keys [content timestamp-str] :as message}] [message-view message (let [parsed-text (cached-parse-text content :browse-link-from-message)] - [react/text {:style (style/text-message message)} parsed-text])]) - -(defn placeholder-message - [{:keys [content] :as message}] - [message-view message - [react/text {:style (style/text-message message)} content]]) + [react/text {:style (style/text-message message)} + parsed-text + [react/text {:style style/message-timestamp-placeholder} (timestamp-with-padding timestamp-str)]]) + {:justify-timestamp? true}]) (defn emoji-message [{:keys [content] :as message}] @@ -204,10 +212,6 @@ [wrapper message [message-view message [message-content-command message]]]) -(defmethod message-content constants/content-type-placeholder - [wrapper message] - [wrapper message [placeholder-message message]]) - (defmethod message-content constants/content-type-emoji [wrapper message] [wrapper message [emoji-message message]]) @@ -293,29 +297,6 @@ (when outgoing [text-status status])))))) -(defn- photo [from photo-path] - [react/view - [react/image {:source (if (and (not (string/blank? photo-path)) - (string/starts-with? photo-path "contacts://")) - (->> (string/replace photo-path #"contacts://" "") - (keyword) - (get resources/contacts)) - {:uri photo-path}) - :style style/photo}]]) - -(defview member-photo [from] - (letsubs [photo-path [:get-photo-path from]] - (photo from (if (string/blank? photo-path) - (identicon/identicon from) - photo-path)))) - -(defview my-photo [from] - (letsubs [{:keys [photo-path]} [:get-current-account]] - (photo from photo-path))) - -(defview message-timestamp [t] - [react/text {:style style/message-timestamp} t]) - (defview message-author-name [from message-username] (letsubs [username [:get-contact-name-by-identity from]] [react/text {:style style/message-author-name} (or username @@ -323,21 +304,21 @@ (gfycat/generate-gfy from))])) ; TODO: We defensively generate the name for now, to be revisited when new protocol is defined (defn message-body - [{:keys [timestamp-str last-in-group? first-in-group? from outgoing username] :as message} content] + [{:keys [last-in-group? first-in-group? group-chat from outgoing username] :as message} content] [react/view (style/group-message-wrapper message) [react/view (style/message-body message) - (when (not outgoing) + (when (and (not outgoing) + group-chat) [react/view style/message-author (when last-in-group? [react/touchable-highlight {:on-press #(re-frame/dispatch [:show-profile from])} [react/view - [member-photo from]]])]) + [photos/member-photo from]]])]) [react/view (style/group-message-view outgoing) (when first-in-group? [message-author-name from username]) [react/view {:style (style/timestamp-content-wrapper message)} - content - [message-timestamp timestamp-str]]]] + content]]] [react/view style/delivery-status [message-delivery-status message]]]) diff --git a/src/status_im/chat/views/photos.cljs b/src/status_im/chat/views/photos.cljs new file mode 100644 index 0000000000..a810ba5333 --- /dev/null +++ b/src/status_im/chat/views/photos.cljs @@ -0,0 +1,23 @@ +(ns status-im.chat.views.photos + (:require-macros [status-im.utils.views :refer [defview letsubs]]) + (:require [status-im.ui.components.react :as react] + [status-im.chat.styles.photos :as style] + [status-im.utils.identicon :as identicon] + [clojure.string :as string] + [status-im.react-native.resources :as resources])) + +(defn- photo [from photo-path] + [react/view + [react/image {:source (if (and (not (string/blank? photo-path)) + (string/starts-with? photo-path "contacts://")) + (->> (string/replace photo-path #"contacts://" "") + (keyword) + (get resources/contacts)) + {:uri photo-path}) + :style style/photo}]]) + +(defview member-photo [from] + (letsubs [photo-path [:get-photo-path from]] + (photo from (if (string/blank? photo-path) + (identicon/identicon from) + photo-path)))) diff --git a/src/status_im/chat/views/toolbar_content.cljs b/src/status_im/chat/views/toolbar_content.cljs index c5a80a2dd7..552268c0ce 100644 --- a/src/status_im/chat/views/toolbar_content.cljs +++ b/src/status_im/chat/views/toolbar_content.cljs @@ -5,6 +5,7 @@ [status-im.ui.components.react :as react] [status-im.i18n :as i18n] + [status-im.chat.views.photos :as photos] [status-im.chat.styles.screen :as st] [status-im.utils.datetime :as time] [status-im.utils.platform :refer [platform-specific]] @@ -60,17 +61,19 @@ (i18n/label-pluralize cnt :t/members-active)))]]))) (defview toolbar-content-view [] - (letsubs [{:keys [group-chat name chat-id - contacts public? public-key]} [:get-current-chat] + (letsubs [{:keys [group-chat name contacts + public? chat-id]} [:get-current-chat] show-actions? [:get-current-chat-ui-prop :show-actions?] accounts [:get-accounts] - contact [:get-current-chat-contact] + contact [:get-current-chat-contact] sync-state [:sync-state]] - [react/view common.styles/flex + [react/view {:style st/toolbar-container} + + [react/view (when-not group-chat [photos/member-photo chat-id])] [react/view (st/chat-name-view (or (empty? accounts) show-actions?)) (let [chat-name (if (string/blank? name) - (generate-gfy public-key) + (generate-gfy chat-id) (or (i18n/get-contact-translated chat-id :name name) (i18n/label :t/chat-name)))] [react/text {:style st/chat-name-text