mirror of
https://github.com/status-im/status-react.git
synced 2025-02-04 15:16:25 +00:00
feat: deleted for me message UI (#14168)
* feat: delete for me message UI delete and sync deleted for me messages immediately after leaving chat view Signed-off-by: yqrashawn <namy.19@gmail.com> * fix: system message width/height Signed-off-by: yqrashawn <namy.19@gmail.com> Signed-off-by: yqrashawn <namy.19@gmail.com>
This commit is contained in:
parent
1b6eaec719
commit
0cbd3ec805
@ -1,14 +1,13 @@
|
||||
(ns quo2.components.messages.system-message
|
||||
(:require [status-im.i18n.i18n :as i18n]
|
||||
[quo.react-native :as rn]
|
||||
[status-im.utils.core :as utils]
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo.theme :as theme]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.reanimated :as ra]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.avatars.icon-avatar :as icon-avatar]
|
||||
[quo2.components.avatars.user-avatar :as user-avatar]
|
||||
[quo2.components.avatars.icon-avatar :as icon-avatar]))
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.reanimated :as ra]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.utils.core :as utils]))
|
||||
|
||||
(def themes-landed {:pinned colors/primary-50-opa-5
|
||||
:added colors/primary-50-opa-5
|
||||
@ -55,7 +54,7 @@
|
||||
|
||||
(defmulti sm-render :type)
|
||||
|
||||
(defmethod sm-render :deleted [{:keys [state action timestamp-str]}]
|
||||
(defmethod sm-render :deleted [{:keys [label timestamp-str]}]
|
||||
[rn/view {:align-items :center
|
||||
:justify-content :space-between
|
||||
:flex 1
|
||||
@ -64,15 +63,12 @@
|
||||
:flex-direction :row}
|
||||
[sm-icon {:icon :main-icons/delete16
|
||||
:color :danger
|
||||
:opacity (if (= state :landed) 0 5)}]
|
||||
:opacity 5}]
|
||||
[text/text {:size :paragraph-2
|
||||
:style {:color (get-color :text)
|
||||
:margin-right 5}}
|
||||
(i18n/label (if action :message-deleted-for-you :message-deleted))]
|
||||
(when (nil? action) [sm-timestamp timestamp-str])]
|
||||
(when action [button/button {:size 24
|
||||
:before :main-icons/timeout
|
||||
:type :grey} (i18n/label :undo)])])
|
||||
(i18n/label (or label :message-deleted))]
|
||||
[sm-timestamp timestamp-str]]])
|
||||
|
||||
(defmethod sm-render :added [{:keys [state mentions timestamp-str]}]
|
||||
[rn/view {:align-items :center
|
||||
@ -140,23 +136,27 @@
|
||||
:style {:color (get-color :time)}}
|
||||
(utils/truncate-str (:info content) 24)])]]]])
|
||||
|
||||
(defn system-message [{:keys [type] :as message}]
|
||||
(defn system-message
|
||||
[{:keys [type style non-pressable? animate-landing?] :as message}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [sv-color (ra/use-shared-value (get-color :bg :landed type))]
|
||||
(ra/animate-shared-value-with-delay
|
||||
sv-color (get-color :bg :default type) 0 :linear 1000)
|
||||
(let [sv-color (ra/use-shared-value
|
||||
(get-color :bg (if animate-landing? :landed :default) type))]
|
||||
(when animate-landing?
|
||||
(ra/animate-shared-value-with-delay
|
||||
sv-color (get-color :bg :default type) 0 :linear 1000))
|
||||
[ra/touchable-opacity
|
||||
{:on-press #(ra/set-shared-value
|
||||
sv-color (get-color :bg :pressed type))
|
||||
{:on-press #(when-not non-pressable?
|
||||
(ra/set-shared-value
|
||||
sv-color (get-color :bg :pressed type)))
|
||||
:style (ra/apply-animations-to-style
|
||||
{:background-color sv-color}
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:border-radius 16
|
||||
:padding-vertical 9
|
||||
:padding-horizontal 11
|
||||
:width 359
|
||||
:height 52
|
||||
:background-color sv-color})}
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:border-radius 16
|
||||
:padding-vertical 9
|
||||
:padding-horizontal 11
|
||||
:background-color sv-color}
|
||||
style))}
|
||||
[sm-render message]]))])
|
||||
|
@ -1,5 +1,6 @@
|
||||
(ns status-im.chat.models.delete-message-for-me
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.chat.models.message-list :as message-list]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im.utils.fx :as fx]
|
||||
@ -43,17 +44,22 @@
|
||||
{:events [:chat.ui/delete-message-for-me]}
|
||||
[{:keys [db]} {:keys [chat-id message-id]} undo-time-limit-ms]
|
||||
(when (get-in db [:messages chat-id message-id])
|
||||
{:db (update-db-delete-locally db chat-id message-id undo-time-limit-ms)
|
||||
(assoc
|
||||
(message-list/rebuild-message-list
|
||||
{:db (update-db-delete-locally db chat-id message-id undo-time-limit-ms)}
|
||||
chat-id)
|
||||
:utils/dispatch-later [{:dispatch [:chat.ui/delete-message-for-me-and-sync
|
||||
{:chat-id chat-id
|
||||
:message-id message-id}]
|
||||
:ms undo-time-limit-ms}]}))
|
||||
:ms undo-time-limit-ms}])))
|
||||
|
||||
(fx/defn undo
|
||||
{:events [:chat.ui/undo-delete-message-for-me]}
|
||||
[{:keys [db]} {:keys [chat-id message-id]}]
|
||||
(when (get-in db [:messages chat-id message-id])
|
||||
{:db (update-db-undo-locally db chat-id message-id)}))
|
||||
(message-list/rebuild-message-list
|
||||
{:db (update-db-undo-locally db chat-id message-id)}
|
||||
chat-id)))
|
||||
|
||||
(fx/defn delete-and-sync
|
||||
{:events [:chat.ui/delete-message-for-me-and-sync]}
|
||||
@ -66,3 +72,19 @@
|
||||
:on-error #(log/error "failed to delete message for me " %)
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response
|
||||
%])}]}))
|
||||
(defn- chats-reducer
|
||||
"traverse all messages find not yet synced deleted-for-me? messages, generate dispatch vector"
|
||||
[acc chat-id messages]
|
||||
(reduce-kv
|
||||
(fn [inner-acc message-id {:keys [deleted-for-me? deleted-for-me-undoable-till]}]
|
||||
(if (and deleted-for-me? deleted-for-me-undoable-till)
|
||||
(conj inner-acc [:chat.ui/delete-message-for-me-and-sync chat-id message-id])
|
||||
inner-acc))
|
||||
acc
|
||||
messages))
|
||||
|
||||
(fx/defn sync-all
|
||||
"Get all deleted-for-me messages that not yet synced with status-go and sync them"
|
||||
{:events [:chat.ui/sync-all-deleted-for-me-messages]}
|
||||
[{:keys [db]}]
|
||||
{:dispatch-n (reduce-kv chats-reducer [] (:messages db))})
|
||||
|
@ -8,65 +8,47 @@
|
||||
(defonce cid "chat-id")
|
||||
|
||||
(deftest delete-for-me
|
||||
(let [db {:messages {cid {mid {:id mid}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "delete for me"
|
||||
(let [expected {:db {:messages {"chat-id" {"message-id"
|
||||
{:id "message-id"
|
||||
:deleted-for-me? true}}}}
|
||||
:utils/dispatch-later
|
||||
[{:dispatch [:chat.ui/delete-message-for-me-and-sync
|
||||
{:chat-id "chat-id" :message-id "message-id"}]
|
||||
:ms 1000}]}
|
||||
result (delete-message-for-me/delete {:db db} message 1000)
|
||||
timestamp (+ (datetime/timestamp) 1000)]
|
||||
(is (= (update-in result [:db :messages "chat-id" "message-id"] dissoc :deleted-for-me-undoable-till)
|
||||
expected))
|
||||
(is (-> (get-in result [:db :messages "chat-id" "message-id" :deleted-for-me-undoable-till])
|
||||
(- timestamp)
|
||||
js/Math.abs
|
||||
(< 10)))))
|
||||
(testing "should return nil if message in db"
|
||||
(is (= (delete-message-for-me/delete {:db {:messages []}} message 1000)
|
||||
nil)))))
|
||||
(with-redefs [datetime/timestamp (constantly 1)]
|
||||
(let [db {:messages {cid {mid {:id mid :whisper-timestamp 1}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "delete for me"
|
||||
(let [result-message (get-in (delete-message-for-me/delete {:db db} message 1000)
|
||||
[:db :messages cid mid])]
|
||||
(is (= (:id result-message) mid))
|
||||
(is (true? (:deleted-for-me? result-message)))
|
||||
(is (= (:deleted-for-me-undoable-till result-message) 1001))))
|
||||
(testing "should return nil if message not in db"
|
||||
(is (= (delete-message-for-me/delete {:db {:messages []}} message 1000)
|
||||
nil))))))
|
||||
|
||||
(deftest undo-delete-for-me
|
||||
(let [db {:messages {cid {mid {:id mid}}}}
|
||||
(let [db {:messages {cid {mid {:id mid :whisper-timestamp 1}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "undo delete for me in time"
|
||||
(let [db (update-in db
|
||||
[:messages cid mid]
|
||||
assoc
|
||||
:deleted-for-me? true
|
||||
:deleted-for-me-undoable-till
|
||||
(+ (datetime/timestamp) 1000))
|
||||
(let [db (update-in db
|
||||
[:messages cid mid]
|
||||
assoc
|
||||
:deleted-for-me? true
|
||||
:deleted-for-me-undoable-till
|
||||
(+ (datetime/timestamp) 1000))
|
||||
result-message (get-in (delete-message-for-me/undo {:db db} message)
|
||||
[:db :messages cid mid])]
|
||||
(is (= (:id result-message) mid))
|
||||
(is (nil? (:deleted-for-me? result-message)))
|
||||
(is (nil? (:deleted-for-me-undoable-till result-message)))))
|
||||
|
||||
expected {:db {:messages {"chat-id" {"message-id"
|
||||
{:id "message-id"}}}}}]
|
||||
(is (= (delete-message-for-me/undo {:db db} message) expected))))
|
||||
(testing "remain deleted for me when undo delete for me late"
|
||||
(let [db (update-in db
|
||||
[:messages cid mid]
|
||||
assoc
|
||||
:deleted-for-me? true
|
||||
:deleted-for-me-undoable-till (- (datetime/timestamp) 1000))
|
||||
result-message (get-in (delete-message-for-me/undo {:db db} message) [:db :messages cid mid])]
|
||||
(is (= (:id result-message) mid))
|
||||
(is (nil? (:deleted-for-me-undoable-till result-message)))
|
||||
(is (true? (:deleted-for-me? result-message)))))
|
||||
|
||||
expected {:db {:messages {"chat-id" {"message-id"
|
||||
{:id "message-id"
|
||||
:deleted-for-me? true}}}}}]
|
||||
(is (= (delete-message-for-me/undo {:db db} message) expected))))
|
||||
(testing "remain deleted for me when undo delete for me late"
|
||||
(let [db (update-in db
|
||||
[:messages cid mid]
|
||||
assoc
|
||||
:deleted-for-me? true
|
||||
:deleted-for-me-undoable-till (- (datetime/timestamp) 1000))
|
||||
|
||||
expected {:db {:messages {"chat-id" {"message-id"
|
||||
{:id "message-id"
|
||||
:deleted-for-me? true}}}}}]
|
||||
(is (= (delete-message-for-me/undo {:db db} message) expected))))
|
||||
(testing "should return nil if message in db"
|
||||
(testing "should return nil if message not in db"
|
||||
(is (= (delete-message-for-me/undo {:db {:messages []}} message)
|
||||
nil)))))
|
||||
|
||||
@ -74,7 +56,7 @@
|
||||
(let [db {:messages {cid {mid {:id mid}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "delete for me and sync"
|
||||
(let [expected-db {:messages {"chat-id" {"message-id" {:id "message-id"}}}}
|
||||
(let [expected-db {:messages {cid {mid {:id mid}}}}
|
||||
effects (delete-message-for-me/delete-and-sync {:db db} message)
|
||||
result-db (:db effects)
|
||||
rpc-calls (:status-im.ethereum.json-rpc/call effects)]
|
||||
@ -100,7 +82,7 @@
|
||||
second)
|
||||
mid))))
|
||||
(testing "delete for me and sync, should clean undo timer"
|
||||
(let [expected-db {:messages {"chat-id" {"message-id" {:id "message-id"}}}}
|
||||
(let [expected-db {:messages {cid {mid {:id mid}}}}
|
||||
effects (delete-message-for-me/delete-and-sync
|
||||
{:db (update-in db
|
||||
[:messages cid mid
|
||||
@ -109,7 +91,7 @@
|
||||
message)
|
||||
result-db (:db effects)]
|
||||
(is (= result-db expected-db))))
|
||||
(testing "should return nil if message in db"
|
||||
(testing "should return nil if message not in db"
|
||||
(is (= (delete-message-for-me/delete-and-sync {:db {:messages []}}
|
||||
message)
|
||||
nil)))))
|
||||
|
@ -1,8 +1,8 @@
|
||||
(ns status-im.chat.models.message-list
|
||||
(:require [status-im.constants :as constants]
|
||||
[status-im.utils.fx :as fx]
|
||||
(:require ["functional-red-black-tree" :as rb-tree]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.utils.datetime :as time]
|
||||
["functional-red-black-tree" :as rb-tree]))
|
||||
[status-im.utils.fx :as fx]))
|
||||
|
||||
(defn- add-datemark [{:keys [whisper-timestamp] :as msg}]
|
||||
;;TODO this is slow
|
||||
@ -16,16 +16,20 @@
|
||||
message-type
|
||||
from
|
||||
outgoing
|
||||
whisper-timestamp]}]
|
||||
whisper-timestamp
|
||||
deleted-for-me?]}]
|
||||
(-> {:whisper-timestamp whisper-timestamp
|
||||
:from from
|
||||
:one-to-one? (= constants/message-type-one-to-one message-type)
|
||||
:system-message? (= constants/message-type-private-group-system-message
|
||||
message-type)
|
||||
:clock-value clock-value
|
||||
:type :message
|
||||
:message-id message-id
|
||||
:outgoing (boolean outgoing)}
|
||||
:from from
|
||||
:one-to-one? (= constants/message-type-one-to-one message-type)
|
||||
:system-message? (boolean
|
||||
(or
|
||||
(= constants/message-type-private-group-system-message
|
||||
message-type)
|
||||
deleted-for-me?))
|
||||
:clock-value clock-value
|
||||
:type :message
|
||||
:message-id message-id
|
||||
:outgoing (boolean outgoing)}
|
||||
add-datemark
|
||||
add-timestamp))
|
||||
|
||||
|
@ -1,21 +1,22 @@
|
||||
(ns status-im.navigation.core
|
||||
(:require
|
||||
["react-native" :as rn]
|
||||
[clojure.set :as clojure.set]
|
||||
["react-native-gesture-handler" :refer (gestureHandlerRootHOC)]
|
||||
["react-native-navigation" :refer (Navigation)]
|
||||
[clojure.set :as clojure.set]
|
||||
[quo.components.text-input :as quo.text-input]
|
||||
[quo.design-system.colors :as quo.colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.login.core :as login-core]
|
||||
[status-im.navigation.roots :as roots]
|
||||
[status-im.navigation.state :as state]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.views :as views]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.multiaccounts.login.core :as login-core]
|
||||
[status-im.navigation.state :as state]))
|
||||
[taoensso.encore :as enc]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def debug? ^boolean js/goog.DEBUG)
|
||||
|
||||
@ -438,4 +439,6 @@
|
||||
:community
|
||||
|
||||
:else
|
||||
:home))}))
|
||||
:home))
|
||||
:dispatch-n (enc/conj-when []
|
||||
(and (= view-id :chat) [:chat.ui/sync-all-deleted-for-me-messages]))}))
|
||||
|
@ -1,6 +1,10 @@
|
||||
(ns status-im.ui2.screens.chat.messages.message
|
||||
(:require [quo.core :as quo]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.react-native :as rn]
|
||||
[quo2.components.messages.system-message :as system-message]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[quo2.foundations.typography :as typography]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.chat.models.delete-message-for-me]
|
||||
@ -11,11 +15,12 @@
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.fast-image :as fast-image]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.chat.bottom-sheets.context-drawer :as message-context-drawer]
|
||||
[status-im.ui2.screens.chat.components.reply :as components.reply]
|
||||
[status-im.ui.screens.chat.image.preview.views :as preview]
|
||||
[status-im.ui.screens.chat.message.audio :as message.audio]
|
||||
[status-im.ui.screens.chat.message.command :as message.command]
|
||||
@ -26,17 +31,13 @@
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.ui.screens.chat.sheets :as sheets]
|
||||
[status-im.ui.screens.chat.styles.message.message :as style]
|
||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||
[status-im.ui.screens.chat.styles.photos :as photos.style]
|
||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||
[status-im.ui.screens.communities.icon :as communities.icon]
|
||||
[status-im.utils.handlers :refer [<sub >evt]]
|
||||
[status-im.ui2.screens.chat.components.reply :as components.reply]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.security :as security]
|
||||
[quo2.foundations.typography :as typography]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[quo.react-native :as rn]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon])
|
||||
[status-im.utils.handlers :refer [<sub >evt]]
|
||||
[status-im.utils.security :as security])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn message-timestamp-anim
|
||||
@ -263,7 +264,7 @@
|
||||
|
||||
(defview community-content [{:keys [community-id] :as message}]
|
||||
(letsubs [{:keys [name description verified] :as community} [:communities/community community-id]
|
||||
communities-enabled? [:communities/enabled?]]
|
||||
communities-enabled? [:communities/enabled?]]
|
||||
(when (and communities-enabled? community)
|
||||
[rn/view {:style (assoc (style/message-wrapper message)
|
||||
:margin-vertical 10
|
||||
@ -294,51 +295,51 @@
|
||||
|
||||
(defn message-content-wrapper
|
||||
"Author, userpic and delivery wrapper"
|
||||
[{:keys [last-in-group?
|
||||
identicon
|
||||
from in-popover? timestamp-str
|
||||
deleted-for-me? pinned]
|
||||
[{:keys [last-in-group? identicon from in-popover? timestamp-str
|
||||
deleted-for-me? deleted-for-me-undoable-till pinned]
|
||||
:as message} content {:keys [modal close-modal]}]
|
||||
(let [response-to (:response-to (:content message))]
|
||||
[rn/view {:style (style/message-wrapper message)
|
||||
:pointer-events :box-none
|
||||
:accessibility-label :chat-item}
|
||||
(when (and (seq response-to) (:quoted-message message))
|
||||
[quoted-message response-to (:quoted-message message)])
|
||||
[rn/view {:style (style/message-body)
|
||||
:pointer-events :box-none}
|
||||
[rn/view (style/message-author-userpic)
|
||||
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
|
||||
[rn/touchable-highlight {:on-press #(do (when modal (close-modal))
|
||||
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||
[photos/member-photo from identicon]])]
|
||||
(if deleted-for-me?
|
||||
[system-message/system-message
|
||||
{:type :deleted
|
||||
:label :message-deleted-for-you
|
||||
:timestamp-str timestamp-str
|
||||
:non-pressable? true
|
||||
:animate-landing? (if deleted-for-me-undoable-till true false)}]
|
||||
[rn/view {:style (style/message-wrapper message)
|
||||
:pointer-events :box-none
|
||||
:accessibility-label :chat-item}
|
||||
(when (and (seq response-to) (:quoted-message message))
|
||||
[quoted-message response-to (:quoted-message message)])
|
||||
[rn/view {:style (style/message-body)
|
||||
:pointer-events :box-none}
|
||||
[rn/view (style/message-author-userpic)
|
||||
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
|
||||
[rn/touchable-highlight {:on-press #(do (when modal (close-modal))
|
||||
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||
[photos/member-photo from identicon]])]
|
||||
|
||||
[rn/view {:style (style/message-author-wrapper)}
|
||||
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
|
||||
[rn/view {:style {:flex-direction :row :align-items :center}}
|
||||
[rn/touchable-opacity {:style style/message-author-touchable
|
||||
:disabled in-popover?
|
||||
:on-press #(do (when modal (close-modal))
|
||||
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||
[message-author-name from {:modal modal}]]
|
||||
[rn/text
|
||||
{:style (merge
|
||||
{:padding-left 5
|
||||
:margin-top 2}
|
||||
(style/message-timestamp-text))
|
||||
:accessibility-label :message-timestamp}
|
||||
timestamp-str]])
|
||||
;; MESSAGE CONTENT
|
||||
;; TODO(yqrashawn): wait for system message component to display deleted for me UI
|
||||
(if deleted-for-me?
|
||||
[rn/view {:style {:border-width 2
|
||||
:border-color :red}}
|
||||
content]
|
||||
content)
|
||||
[link-preview/link-preview-wrapper (:links (:content message)) false false]]]
|
||||
; delivery status
|
||||
[rn/view (style/delivery-status)
|
||||
[message-delivery-status message]]]))
|
||||
[rn/view {:style (style/message-author-wrapper)}
|
||||
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
|
||||
[rn/view {:style {:flex-direction :row :align-items :center}}
|
||||
[rn/touchable-opacity {:style style/message-author-touchable
|
||||
:disabled in-popover?
|
||||
:on-press #(do (when modal (close-modal))
|
||||
(re-frame/dispatch [:chat.ui/show-profile from]))}
|
||||
[message-author-name from {:modal modal}]]
|
||||
[rn/text
|
||||
{:style (merge
|
||||
{:padding-left 5
|
||||
:margin-top 2}
|
||||
(style/message-timestamp-text))
|
||||
:accessibility-label :message-timestamp}
|
||||
timestamp-str]])
|
||||
;; MESSAGE CONTENT
|
||||
content
|
||||
[link-preview/link-preview-wrapper (:links (:content message)) false false]]]
|
||||
;; delivery status
|
||||
[rn/view (style/delivery-status)
|
||||
[message-delivery-status message]]])))
|
||||
|
||||
(def image-max-width 260)
|
||||
(def image-max-height 192)
|
||||
|
Loading…
x
Reference in New Issue
Block a user