Show timestamp inside bubble for text messages

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2018-04-23 17:46:27 +01:00
parent 3b4d7a6a62
commit 4aaecf792b
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
6 changed files with 83 additions and 65 deletions

View File

@ -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)

View File

@ -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})

View File

@ -12,7 +12,8 @@
:background-color component.styles/chat-background})
(def toolbar-container
{})
{:flex 1
:flex-direction :row})
(def messages-container
{:flex 1

View File

@ -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]]])

View File

@ -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))))

View File

@ -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