diff --git a/src/status_im/ui/components/chat_icon/screen.cljs b/src/status_im/ui/components/chat_icon/screen.cljs index 82bbb4259d..7532d4a50d 100644 --- a/src/status_im/ui/components/chat_icon/screen.cljs +++ b/src/status_im/ui/components/chat_icon/screen.cljs @@ -5,21 +5,21 @@ [status-im.ui.components.icons.icons :as icons] [status-im.ui.components.chat-icon.styles :as styles] [quo.design-system.colors :as colors] - [status-im.ui.components.react :as react] [status-im.ui.screens.chat.photos :as photos] [status-im.profile.db :as profile.db] - [status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils])) + [status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils] + [quo.react-native :as rn])) ;;TODO REWORK THIS NAMESPACE (def get-name-first-char (memoize (fn [name] - ;; TODO: for now we check if the first letter is a # - ;; which means it is most likely a public chat and - ;; use the second letter if that is the case - ;; a broader refactoring should clean up upstream params - ;; for default-chat-icon + ;; TODO: for now we check if the first letter is a # + ;; which means it is most likely a public chat and + ;; use the second letter if that is the case + ;; a broader refactoring should clean up upstream params + ;; for default-chat-icon (string/capitalize (if (and (= "#" (first name)) (< 1 (count name))) (second name) @@ -27,13 +27,13 @@ (defn default-chat-icon [name styles] (when-not (string/blank? name) - [react/view (:default-chat-icon styles) - [react/text {:style (:default-chat-icon-text styles)} + [rn/view (:default-chat-icon styles) + [rn/text {:style (:default-chat-icon-text styles)} (get-name-first-char name)]])) (defn chat-icon-view [chat-id group-chat name styles] - [react/view (:container styles) + [rn/view (:container styles) (if group-chat [default-chat-icon name styles] (let [photo-path @(re-frame.core/subscribe [:chats/photo-path chat-id])] @@ -41,8 +41,8 @@ (defn emoji-chat-icon [emoji styles] (when-not (string/blank? emoji) - [react/view (:default-chat-icon styles) - [react/text {:style (:default-chat-icon-text styles)} emoji]])) + [rn/view (:default-chat-icon styles) + [rn/text {:style (:default-chat-icon-text styles)} emoji]])) (defn profile-photo-plus-dot-view [{:keys [public-key photo-container photo-path community?]}] @@ -56,16 +56,16 @@ dot-styles (visibility-status-utils/icon-visibility-status-dot public-key size identicon?) dot-accessibility-label (:accessibility-label dot-styles)] - [react/view {:style photo-container - :accessibility-label :profile-photo} + [rn/view {:style photo-container + :accessibility-label :profile-photo} [photos/photo photo-path {:size size}] (when-not community? - [react/view {:style dot-styles - :accessibility-label dot-accessibility-label}])])) + [rn/view {:style dot-styles + :accessibility-label dot-accessibility-label}])])) (defn emoji-chat-icon-view [chat-id group-chat name emoji styles] - [react/view (:container styles) + [rn/view (:container styles) (if group-chat (if (string/blank? emoji) [default-chat-icon name styles] @@ -128,17 +128,17 @@ (defn custom-icon-view-list [name color & [size]] - [react/view (styles/container-list-size (or size 40)) + [rn/view (styles/container-list-size (or size 40)) [default-chat-icon name {:default-chat-icon (styles/default-chat-icon-profile color (or size 40)) :default-chat-icon-text (styles/default-chat-icon-text (or size 40))}]]) (defn contact-icon-view [contact {:keys [container] :as styles}] - [react/view container + [rn/view container [photos/photo (multiaccounts/displayed-photo contact) styles]]) (defn contact-icon-contacts-tab [photo-path] - [react/view styles/container-chat-list + [rn/view styles/container-chat-list [photos/photo photo-path {:size 40}]]) (defn dapp-icon-permission [contact size] @@ -174,7 +174,7 @@ :default-chat-icon-text (if (string/blank? emoji) (styles/default-chat-icon-text size) (styles/emoji-chat-icon-text size))} override-styles)] - [react/view (:container styles) + [rn/view (:container styles) (if (and photo-path (seq photo-path)) [profile-photo-plus-dot-view {:photo-path photo-path :public-key public-key @@ -184,5 +184,5 @@ [default-chat-icon name styles] [emoji-chat-icon emoji styles])) (when edit? - [react/view {:style (styles/chat-icon-profile-edit)} + [rn/view {:style (styles/chat-icon-profile-edit)} [icons/tiny-icon :tiny-icons/tiny-edit {:color colors/white-persist}]])])) diff --git a/src/status_im/ui/screens/chat/styles/message/message.cljs b/src/status_im/ui/screens/chat/styles/message/message.cljs index 6eb6f3f892..4121889166 100644 --- a/src/status_im/ui/screens/chat/styles/message/message.cljs +++ b/src/status_im/ui/screens/chat/styles/message/message.cljs @@ -76,8 +76,9 @@ (merge {:flex-direction :row})) (defn pin-indicator-container [] - {:margin-top 8 + {:margin-top 4 :margin-left 68 + :top 4 :justify-content :center :align-self :flex-start :align-items :flex-start}) diff --git a/src/status_im/ui/screens/chat/toolbar_content.cljs b/src/status_im/ui/screens/chat/toolbar_content.cljs index 92268d7b3c..8f62a87c2f 100644 --- a/src/status_im/ui/screens/chat/toolbar_content.cljs +++ b/src/status_im/ui/screens/chat/toolbar_content.cljs @@ -2,13 +2,13 @@ (:require [status-im.i18n.i18n :as i18n] [status-im.constants :as constants] [status-im.ui.components.chat-icon.screen :as chat-icon.screen] - [status-im.ui.components.react :as react] [status-im.ui.screens.chat.styles.main :as st] - [re-frame.core :as re-frame])) + [re-frame.core :as re-frame] + [quo.react-native :as rn])) (defn- group-last-activity [{:keys [contacts public?]}] - [react/view {:flex-direction :row} - [react/text {:style st/toolbar-subtitle} + [rn/view {:flex-direction :row} + [rn/text {:style st/toolbar-subtitle} (if public? (i18n/label :t/public-group-status) (let [cnt (count contacts)] @@ -18,15 +18,15 @@ (defn one-to-one-name [from] (let [[first-name _] @(re-frame.core/subscribe [:contacts/contact-two-names-by-identity from])] - [react/text {:style st/chat-name-text - :number-of-lines 1 - :accessibility-label :chat-name-text} + [rn/text {:style st/chat-name-text + :number-of-lines 1 + :accessibility-label :chat-name-text} first-name])) (defn contact-indicator [contact-id] (let [added? @(re-frame/subscribe [:contacts/contact-added? contact-id])] - [react/view {:flex-direction :row} - [react/text {:style st/toolbar-subtitle} + [rn/view {:flex-direction :row} + [rn/text {:style st/toolbar-subtitle} (if added? (i18n/label :chat-is-a-contact) (i18n/label :chat-is-not-a-contact))]])) @@ -34,14 +34,14 @@ (defn toolbar-content-view-inner [chat-info] (let [{:keys [group-chat invitation-admin color chat-id contacts chat-type chat-name public? emoji]} chat-info] - [react/view {:style st/toolbar-container} - [react/view {:margin-right 10} + [rn/view {:style st/toolbar-container} + [rn/view {:margin-right 10} [chat-icon.screen/chat-icon-view-toolbar chat-id group-chat chat-name color emoji 36]] - [react/view {:style st/chat-name-view} + [rn/view {:style st/chat-name-view} (if group-chat - [react/text {:style st/chat-name-text - :number-of-lines 1 - :accessibility-label :chat-name-text} + [rn/text {:style st/chat-name-text + :number-of-lines 1 + :accessibility-label :chat-name-text} chat-name] [one-to-one-name chat-id]) (when-not group-chat diff --git a/src/status_im/ui2/screens/chat/components/reply.cljs b/src/status_im/ui2/screens/chat/components/reply.cljs index 7112fac1aa..2868f45204 100644 --- a/src/status_im/ui2/screens/chat/components/reply.cljs +++ b/src/status_im/ui2/screens/chat/components/reply.cljs @@ -86,4 +86,4 @@ ;;TODO quo2 icon should be used [icons/icon :main-icons/close {:width 16 :height 16 - :color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/neutral-40)}]])])) \ No newline at end of file + :color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/neutral-40)}]])])) diff --git a/src/status_im/ui2/screens/chat/messages/message.cljs b/src/status_im/ui2/screens/chat/messages/message.cljs index 35864b8749..c420141290 100644 --- a/src/status_im/ui2/screens/chat/messages/message.cljs +++ b/src/status_im/ui2/screens/chat/messages/message.cljs @@ -15,6 +15,7 @@ [status-im.ui.components.icons.icons :as icons] [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] @@ -28,13 +29,14 @@ [status-im.ui.screens.chat.utils :as chat.utils] [status-im.ui.screens.chat.styles.photos :as photos.style] [status-im.ui.screens.communities.icon :as communities.icon] - [status-im.utils.handlers :refer [>evt]] + [status-im.utils.handlers :refer [evt]] [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.ui2.screens.chat.components.reply :as reply] - [quo.react-native :as rn]) + [status-im.ui.components.list.views :as list] + [quo.react-native :as rn] + [status-im.ui.components.chat-icon.screen :as chat-icon]) (:require-macros [status-im.utils.views :refer [defview letsubs]])) (defn message-timestamp-anim @@ -72,9 +74,9 @@ :align-items :flex-end} (when outgoing [icons/icon (case outgoing-status - :sending :tiny-icons/tiny-pending - :sent :tiny-icons/tiny-sent - :not-sent :tiny-icons/tiny-warning + :sending :tiny-icons/tiny-pending + :sent :tiny-icons/tiny-sent + :not-sent :tiny-icons/tiny-warning :delivered :tiny-icons/tiny-delivered :tiny-icons/tiny-pending) {:width 16 @@ -97,7 +99,7 @@ (defview quoted-message [_ reply pin?] [rn/view {:style (when-not pin? (style/quoted-message-container))} - [reply/reply-message reply false pin?]]) + [components.reply/reply-message reply false pin?]]) (defn system-text? [content-type] (= content-type constants/content-type-system-text)) @@ -187,10 +189,10 @@ (reduce (fn [acc e] (render-block message acc e)) [:<>] tree)) (defn render-parsed-text-with-message-status [{:keys [edited-at in-popover?] :as message} tree] - (let [elements (render-parsed-text message tree) + (let [elements (render-parsed-text message tree) message-status [rn/text {:style (style/message-status-placeholder)} (str (if (not in-popover?) " " " ") (when (and (not in-popover?) edited-at) edited-at-text))] - last-element (peek elements)] + last-element (peek elements)] ;; Using `nth` here as slightly faster than `first`, roughly 30% ;; It's worth considering pure js structures for this code path as ;; it's perfomance critical @@ -218,7 +220,7 @@ [:bottom-sheet/show-sheet {:content (sheets/options chat-id message-id) :content-height 200}]) - (react/dismiss-keyboard!))} + (rn/dismiss-keyboard!))} [rn/view style/not-sent-view [rn/text {:style style/not-sent-text} (i18n/label :t/status-not-sent-tap)] @@ -226,27 +228,23 @@ [icons/icon :main-icons/warning {:color colors/red}]]]]) (defn pin-author-name [pinned-by] - (let [user-contact @(re-frame/subscribe [:multiaccount/contact]) + (let [user-contact @(re-frame/subscribe [:multiaccount/contact]) contact-names @(re-frame/subscribe [:contacts/contact-two-names-by-identity pinned-by])] ;; We append empty spaces to the name as a workaround to make one-line and multi-line label components show correctly (str " " (if (= pinned-by (user-contact :public-key)) (i18n/label :t/You) (first contact-names))))) -(def pin-icon-width 10) - -(def pin-icon-height 15) - -(defn pin-icon [] - [icons/icon :main-icons/pin16 {:color (:text-04 @colors/theme) - :height pin-icon-height - :width pin-icon-width}]) +(defn pin-icon [color size] + [icons/icon :main-icons/pin16 {:color color + :height size + :width size}]) (defn pinned-by-indicator [pinned-by] - [rn/view {:style (style/pin-indicator) + [rn/view {:style (style/pin-indicator) :accessibility-label :pinned-by} - [pin-icon] - [quo/text {:size :small - :color :main - :style (style/pin-author-text)} + [pin-icon quo2.colors/primary-50 16] + [quo/text {:size :small + :color :main + :style (style/pin-author-text)} (pin-author-name pinned-by)]]) (defn message-delivery-status @@ -274,14 +272,14 @@ (when verified [rn/view (style/community-verified) [rn/text {:style {:font-size 13 - :color colors/blue}} (i18n/label :t/communities-verified)]]) + :color colors/blue}} (i18n/label :t/communities-verified)]]) [rn/view (style/community-message verified) - [rn/view {:width 62 + [rn/view {:width 62 :padding-left 14} (if (= community-id constants/status-community-id) [rn/image {:source (resources/get-image :status-logo) - :style {:width 40 - :height 40}}] + :style {:width 40 + :height 40}}] [communities.icon/community-icon community])] [rn/view {:padding-right 14 :flex 1} [rn/text {:style {:font-weight "700" :font-size 17}} @@ -292,7 +290,7 @@ :community {:community-id (:id community)}])} [rn/text {:style {:text-align :center - :color colors/blue}} (i18n/label :t/view)]]]]))) + :color colors/blue}} (i18n/label :t/view)]]]]))) (defn message-content-wrapper "Author, userpic and delivery wrapper" @@ -302,18 +300,19 @@ deleted-for-me? pinned] :as message} content {:keys [modal close-modal]}] (let [response-to (:response-to (:content message))] - [rn/view {:style (style/message-wrapper 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) + [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}} @@ -332,7 +331,7 @@ ;; 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 + [rn/view {:style {:border-width 2 :border-color :red}} content] content) @@ -346,7 +345,7 @@ (defn image-set-size [dimensions] (fn [evt] - (let [width (.-width (.-nativeEvent evt)) + (let [width (.-width (.-nativeEvent evt)) height (.-height (.-nativeEvent evt))] (if (< width height) ;; if width less than the height we reduce width proportionally to height @@ -358,14 +357,14 @@ (defn message-content-image [{:keys [content]} _] (let [dimensions (reagent/atom {:width image-max-width :height image-max-height :loaded false}) - visible (reagent/atom false) - uri (:image content)] + visible (reagent/atom false) + uri (:image content)] (fn [{:keys [in-popover?] :as message} {:keys [on-long-press]}] (let [style-opts {:outgoing false - :opacity (if (:loaded @dimensions) 1 0) - :width (:width @dimensions) - :height (:height @dimensions)}] + :opacity (if (:loaded @dimensions) 1 0) + :width (:width @dimensions) + :height (:height @dimensions)}] [:<> [preview/preview-image {:message message :visible @visible @@ -373,10 +372,10 @@ (reagent/flush))}] [rn/touchable-highlight {:on-press (fn [] (reset! visible true) - (react/dismiss-keyboard!)) + (rn/dismiss-keyboard!)) :on-long-press @on-long-press :disabled in-popover?} - [rn/view {:style (style/image-message style-opts) + [rn/view {:style (style/image-message style-opts) :accessibility-label :image-message} (when (or (:error @dimensions) (not (:loaded @dimensions))) [rn/view @@ -385,10 +384,10 @@ (if (:error @dimensions) [icons/icon :main-icons/cancel] [rn/activity-indicator {:animating true}])]) - [fast-image/fast-image {:style (dissoc style-opts :outgoing) - :on-load (image-set-size dimensions) - :on-error #(swap! dimensions assoc :error true) - :source {:uri uri}}] + [fast-image/fast-image {:style (dissoc style-opts :outgoing) + :on-load (image-set-size dimensions) + :on-error #(swap! dimensions assoc :error true) + :source {:uri uri}}] [rn/view {:style (style/image-message-border style-opts)}]]]])))) (defmulti ->message :content-type) @@ -418,7 +417,7 @@ :prevent-closing? true}])) (re-frame/dispatch [::models.pin-message/send-pin-message (assoc message :pinned (not pinned))])))) -(defn on-long-press-fn [on-long-press {:keys [pinned message-pin-enabled outgoing edit-enabled show-input?] :as message} content] +(defn on-long-press-fn [on-long-press {:keys [pinned message-pin-enabled outgoing edit-enabled show-input? community?] :as message} content] (on-long-press (concat (when (and outgoing edit-enabled) @@ -435,7 +434,7 @@ :id :reply}]) [{:type :main :on-press #(react/copy-to-clipboard - (reply/get-quoted-text-with-mentions + (components.reply/get-quoted-text-with-mentions (get content :parsed-text))) :label (i18n/label :t/copy-text) :icon :main-icons/copy-context20 @@ -443,7 +442,7 @@ (when message-pin-enabled [{:type :main :on-press #(pin-message message) - :label (i18n/label (if pinned :t/unpin-from-chat :t/pin-to-chat)) + :label (i18n/label (if pinned (if community? :t/unpin-from-channel :t/unpin-from-chat) (if community? :t/pin-to-channel :t/pin-to-chat))) :icon :main-icons/pin-context20 :id (if pinned :unpin :pin)}]) [{:type :danger @@ -461,7 +460,7 @@ :id :delete-for-all}])))) (defn collapsible-text-message [_ _] - (let [collapsed? (reagent/atom false) + (let [collapsed? (reagent/atom false) show-timestamp? (reagent/atom false)] (fn [{:keys [content in-popover?] :as message} on-long-press modal ref] (let [on-long-press (fn [] @@ -472,10 +471,7 @@ (reset! ref on-long-press) [rn/touchable-highlight (when-not modal - {:on-press (fn [_] - (react/dismiss-keyboard!) - (reset! show-timestamp? true)) - :delay-long-press 100 + {:delay-long-press 100 :on-long-press on-long-press :disabled in-popover?}) [rn/view style/message-view-wrapper @@ -491,34 +487,6 @@ [collapsible-text-message message on-long-press modal ref] reaction-picker]) -(defmethod ->message constants/content-type-pin [{:keys [from in-popover? timestamp-str] :as message} {:keys [modal close-modal]}] - (let [response-to (:response-to (:content message))] - [rn/view {:style (merge {:flex-direction :row :margin-vertical 8} (style/message-wrapper message))} - [rn/view {:style {:width photos.style/default-size - :height photos.style/default-size - :margin-horizontal 8 - :border-radius photos.style/default-size - :justify-content :center - :align-items :center - :background-color quo2.colors/primary-50-opa-10}} - [pin-icon]] - [rn/view - [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 {:font-size 13}} (str " " (i18n/label :pinned-a-message))] - [rn/text - {:style (merge - {:padding-left 5 - :margin-top 2} - (style/message-timestamp-text)) - :accessibility-label :message-timestamp} - timestamp-str]] - [quoted-message response-to (:quoted-message message) true]]])) - (defmethod ->message constants/content-type-community [message] [community-content message]) @@ -561,7 +529,7 @@ [rn/touchable-highlight (when-not modal {:disabled in-popover? :on-press (fn [] - (react/dismiss-keyboard!) + (rn/dismiss-keyboard!) (reset! show-timestamp? true)) :delay-long-press 100 :on-long-press on-long-press}) @@ -580,7 +548,7 @@ :as message} {:keys [on-long-press modal ref] :as reaction-picker}] - (let [pack (get-in content [:sticker :pack]) + (let [pack (get-in content [:sticker :pack]) on-long-press (fn [] (on-long-press (when-not outgoing @@ -597,7 +565,7 @@ :on-press (fn [_] (when pack (re-frame/dispatch [:stickers/open-sticker-pack (str pack)])) - (react/dismiss-keyboard!)) + (rn/dismiss-keyboard!)) :delay-long-press 100 :on-long-press on-long-press}) [fast-image/fast-image {:style {:margin 10 :width 140 :height 140} @@ -660,7 +628,7 @@ :id :reply} {:type :main :on-press #(pin-message message) - :label (i18n/label (if pinned :t/unpin-from-chat :t/pin-to-chat)) + :label (i18n/label (if pinned :t/unpin-from-chat :t/pin-to-chat)) :icon :main-icons/pin-context20 :id (if pinned :unpin :pin)} {:type :danger @@ -681,8 +649,8 @@ [rn/touchable-highlight (when-not modal {:on-long-press on-long-press - :on-press (fn [] - (reset! show-timestamp? true))}) + :on-press (fn [] + (reset! show-timestamp? true))}) [rn/view style/message-view-wrapper [message-timestamp message show-timestamp?] [rn/view {:style (style/message-view message) :accessibility-label :audio-message} @@ -694,7 +662,7 @@ [rn/view {:style {:flex-direction :row}} [quo/text {:style {:margin-right 5.27} :weight :medium - :color :secondary} + :color :secondary} (i18n/label :t/contact-request-pending)] [rn/activity-indicator {:animating true :size :small @@ -713,7 +681,7 @@ (defn contact-request-status-label [state] [rn/view {:style (style/contact-request-status-label state)} (case state - constants/contact-request-message-state-pending [contact-request-status-pending] + constants/contact-request-message-state-pending [contact-request-status-pending] constants/contact-request-message-state-accepted [contact-request-status-accepted] constants/contact-request-message-state-declined [contact-request-status-declined])]) @@ -721,14 +689,14 @@ [message _] [rn/view {:style (style/content-type-contact-request)} [rn/image {:source (resources/get-image :hand-wave) - :style {:width 112 + :style {:width 112 :height 97}}] - [quo/text {:style {:margin-top 6} + [quo/text {:style {:margin-top 6} :weight :bold :size :large} (i18n/label :t/contact-request)] [rn/view {:style {:padding-horizontal 16}} - [quo/text {:style {:margin-top 2 + [quo/text {:style {:margin-top 2 :margin-bottom 14}} (get-in message [:content :text])]] [contact-request-status-label (:contact-request-state message)]]) @@ -737,34 +705,39 @@ [message-content-wrapper message [unknown-content-type message]]) -(defn chat-message [{:keys [pinned pinned-by mentioned] :as message}] - (let [reactions @(re-frame/subscribe [:chats/message-reactions (:message-id message) (:chat-id message)]) - own-reactions (reduce (fn [acc {:keys [emoji-id own]}] - (if own (conj acc emoji-id) acc)) - [] reactions) - send-emoji (fn [{:keys [emoji-id]}] - (re-frame/dispatch [::models.reactions/send-emoji-reaction - {:message-id (:message-id message) - :emoji-id emoji-id}])) - retract-emoji (fn [{:keys [emoji-id emoji-reaction-id]}] - (re-frame/dispatch [::models.reactions/send-emoji-reaction-retraction - {:message-id (:message-id message) - :emoji-id emoji-id - :emoji-reaction-id emoji-reaction-id}])) - on-emoji-press (fn [emoji-id] - (let [active ((set own-reactions) emoji-id)] - (if active - (retract-emoji {:emoji-id emoji-id - :emoji-reaction-id (reactions/extract-id reactions emoji-id)}) - (send-emoji {:emoji-id emoji-id})))) - on-open-drawer (fn [actions] - (re-frame/dispatch [:bottom-sheet/show-sheet - {:content (message-context-drawer/message-options - actions - (into #{} (js->clj own-reactions)) - #(on-emoji-press %))}])) - on-long-press (atom nil)] - [rn/view {:style (merge (when (or mentioned pinned) {:background-color quo2.colors/primary-50-opa-5 :border-radius 16 :margin-bottom 4}) {:margin-horizontal 8})} +(defn chat-message [{:keys [pinned pinned-by mentioned in-pinned-view? last-in-group?] :as message}] + (let [reactions @(re-frame/subscribe [:chats/message-reactions (:message-id message) (:chat-id message)]) + own-reactions (reduce (fn [acc {:keys [emoji-id own]}] + (if own (conj acc emoji-id) acc)) + [] reactions) + send-emoji (fn [{:keys [emoji-id]}] + (re-frame/dispatch [::models.reactions/send-emoji-reaction + {:message-id (:message-id message) + :emoji-id emoji-id}])) + retract-emoji (fn [{:keys [emoji-id emoji-reaction-id]}] + (re-frame/dispatch [::models.reactions/send-emoji-reaction-retraction + {:message-id (:message-id message) + :emoji-id emoji-id + :emoji-reaction-id emoji-reaction-id}])) + on-emoji-press (fn [emoji-id] + (let [active ((set own-reactions) emoji-id)] + (if active + (retract-emoji {:emoji-id emoji-id + :emoji-reaction-id (reactions/extract-id reactions emoji-id)}) + (send-emoji {:emoji-id emoji-id})))) + on-open-drawer (fn [actions] + (re-frame/dispatch [:bottom-sheet/show-sheet + {:content (message-context-drawer/message-options + actions + (into #{} (js->clj own-reactions)) + #(on-emoji-press %))}])) + on-long-press (atom nil)] + [rn/view + {:style (merge (when (and (not in-pinned-view?) (or mentioned pinned)) {:background-color quo2.colors/primary-50-opa-5 + :border-radius 16 + :margin-bottom 4}) + (when (or mentioned pinned last-in-group?) {:margin-top 8}) + {:margin-horizontal 8})} (when pinned [rn/view {:style (style/pin-indicator-container)} [pinned-by-indicator pinned-by]]) @@ -772,3 +745,118 @@ :modal false :on-long-press on-open-drawer}] [reaction-row/message-reactions message reactions nil on-emoji-press on-long-press]])) ;; TODO: pass on-open-drawer function + +(defn message-render-fn + [{:keys [outgoing] :as message} + _ + {:keys [group-chat public? community? current-public-key show-input? message-pin-enabled edit-enabled]}] + [chat-message + (assoc message + :incoming-group (and group-chat (not outgoing)) + :group-chat group-chat + :public? public? + :community? community? + :current-public-key current-public-key + :show-input? show-input? + :message-pin-enabled message-pin-enabled + :in-pinned-view? true + :pinned true + :edit-enabled edit-enabled)]) + +(def list-key-fn #(or (:message-id %) (:value %))) + +(defn pinned-messages-list [chat-id] + (let [pinned-messages (vec (vals (message constants/content-type-pin [{:keys [from in-popover? timestamp-str chat-id] :as message} {:keys [modal close-modal]}] + (let [response-to (:response-to (:content message))] + [rn/touchable-opacity {:on-press (fn [] + (re-frame/dispatch [:bottom-sheet/show-sheet + {:content #(pinned-messages-list chat-id)}])) + :active-opacity 1 + :style (merge {:flex-direction :row :margin-vertical 8} (style/message-wrapper message))} + [rn/view {:style {:width photos.style/default-size + :height photos.style/default-size + :margin-right 16 + :border-radius photos.style/default-size + :justify-content :center + :align-items :center + :background-color quo2.colors/primary-50-opa-10}} + [pin-icon quo2.colors/primary-50 16]] + [rn/view + [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 {:font-size 13}} (str " " (i18n/label :pinned-a-message))] + [rn/text + {:style (merge + {:padding-left 5 + :margin-top 2} + (style/message-timestamp-text)) + :accessibility-label :message-timestamp} + timestamp-str]] + [quoted-message response-to (:quoted-message message) true]]])) + +(defn pinned-banner [chat-id] + (let [pinned-messages ( pins-count 0) + [rn/touchable-opacity + {:style {:height 50 + :background-color quo2.colors/primary-50-opa-20 + :flex-direction :row + :align-items :center + :padding-horizontal 20 + :padding-vertical 10} + :active-opacity 1 + :on-press (fn [] + (re-frame/dispatch [:bottom-sheet/show-sheet + {:content #(pinned-messages-list chat-id)}]))} + [pin-icon (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white) 20] + [rn/text {:number-of-lines 1 + :style (merge typography/paragraph-2 {:margin-left 10 + :margin-right 50 + :color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)})} latest-pin-text] + [rn/view {:style {:position :absolute + :right 22 + :height 20 + :width 20 + :border-radius 8 + :justify-content :center + :align-items :center + :background-color quo2.colors/neutral-80-opa-5}} + [rn/text {:style (merge typography/label typography/font-medium {:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)})} pins-count]]]))) diff --git a/src/status_im/ui2/screens/chat/view.cljs b/src/status_im/ui2/screens/chat/view.cljs index 61659b6035..a847594ed9 100644 --- a/src/status_im/ui2/screens/chat/view.cljs +++ b/src/status_im/ui2/screens/chat/view.cljs @@ -12,7 +12,8 @@ [status-im.ui2.screens.chat.messages.view :as messages] [status-im.utils.handlers :refer [evt]] [status-im.ui.components.icons.icons :as icons] - [re-frame.db])) + [re-frame.db] + [status-im.ui2.screens.chat.messages.message :as message])) (defn topbar-content [] (let [window-width (