From 65a36836d4eb5661daede89807d9646e01138638 Mon Sep 17 00:00:00 2001 From: Volodymyr Kozieiev Date: Fri, 5 May 2023 15:42:44 +0100 Subject: [PATCH] Last message preview improvings --- src/status_im/data_store/chats.cljs | 14 +- src/status_im/data_store/messages.cljs | 3 +- .../chat/home/chat_list_item/view.cljs | 213 ++++++++++++------ status-go-version.json | 6 +- translations/en.json | 29 ++- 5 files changed, 192 insertions(+), 73 deletions(-) diff --git a/src/status_im/data_store/chats.cljs b/src/status_im/data_store/chats.cljs index d4fc33d320b5..b3eaa514e733 100644 --- a/src/status_im/data_store/chats.cljs +++ b/src/status_im/data_store/chats.cljs @@ -91,10 +91,16 @@ :chat-type (.-chatType chat) :unviewed-messages-count (.-unviewedMessagesCount chat) :unviewed-mentions-count (.-unviewedMentionsCount chat) - :last-message {:content {:text (.-text chat) - :parsed-text (types/js->clj (.-parsedText chat))} - :content-type (.-contentType chat) - :community-id (.-contentCommunityId chat)} + :last-message {:content {:text (.-text chat) + :parsed-text (types/js->clj (.-parsedText chat)) + :response-to (.-responseTo chat)} + :content-type (.-contentType chat) + :community-id (.-contentCommunityId chat) + :outgoing (boolean (.-outgoingStatus chat)) + :album-images-count (.-albumImagesCount chat) + :from (.-from chat) + :deleted? (.-deleted chat) + :deleted-for-me? (.-deletedForMe chat)} :last-clock-value (.-lastClockValue chat) :profile-public-key (.-profile chat) :highlight (.-highlight chat) diff --git a/src/status_im/data_store/messages.cljs b/src/status_im/data_store/messages.cljs index 9660a1d174e8..d273a4c0627f 100644 --- a/src/status_im/data_store/messages.cljs +++ b/src/status_im/data_store/messages.cljs @@ -42,7 +42,8 @@ :imageWidth :image-width :imageHeight :image-height :new :new? - :albumImagesCount :album-images-count}) + :albumImagesCount :album-images-count + :displayName :display-name}) (update :quoted-message set/rename-keys diff --git a/src/status_im2/contexts/chat/home/chat_list_item/view.cljs b/src/status_im2/contexts/chat/home/chat_list_item/view.cljs index 4f80ad8c8058..7d6cb6fd6028 100644 --- a/src/status_im2/contexts/chat/home/chat_list_item/view.cljs +++ b/src/status_im2/contexts/chat/home/chat_list_item/view.cljs @@ -1,12 +1,14 @@ (ns status-im2.contexts.chat.home.chat-list-item.view - (:require [clojure.string :as string] - [quo2.core :as quo] + (:require [quo2.core :as quo] [quo2.foundations.colors :as colors] [react-native.core :as rn] [utils.datetime :as datetime] - [status-im2.common.home.actions.view :as actions] ;;TODO move to status-im2 + [status-im2.common.home.actions.view :as actions] [status-im2.contexts.chat.home.chat-list-item.style :as style] - [utils.re-frame :as rf])) + [utils.re-frame :as rf] + [status-im2.constants :as constants] + [clojure.string :as string] + [utils.i18n :as i18n])) (def max-subheader-length 50) @@ -16,61 +18,149 @@ (rf/dispatch [:dismiss-keyboard]) (rf/dispatch [:chat/navigate-to-chat chat-id]))) -(defn truncate-literal - [literal] - (when literal - (let [size (min max-subheader-length (.-length literal))] - {:components (.substring literal 0 size) - :length size}))) - -(defn add-parsed-to-subheader - [acc {:keys [type destination literal children]}] - (let [result (case type - "paragraph" - (reduce - (fn [{:keys [_ length] :as acc-paragraph} parsed-child] - (if (>= length max-subheader-length) - (reduced acc-paragraph) - (add-parsed-to-subheader acc-paragraph parsed-child))) - {:components [quo/text] - :length 0} - children) - - "mention" - {:components [quo/text (rf/sub [:messages/resolve-mention literal])] - :length 4} ;; we can't predict name length so take the - ;; smallest possible - - "status-tag" - (truncate-literal (str "#" literal)) - - "link" - (truncate-literal destination) - - (truncate-literal literal))] - {:components (conj (:components acc) (:components result)) - :length (+ (:length acc) (:length result))})) - -(defn render-subheader - "Render the preview of a last message to a maximum of max-subheader-length characters" +(defn parsed-text-to-one-line [parsed-text] - (let [result - (reduce - (fn [{:keys [_ length] :as acc-text} new-text-chunk] - (if (>= length max-subheader-length) - (reduced acc-text) - (add-parsed-to-subheader acc-text new-text-chunk))) - {:components [quo/text - {:size :paragraph-2 - :style {:color (colors/theme-colors colors/neutral-50 - colors/neutral-40) - :width "90%"} - :number-of-lines 1 - :ellipsize-mode :tail - :accessibility-label :chat-message-text}] - :length 0} - parsed-text)] - (:components result))) + (reduce + (fn [acc {:keys [type literal children destination]}] + (case type + "paragraph" + (str acc (parsed-text-to-one-line children) " ") + + "mention" + (str acc "@" (rf/sub [:messages/resolve-mention literal])) + + "status-tag" + (str acc literal) + + "link" + (str acc destination) + + (str acc (string/replace literal #"\n" " ")))) + "" + parsed-text)) + +(defn extract-text-from-message + [{:keys [content]}] + (let [{:keys [parsed-text text]} content] + (if parsed-text + (parsed-text-to-one-line parsed-text) + (if text + (string/replace text #"\n" " ") + text)))) + +(defn preview-text-from-content + [group-chat primary-name {:keys [content-type album-images-count content outgoing] :as message}] + (let [content-text (extract-text-from-message message) + reply? (not (string/blank? (:response-to content))) + author (if outgoing + :you + (if group-chat + :other-person + :dont-show)) + preview-text + (case content-type + constants/content-type-text + (if reply? + (case author + :you (str (i18n/label :t/you-replied) ": " content-text) + :other-person (str (i18n/label :t/user-replied {:user primary-name}) ": " content-text) + :dont-show (str (i18n/label :t/replied) ": " content-text) + (str (i18n/label :t/replied) ": " content-text)) + (case author + :you (str (i18n/label :t/You) ": " content-text) + :other-person (str primary-name ": " content-text) + :dont-show content-text + content-text)) + + constants/content-type-emoji + (case author + :you (str (i18n/label :t/You) ": " content-text) + :other-person (str primary-name ": " content-text) + :dont-show content-text + content-text) + + constants/content-type-system-text + (case author + :you (i18n/label :t/you-pinned-a-message) + :other-person (i18n/label :t/user-pinned-a-message {:user primary-name}) + :dont-show (i18n/label :t/Pinned-a-message) + (i18n/label :t/Pinned-a-message)) + + constants/content-type-sticker + (case author + :you (i18n/label :t/you-sent-a-sticker) + :other-person (i18n/label :t/user-sent-a-sticker {:user primary-name}) + :dont-show (i18n/label :t/sent-a-sticker) + (i18n/label :t/sent-a-sticker)) + + constants/content-type-image + (let [sent-photos (if album-images-count + (case author + :you (i18n/label :t/you-sent-n-photos + {:number album-images-count}) + :other-person (i18n/label :t/user-sent-n-photos + {:number album-images-count + :user primary-name}) + :dont-show (i18n/label :t/sent-n-photos {:number album-images-count}) + (i18n/label :t/sent-n-photos {:number album-images-count})) + (case author + :you (i18n/label :t/you-sent-a-photo) + :other-person (i18n/label :t/user-sent-a-photo {:user primary-name}) + :dont-show (i18n/label :t/sent-a-photo) + (i18n/label :t/sent-a-photo)))] + (if (not (string/blank? content-text)) + (str sent-photos ": " content-text) + sent-photos)) + + constants/content-type-audio + (case author + :you (i18n/label :t/you-sent-audio-message) + :other-person (i18n/label :t/user-sent-audio-message {:user primary-name}) + :dont-show (i18n/label :t/sent-audio-message) + (i18n/label :t/sent-audio-message)) + + constants/content-type-gif + (case author + :you (i18n/label :t/you-sent-a-gif) + :other-person (i18n/label :t/user-sent-audio-message {:user primary-name}) + :dont-show (i18n/label :t/sent-a-gif) + (i18n/label :t/sent-a-gif)) + + constants/content-type-community + (case author + :you (i18n/label :t/you-shared-a-community) + :other-person (i18n/label :t/user-shared-a-community {:user primary-name}) + :dont-show (i18n/label :t/shared-a-community) + (i18n/label :t/shared-a-community)) + + "")] + (subs preview-text 0 (min (count preview-text) max-subheader-length)))) + + +(defn last-message-preview + "Render the preview of a last message to a maximum of max-subheader-length characters" + [group-chat {:keys [deleted? outgoing from deleted-for-me?] :as message}] + (let [[primary-name _] (rf/sub [:contacts/contact-two-names-by-identity from]) + preview-text (if deleted-for-me? + (i18n/label :t/you-deleted-a-message) + (if deleted? + (if outgoing + (i18n/label :t/you-deleted-a-message) + (if group-chat + (i18n/label :t/user-deleted-a-message {:user primary-name}) + (i18n/label :t/this-message-was-deleted))) + (preview-text-from-content group-chat primary-name message)))] + [quo/text + {:size :paragraph-2 + :style {:color (colors/theme-colors colors/neutral-50 + colors/neutral-40) + :flex 1 + :margin-right 20} + :number-of-lines 1 + :ellipsize-mode :tail + :accessibility-label :chat-message-text} + preview-text])) + (defn verified-or-contact-icon [{:keys [ens-verified added?]}] @@ -136,12 +226,7 @@ :color color}] [rn/view {:style {:margin-left 8}} [name-view display-name contact timestamp] - (if (string/blank? (get-in last-message [:content :parsed-text])) - [quo/text - {:size :paragraph-2 - :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} - (get-in last-message [:content :text])] - [render-subheader (get-in last-message [:content :parsed-text])])] + [last-message-preview group-chat last-message]] (when-not muted (if (> unviewed-mentions-count 0) [quo/info-count {:style {:top 16}} diff --git a/status-go-version.json b/status-go-version.json index df2f3f637c40..2b65755eb70f 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -3,7 +3,7 @@ "_comment": "Instead use: scripts/update-status-go.sh ", "owner": "status-im", "repo": "status-go", - "version": "v0.148.3", - "commit-sha1": "8608aecdb495b59176afa2609c6c8efb6284cef7", - "src-sha256": "0wai1cq0mwrc6757kiyismd08fv1xzjiw99r8y31x7nrfyfl5x6l" + "version": "chat_preview_fields", + "commit-sha1": "40f3a15033ca2f4597578a93f90fb73831bcb56a", + "src-sha256": "1289r2xwmnl508qdyvryj9bk5p7fw1mw75y6xwn2wgy6yqyjwx1w" } diff --git a/translations/en.json b/translations/en.json index a9b634f543d5..a880602ddc29 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2088,5 +2088,32 @@ "community-request-pending-body-text": "You requested to join", "community-kicked-heading": "Kicked from community", "community-kicked-body": "You were kicked from", - "error-loading-audio": "Error while loading audio" + "error-loading-audio": "Error while loading audio", + "you-colon": "You:", + "you-replied": "You replied", + "user-replied": "{{user}} replied", + "you-pinned-a-message": "You pinned a message", + "Pinned-a-message": "Pinned a message", + "user-pinned-a-message": "{{user}} pinned a message", + "you-sent-a-sticker": "You sent a Sticker", + "sent-a-sticker": "Sent a Sticker", + "user-sent-a-sticker": "{{user}} sent a Sticker", + "you-sent-a-photo": "You sent a photo", + "sent-a-photo": "Sent a photo", + "user-sent-a-photo": "{{user}} sent a photo", + "you-sent-n-photos": "You sent {{number}} photos", + "sent-n-photos": "Sent {{number}} photos", + "user-sent-n-photos": "{{user}} sent {{number}} photos", + "you-sent-audio-message": "You sent audio message", + "sent-audio-message": "Sent audio message", + "user-sent-audio-message": "{{user}} sent audio message", + "you-sent-a-gif": "You sent a GIF", + "sent-a-gif": "Sent a GIF", + "user-sent-a-gif": "{{user}} sent a GIF", + "you-shared-a-community": "You shared a community", + "shared-a-community": "Shared a community", + "user-shared-a-community": "{{user}} shared a community", + "you-deleted-a-message": "You deleted a message", + "this-message-was-deleted": "This message was deleted", + "user-deleted-a-message": "{{user}} deleted a message" }