feat: pinned messages new ui (#14147)

* feat: pinned messages new ui
This commit is contained in:
Omar Basem 2022-10-13 22:27:56 +04:00 committed by GitHub
parent 5492d502fc
commit af3ba74e30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 114 additions and 77 deletions

View File

@ -4,6 +4,7 @@
[status-im.data-store.pin-messages :as data-store.pin-messages]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]
[status-im.transport.message.protocol :as protocol]
[re-frame.core :as re-frame]))
(fx/defn handle-failed-loading-pin-messages
@ -73,7 +74,8 @@
{:events [::send-pin-message]}
[{:keys [db] :as cofx} {:keys [chat-id message-id pinned] :as pin-message}]
(let [current-public-key (get-in db [:multiaccount :public-key])
message (merge pin-message {:pinned-by current-public-key})]
message (merge pin-message {:pinned-by current-public-key})
preferred-name (get-in db [:multiaccount :preferred-name])]
(fx/merge cofx
{:db (cond-> db
pinned
@ -86,7 +88,12 @@
(update-in [:pin-messages chat-id] dissoc message-id)))}
(data-store.pin-messages/send-pin-message {:chat-id (pin-message :chat-id)
:message_id (pin-message :message-id)
:pinned (pin-message :pinned)}))))
:pinned (pin-message :pinned)})
(when pinned
(protocol/send-chat-messages [{:chat-id (pin-message :chat-id)
:content-type constants/content-type-pin
:response-to (pin-message :message-id)
:ens-name preferred-name}])))))
(fx/defn load-pin-messages
{:events [::load-pin-messages]}

View File

@ -14,6 +14,7 @@
(def ^:const content-type-community 9)
(def ^:const content-type-gap 10)
(def ^:const content-type-contact-request 11) ;; TODO: temp, will be removed
(def ^:const content-type-pin 13)
(def ^:const contact-request-state-none 0)
(def ^:const contact-request-state-mutual 1)

View File

@ -31,7 +31,7 @@
(defn edit-message []
[rn/view {:style {:flex-direction :row :height 24}}
[rn/view {:style (styles/reply-content)}
[rn/view {:style (styles/reply-content false)}
[icons/icon :main-icons/edit-connector {:color (theme-colors quo2.colors/neutral-40 quo2.colors/neutral-60)
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}]
[rn/view {:style {:position :absolute :left 36 :right 54 :top 3 :flex-direction :row :align-items :center}}

View File

@ -81,15 +81,16 @@
[icons/icon :main-icons/close-circle {:container-style (styles/close-button)
:color (:icon-02 @quo.colors/theme)}]]]]))
(defn reply-message [{:keys [from identicon content-type contentType parsed-text content]} in-chat-input?]
; This component is also used for quoted pinned message as the UI is very similar
(defn reply-message [{:keys [from identicon content-type contentType parsed-text content]} in-chat-input? pin?]
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])
current-public-key @(re-frame/subscribe [:multiaccount/public-key])
content-type (or content-type contentType)]
[rn/view {:style {:flex-direction :row :height 24}}
[rn/view {:style (styles/reply-content)}
[icons/icon :main-icons/connector {:color (theme-colors quo2.colors/neutral-40 quo2.colors/neutral-60)
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}]
[rn/view {:style {:position :absolute :left 34 :top 3 :flex-direction :row :align-items :center :width "45%"}}
[rn/view {:style {:flex-direction :row :height (when-not pin? 24)}}
[rn/view {:style (styles/reply-content pin?)}
(when-not pin? [icons/icon :main-icons/connector {:color (theme-colors quo2.colors/neutral-40 quo2.colors/neutral-60)
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}])
[rn/view {:style (styles/quoted-message pin?)}
[photos/member-photo from identicon 16]
[quo2.text/text {:weight :semi-bold
:size :paragraph-2
@ -125,7 +126,7 @@
(defn send-image [images]
[rn/view {:style (styles/reply-container-image)}
[rn/scroll-view {:horizontal true
:style (styles/reply-content)}
:style (styles/reply-content false)}
(for [{:keys [uri]} (vals images)]
^{:key uri}
[rn/image {:source {:uri uri}

View File

@ -108,11 +108,19 @@
:padding-horizontal 10
:flex 1})
(defn reply-content []
{:padding-horizontal 10
(defn reply-content [pin?]
{:padding-horizontal (when-not pin? 10)
:flex 1
:flex-direction :row})
(defn quoted-message [pin?]
(merge {:flex-direction :row
:align-items :center
:width "45%"}
(when-not pin? {:position :absolute
:left 34
:top 3})))
(defn contact-request-content []
{:flex 1
:flex-direction :row

View File

@ -12,9 +12,6 @@
[status-im.react-native.resources :as resources]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.fast-image :as fast-image]
[status-im.utils.handlers :refer [>evt]]
[quo2.foundations.colors :as quo2.colors]
[quo2.foundations.typography :as typography]
[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]
@ -30,9 +27,14 @@
[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.communities.icon :as communities.icon]
[status-im.utils.handlers :refer [>evt]]
[status-im.utils.config :as config]
[status-im.utils.security :as security])
[status-im.utils.security :as security]
[quo2.foundations.typography :as typography]
[quo2.foundations.colors :as quo2.colors])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn message-timestamp-anim
@ -93,9 +95,12 @@
timestamp-str]])))
(defview quoted-message
[_ reply]
[react/view {:style (style/quoted-message-container)}
[components.reply/reply-message reply false]])
[_ reply pin?]
[react/view {:style (when-not pin? (style/quoted-message-container))}
[components.reply/reply-message reply false pin?]])
(defn system-text? [content-type]
(= content-type constants/content-type-system-text))
(defn render-inline [message-text content-type acc {:keys [type literal destination]}]
(case type
@ -137,9 +142,9 @@
(conj acc
[react/view {:style {:background-color quo2.colors/primary-50-opa-10 :border-radius 6 :padding-horizontal 3}}
[react/text-class
{:style (merge {:color (if (= content-type constants/content-type-system-text) colors/black (:text-04 @colors/theme))}
(if (= content-type constants/content-type-system-text) typography/font-regular typography/font-medium))
:on-press (when-not (= content-type constants/content-type-system-text)
{:style (merge {:color (if (system-text? content-type) colors/black quo2.colors/primary-50)}
(if (system-text? content-type) typography/font-regular typography/font-medium))
:on-press (when-not (system-text? content-type)
#(>evt [:chat.ui/show-profile literal]))}
[mention-element literal]]])
"status-tag"
@ -226,26 +231,20 @@
;; 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 9)
(def pin-icon-width 10)
(def pin-icon-height 15)
(defn pinned-by-indicator [display-photo? pinned-by]
[react/view {:style (style/pin-indicator display-photo?)
:accessibility-label :pinned-by}
[react/view {:style (style/pinned-by-text-icon-container)}
[react/view {:style (style/pin-icon-container)}
[icons/icon :main-icons/pin {:color colors/gray
(defn pin-icon []
[icons/icon :main-icons/pin16 {:color (:text-04 @colors/theme)
:height pin-icon-height
:width pin-icon-width
:background-color :red}]]
[quo/text {:weight :regular
:size :small
:color :main
:style (style/pinned-by-text)}
(i18n/label :t/pinned-by)]]
[quo/text {:weight :medium
:size :small
:width pin-icon-width}])
(defn pinned-by-indicator [pinned-by]
[react/view {:style (style/pin-indicator)
:accessibility-label :pinned-by}
[pin-icon]
[quo/text {:size :small
:color :main
:style (style/pin-author-text)}
(pin-author-name pinned-by)]])
@ -300,7 +299,7 @@
[{:keys [last-in-group?
identicon
from in-popover? timestamp-str
deleted-for-me?]
deleted-for-me? pinned]
:as message} content {:keys [modal close-modal]}]
(let [response-to (:response-to (:content message))]
[react/view {:style (style/message-wrapper message)
@ -311,12 +310,12 @@
[react/view {:style (style/message-body)
:pointer-events :box-none}
[react/view (style/message-author-userpic)
(when (or (and (seq response-to) (:quoted-message message)) last-in-group?)
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
[react/touchable-highlight {:on-press #(do (when modal (close-modal))
(re-frame/dispatch [:chat.ui/show-profile from]))}
[photos/member-photo from identicon]])]
[react/view {:style (style/message-author-wrapper)}
(when (or (and (seq response-to) (:quoted-message message)) last-in-group?)
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
[react/view {:style {:flex-direction :row :align-items :center}}
[react/touchable-opacity {:style style/message-author-touchable
:disabled in-popover?
@ -492,6 +491,34 @@
[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))]
[react/view {:style (merge {:flex-direction :row :margin-vertical 8} (style/message-wrapper message))}
[react/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]]
[react/view
[react/view {:style {:flex-direction :row :align-items :center}}
[react/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}]]
[react/text {:style {:font-size 13}} (str " " (i18n/label :pinned-a-message))]
[react/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])
@ -710,7 +737,7 @@
[message-content-wrapper message
[unknown-content-type message]])
(defn chat-message [{:keys [display-photo? pinned pinned-by mentioned] :as 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))
@ -737,11 +764,12 @@
(into #{} (js->clj own-reactions))
#(on-emoji-press %))}]))
on-long-press (atom nil)]
[react/view {:style (merge (when mentioned {:background-color quo2.colors/primary-50-opa-5 :border-radius 16 :margin-bottom 4}) {:margin-horizontal 8})}
[react/view {:style (merge (when (or mentioned pinned) {:background-color quo2.colors/primary-50-opa-5 :border-radius 16 :margin-bottom 4}) {:margin-horizontal 8})}
(when pinned
[react/view {:style (style/pin-indicator-container)}
[pinned-by-indicator pinned-by]])
[->message message {:ref on-long-press
: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
(when pinned
[react/view {:style (style/pin-indicator-container)}
[pinned-by-indicator display-photo? pinned-by]])]))
]))

View File

@ -92,6 +92,7 @@
(defn reactions-row [timeline margin-top]
{:flex-direction :row
:padding-right 8
:padding-bottom 8
:justify-content :flex-start
:margin-top margin-top
:flex-wrap :wrap

View File

@ -3,7 +3,8 @@
[quo.design-system.colors :as colors]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.styles.photos :as photos]
[quo2.foundations.colors :as quo2.colors]))
[quo2.foundations.colors :as quo2.colors]
[quo2.foundations.typography :as typography]))
(defn style-message-text
[]
@ -71,30 +72,15 @@
{:align-self :flex-start
:padding-left 8})
(defn pin-indicator [display-photo?]
(merge
{:flex-direction :row
:border-top-left-radius 4
:border-top-right-radius 12
:border-bottom-left-radius 12
:border-bottom-right-radius 12
:padding-left 8
:padding-right 10
:padding-vertical 5
:background-color colors/gray-lighter
:justify-content :center
:max-width "80%"
:align-self :flex-start
:align-items :flex-start}
(when display-photo?
{:margin-left 44})))
(defn pin-indicator []
(merge {:flex-direction :row}))
(defn pin-indicator-container []
{:margin-top 2
{:margin-top 8
:margin-left 68
:justify-content :center
:align-self :flex-start
:align-items :flex-start
:padding-left 8})
:align-items :flex-start})
(defn pinned-by-text-icon-container []
{:flex-direction :row
@ -108,14 +94,9 @@
:margin-top 1})
(defn pin-author-text []
{:margin-left 2
:margin-right 12
:padding-right 0
:left 12
:flex-direction :row
:flex-shrink 1
:align-self :flex-start
:overflow :hidden})
(merge typography/font-medium
{:color quo2.colors/primary-50
:bottom 2}))
(defn pinned-by-text []
{:margin-left 5})
@ -171,8 +152,18 @@
:flex-direction :row-reverse})
(defn message-view
[{:keys [content-type]}]
[{:keys [content-type mentioned]}]
(merge
{:border-radius 10}
(cond
(= content-type constants/content-type-system-text) nil
mentioned {:background-color colors/mentioned-background
:border-color colors/mentioned-border
:border-width 1}
(= content-type constants/content-type-audio) {:background-color colors/blue
:padding-horizontal 12
:padding-top 6})
(when (= content-type constants/content-type-emoji)
{:flex-direction :row})))