[Feature] Implement replies notification in Activity Center (#14656)

* [Feature][#14550] Added Replies UI in Activity Center

* [Fix][#14550] Removed underlay color from touchables in Replies UI in Activity Center

* [Fix][#14550] Comments from review

* [Fix][#14550] Comments from review

* [Feature][#14550] Added community support on tags in AC

* [Feature][#14550] Date utils test
This commit is contained in:
Mohamed Javid 2023-01-04 19:01:37 +05:30 committed by GitHub
parent ec15232af8
commit e30f895fe9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 120 additions and 36 deletions

View File

@ -81,19 +81,21 @@
context)))) context))))
(defn- activity-message (defn- activity-message
[{:keys [title body]}] [{:keys [title body title-number-of-lines body-number-of-lines]}]
[rn/view {:style style/message-container} [rn/view {:style style/message-container}
(when title (when title
[text/text [text/text
{:size :paragraph-2 {:size :paragraph-2
:accessibility-label :activity-message-title :accessibility-label :activity-message-title
:style style/message-title} :style style/message-title
:number-of-lines title-number-of-lines}
title]) title])
(if (string? body) (if (string? body)
[text/text [text/text
{:style style/message-body {:style style/message-body
:accessibility-label :activity-message-body :accessibility-label :activity-message-body
:size :paragraph-1} :size :paragraph-1
:number-of-lines body-number-of-lines}
body] body]
body)]) body)])

View File

@ -17,7 +17,7 @@
;; `:chat.ui/navigate-to-chat`, otherwise the chat screen ;; `:chat.ui/navigate-to-chat`, otherwise the chat screen
;; looks completely broken if it has never been opened ;; looks completely broken if it has never been opened
;; before for the accepted contact. ;; before for the accepted contact.
[rn/touchable-without-feedback [rn/touchable-opacity
{:on-press (fn [] {:on-press (fn []
(rf/dispatch [:hide-popover]) (rf/dispatch [:hide-popover])
(rf/dispatch [:contact.ui/send-message-pressed (rf/dispatch [:contact.ui/send-message-pressed

View File

@ -9,12 +9,19 @@
[status-im2.contexts.activity-center.notification.mentions.style :as style] [status-im2.contexts.activity-center.notification.mentions.style :as style]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
(def tag-params
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/tag
:text-style style/tag-text})
(defn message-body (defn message-body
[message] [message]
(let [parsed-text (get-in message [:content :parsed-text]) (let [parsed-text (get-in message [:content :parsed-text])
parsed-text-children (:children (first parsed-text))] parsed-text-children (:children (first parsed-text))]
(into [quo/text (into [quo/text
{:number-of-lines 2 {:number-of-lines 1
:style style/tag-text :style style/tag-text
:accessibility-label :activity-message-body :accessibility-label :activity-message-body
:size :paragraph-1}] :size :paragraph-1}]
@ -29,25 +36,25 @@
parsed-text-children)))) parsed-text-children))))
(defn view (defn view
[{:keys [author chat-name chat-id message] :as notification}] [{:keys [author chat-name chat-id message read timestamp]}]
[rn/touchable-without-feedback (let [chat (rf/sub [:chats/chat chat-id])
community-id (:community-id chat)
is-chat-from-community? (not (nil? community-id))
community (rf/sub [:communities/community community-id])
community-name (:name community)
community-image (get-in community [:images :thumbnail :uri])]
[rn/touchable-opacity
{:on-press (fn [] {:on-press (fn []
(rf/dispatch [:hide-popover]) (rf/dispatch [:hide-popover])
(rf/dispatch [:chat.ui/navigate-to-chat chat-id]))} (rf/dispatch [:chat.ui/navigate-to-chat chat-id]))}
[quo/activity-log [quo/activity-log
{:title (i18n/label :t/mention) {:title (i18n/label :t/mention)
:icon :i/mention :icon :i/mention
:timestamp (datetime/timestamp->relative (:timestamp notification)) :timestamp (datetime/timestamp->relative timestamp)
:unread? (not (:read notification)) :unread? (not read)
:context [[common/user-avatar-tag author] :context [[common/user-avatar-tag author]
[quo/text {:style style/tag-text} (string/lower-case (i18n/label :t/on))] [quo/text {:style style/tag-text} (string/lower-case (i18n/label :t/on))]
;; TODO (@smohamedjavid): The `group-avatar-tag` component (if is-chat-from-community?
;; does NOT support displaying channel name along with community/chat name. [quo/context-tag tag-params {:uri community-image} community-name chat-name]
;; Need to update the component to support it. [quo/group-avatar-tag chat-name tag-params])]
[quo/group-avatar-tag chat-name :message {:body (message-body message)}}]]))
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/tag
:text-style style/tag-text}]]
:message {:body (message-body message)}}]])

View File

@ -0,0 +1,12 @@
(ns status-im2.contexts.activity-center.notification.reply.style
(:require [quo2.foundations.colors :as colors]))
(def tag
{:background-color colors/white-opa-10})
(def tag-text
{:color colors/white})
(def lowercase-text
{:color colors/white
:text-transform :lowercase})

View File

@ -0,0 +1,53 @@
(ns status-im2.contexts.activity-center.notification.reply.view
(:require [i18n.i18n :as i18n]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im.ui2.screens.chat.messages.message :as old-message]
[status-im2.common.constants :as constants]
[status-im2.contexts.activity-center.notification.common.view :as common]
[status-im2.contexts.activity-center.notification.reply.style :as style]
[utils.datetime :as datetime]
[utils.re-frame :as rf]))
(def tag-params
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/tag
:text-style style/tag-text})
;; NOTE: Replies support text, image and stickers only.
(defn get-message-content
[{:keys [content-type] :as message}]
(case content-type
constants/content-type-text (get-in message [:content :text])
constants/content-type-image [old-message/message-content-image message]
constants/content-type-sticker [old-message/sticker message]))
(defn view
[{:keys [author chat-name chat-id message read timestamp]}]
(let [chat (rf/sub [:chats/chat chat-id])
community-id (:community-id chat)
is-chat-from-community? (not (nil? community-id))
community (rf/sub [:communities/community community-id])
community-name (:name community)
community-image (get-in community [:images :thumbnail :uri])]
[rn/touchable-opacity
{:on-press (fn []
(rf/dispatch [:hide-popover])
(rf/dispatch [:chat.ui/navigate-to-chat chat-id]))}
[quo/activity-log
{:title (i18n/label :t/message-reply)
:icon :i/reply
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context [[common/user-avatar-tag author]
[quo/text {:style style/lowercase-text} (i18n/label :t/on)]
(if is-chat-from-community?
[quo/context-tag tag-params {:uri community-image} community-name chat-name]
[quo/group-avatar-tag chat-name tag-params])]
:message {:body-number-of-lines 1
:body (get-message-content message)}}]]))

View File

@ -9,6 +9,7 @@
[status-im2.contexts.activity-center.notification.contact-verification.view :as [status-im2.contexts.activity-center.notification.contact-verification.view :as
contact-verification] contact-verification]
[status-im2.contexts.activity-center.notification.mentions.view :as mentions] [status-im2.contexts.activity-center.notification.mentions.view :as mentions]
[status-im2.contexts.activity-center.notification.reply.view :as reply]
[status-im2.contexts.activity-center.style :as style] [status-im2.contexts.activity-center.style :as style]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -107,6 +108,9 @@
types/mention types/mention
[mentions/view notification] [mentions/view notification]
types/reply
[reply/view notification]
nil)]) nil)])
(defn view (defn view

View File

@ -57,6 +57,7 @@
;;;; Date formats ;;;; Date formats
(defn- short-date-format [_] "dd MMM") (defn- short-date-format [_] "dd MMM")
(defn- short-date-format-with-time [_] "dd MMM h:mm a")
(defn- datetime-within-one-week-format (defn- datetime-within-one-week-format
[^js locsym] [^js locsym]
@ -86,6 +87,7 @@
(def date-fmt (get-formatter-fn medium-date-format)) (def date-fmt (get-formatter-fn medium-date-format))
(def time-fmt (get-formatter-fn short-time-format)) (def time-fmt (get-formatter-fn short-time-format))
(def short-date-fmt (get-formatter-fn short-date-format)) (def short-date-fmt (get-formatter-fn short-date-format))
(def short-date-with-time-fmt (get-formatter-fn short-date-format-with-time))
(def datetime-within-one-week-fmt (get-formatter-fn datetime-within-one-week-format)) (def datetime-within-one-week-fmt (get-formatter-fn datetime-within-one-week-format))
;;;; Utilities ;;;; Utilities
@ -142,10 +144,14 @@
(defn timestamp->relative (defn timestamp->relative
[ms] [ms]
(let [datetime (t.coerce/from-long ms)] (let [datetime (-> ms
t.coerce/from-long
(t/plus time-zone-offset))]
(cond (cond
(today? datetime) (today? datetime)
(.format ^js (time-fmt) datetime) (str (string/capitalize (i18n/label :t/datetime-today))
" "
(.format ^js (time-fmt) datetime))
(within-last-n-days? datetime 1) (within-last-n-days? datetime 1)
(str (string/capitalize (i18n/label :t/datetime-yesterday)) (str (string/capitalize (i18n/label :t/datetime-yesterday))
@ -156,7 +162,7 @@
(.format ^js (datetime-within-one-week-fmt) datetime) (.format ^js (datetime-within-one-week-fmt) datetime)
(current-year? datetime) (current-year? datetime)
(.format ^js (short-date-fmt) datetime) (.format ^js (short-date-with-time-fmt) datetime)
(previous-years? datetime) (previous-years? datetime)
(.format ^js (date-fmt) datetime)))) (.format ^js (date-fmt) datetime))))

View File

@ -152,9 +152,9 @@
(is (= "Jan 1, 1973" (datetime/timestamp->relative 94694400000)))) (is (= "Jan 1, 1973" (datetime/timestamp->relative 94694400000))))
(testing "formats 7 days ago or older, but in the current year" (testing "formats 7 days ago or older, but in the current year"
(is (= "03 Mar" (datetime/timestamp->relative 163091745000))) (is (= "03 Mar 3:15 PM" (datetime/timestamp->relative 163091745000)))
(is (= "02 Mar" (datetime/timestamp->relative 163004400000))) (is (= "02 Mar 3:00 PM" (datetime/timestamp->relative 163004400000)))
(is (= "01 Jan" (datetime/timestamp->relative 157820400000)))) (is (= "01 Jan 3:00 PM" (datetime/timestamp->relative 157820400000))))
(testing "formats dates within the last 6 days" (testing "formats dates within the last 6 days"
(is (= "Sat 3:15 PM" (datetime/timestamp->relative 163523745000))) (is (= "Sat 3:15 PM" (datetime/timestamp->relative 163523745000)))
@ -168,9 +168,9 @@
(is (= "Yesterday 11:59 PM" (datetime/timestamp->relative 163641599000)))) (is (= "Yesterday 11:59 PM" (datetime/timestamp->relative 163641599000))))
(testing "formats today, at various timestamps" (testing "formats today, at various timestamps"
(is (= "3:15 PM" (datetime/timestamp->relative 163696545000))) (is (= "Today 3:15 PM" (datetime/timestamp->relative 163696545000)))
(is (= "12:00 PM" (datetime/timestamp->relative 163684800000))) (is (= "Today 12:00 PM" (datetime/timestamp->relative 163684800000)))
(is (= "12:00 AM" (datetime/timestamp->relative 163641600000)))))) (is (= "Today 12:00 AM" (datetime/timestamp->relative 163641600000))))))
#_((deftest day-relative-before-yesterday-force-24H-test #_((deftest day-relative-before-yesterday-force-24H-test
(with-redefs [t/*ms-fn* (constantly epoch-plus-3d) (with-redefs [t/*ms-fn* (constantly epoch-plus-3d)