feat: autocomplete mentions new ui (#14142)
* feat: autocomplete mentions new ui
This commit is contained in:
parent
7368478033
commit
5492d502fc
|
@ -6,9 +6,10 @@
|
|||
[quo.platform :as platform]
|
||||
[quo.components.text :as text]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[status-im.ui.screens.chat.components.style :as styles]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.handlers :refer [<sub]]
|
||||
[status-im.utils.handlers :refer [<sub >evt]]
|
||||
[status-im.ui.screens.chat.components.reply :as reply]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.chat.constants :as chat.constants]
|
||||
|
@ -331,47 +332,46 @@
|
|||
[idx item])
|
||||
@(re-frame/subscribe [:chat/input-with-mentions]))]
|
||||
^{:key (str idx "_" type "_" text)}
|
||||
[rn/text (when (= type :mention) {:style {:color "#0DA4C9"}})
|
||||
text])
|
||||
[rn/text (when (= type :mention) {:style {:color quo2.colors/primary-50}}) text])
|
||||
(get @input-texts chat-id))]))
|
||||
|
||||
(defn mention-item
|
||||
[[public-key {:keys [alias name nickname] :as user}] _ _ text-input-ref]
|
||||
(let [ens-name? (not= alias name)]
|
||||
[list-item/list-item
|
||||
(cond-> {:icon [photos/member-photo public-key]
|
||||
:size :small
|
||||
:text-size :small
|
||||
:title
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:size :small}
|
||||
(if nickname
|
||||
nickname
|
||||
name)
|
||||
(when nickname
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:color :secondary
|
||||
:ellipsize-mode :tail
|
||||
:size :small}
|
||||
" "
|
||||
(when ens-name?
|
||||
"@")
|
||||
name])]
|
||||
:title-text-weight :medium
|
||||
:on-press
|
||||
(fn []
|
||||
(re-frame/dispatch [:chat.ui/select-mention text-input-ref user]))}
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(re-frame/dispatch [:chat.ui/select-mention text-input-ref user])}
|
||||
|
||||
ens-name?
|
||||
(assoc :subtitle alias))]))
|
||||
[list-item/list-item
|
||||
(cond-> {:icon [photos/member-photo public-key]
|
||||
:size :small
|
||||
:text-size :small
|
||||
:title
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:size :small}
|
||||
(if nickname
|
||||
nickname
|
||||
name)
|
||||
(when nickname
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:color :secondary
|
||||
:ellipsize-mode :tail
|
||||
:size :small}
|
||||
" "
|
||||
(when ens-name?
|
||||
"@")
|
||||
name])]
|
||||
:title-text-weight :medium}
|
||||
|
||||
ens-name?
|
||||
(assoc :subtitle alias))]]))
|
||||
|
||||
(def chat-toolbar-height (reagent/atom nil))
|
||||
|
||||
(defn autocomplete-mentions [text-input-ref bottom]
|
||||
(defn autocomplete-mentions-old [text-input-ref bottom]
|
||||
(let [suggestions @(re-frame/subscribe [:chat/mention-suggestions])]
|
||||
(when (seq suggestions)
|
||||
(let [height (+ 16 (* 52 (min 4.5 (count suggestions))))]
|
||||
|
@ -389,6 +389,22 @@
|
|||
:render-data text-input-ref
|
||||
:render-fn mention-item}]]]))))
|
||||
|
||||
(defn autocomplete-mentions [suggestions]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [animation (reanimated/use-shared-value 0)]
|
||||
(quo.react/effect! #(do
|
||||
(reanimated/set-shared-value animation (reanimated/with-timing (if (seq suggestions) 0 200)))))
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY animation}]}
|
||||
{:bottom 0 :position :absolute :z-index 5 :max-height 180})}
|
||||
[list/flat-list
|
||||
{:keyboardShouldPersistTaps :always
|
||||
:data suggestions
|
||||
:key-fn first
|
||||
:render-fn mention-item
|
||||
:content-container-style {:padding-bottom 12}}]]))])
|
||||
|
||||
(defn on-chat-toolbar-layout [^js ev]
|
||||
(reset! chat-toolbar-height (-> ev .-nativeEvent .-layout .-height)))
|
||||
|
||||
|
@ -475,6 +491,21 @@
|
|||
(swap! context assoc :state :min)
|
||||
min-y)))
|
||||
|
||||
(defn calculate-y-with-mentions [y max-y max-height chat-id suggestions reply]
|
||||
(let [input-text (:input-text (get (<sub [:chat/inputs]) chat-id))
|
||||
num-lines (count (string/split input-text "\n"))
|
||||
text-height (* num-lines 22)
|
||||
mentions-height (min 132 (+ 16 (* 46 (- (count suggestions) 1))))
|
||||
should-translate (if (< (- max-height text-height) mentions-height) true false)
|
||||
min-value (if-not reply mentions-height (+ mentions-height 44))
|
||||
; translate value when mentions list appear while at bottom of expanded input sheet
|
||||
mentions-translate-value (if should-translate (min min-value (- mentions-height (- max-height text-height))) mentions-height)]
|
||||
(when (or (< y max-y) should-translate) mentions-translate-value)))
|
||||
|
||||
(defn get-y-value [context keyboard-shown min-y max-y added-value max-height chat-id suggestions reply]
|
||||
(let [y (calculate-y context keyboard-shown min-y max-y added-value)]
|
||||
y (+ y (when (seq suggestions) (calculate-y-with-mentions y max-y max-height chat-id suggestions reply)))))
|
||||
|
||||
(defn get-bottom-sheet-gesture [context translate-y text-input-ref keyboard-shown min-y max-y shared-height max-height bg-opacity]
|
||||
(-> (gesture/gesture-pan)
|
||||
(gesture/on-start
|
||||
|
@ -564,18 +595,17 @@
|
|||
[:f>
|
||||
(fn []
|
||||
(let [reply (<sub [:chats/reply-message])
|
||||
suggestions (<sub [:chat/mention-suggestions])
|
||||
{window-height :height} (rn/use-window-dimensions)
|
||||
{:keys [keyboard-shown keyboard-height]} (rn/use-keyboard)
|
||||
|
||||
max-y (- window-height (if (> keyboard-height 0) keyboard-height 360) (:top insets)) ; 360 - default height
|
||||
max-height (- max-y 56 (:bottom insets)) ; 56 - top-bar height
|
||||
added-value (if reply 38 0) ; increased height of input box needed when reply
|
||||
min-y (+ min-y added-value)
|
||||
y (calculate-y context keyboard-shown min-y max-y added-value)
|
||||
added-value (if (and (not (seq suggestions)) reply) 38 0) ; increased height of input box needed when reply
|
||||
min-y (+ min-y (when reply 38))
|
||||
y (get-y-value context keyboard-shown min-y max-y added-value max-height chat-id suggestions reply)
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
shared-height (reanimated/use-shared-value min-y)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
|
||||
input-content-change (get-input-content-change context translate-y shared-height max-height
|
||||
bg-opacity keyboard-shown min-y max-y)
|
||||
bottom-sheet-gesture (get-bottom-sheet-gesture context translate-y (:text-input-ref refs) keyboard-shown
|
||||
|
@ -607,19 +637,21 @@
|
|||
:refs refs
|
||||
:set-active-panel #()}]]]]
|
||||
;CONTROLS
|
||||
[rn/view {:style (styles/new-bottom-sheet-controls insets)}
|
||||
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/image]
|
||||
[rn/view {:width 12}]
|
||||
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/reaction]
|
||||
[rn/view {:flex 1}]
|
||||
;;SEND button
|
||||
[rn/view {:ref send-ref :style (when-not (seq (get @input-texts chat-id)) {:width 0 :right -100})}
|
||||
[quo2.button/button {:icon true :size 32 :accessibility-label :send-message-button
|
||||
:on-press #(do (swap! context assoc :clear true)
|
||||
(clear-input chat-id refs)
|
||||
(re-frame/dispatch [:chat.ui/send-current-message]))}
|
||||
:main-icons2/arrow-up]]]
|
||||
(when-not (seq suggestions)
|
||||
[rn/view {:style (styles/new-bottom-sheet-controls insets)}
|
||||
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/image]
|
||||
[rn/view {:width 12}]
|
||||
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/reaction]
|
||||
[rn/view {:flex 1}]
|
||||
;;SEND button
|
||||
[rn/view {:ref send-ref :style (when-not (seq (get @input-texts chat-id)) {:width 0 :right -100})}
|
||||
[quo2.button/button {:icon true :size 32 :accessibility-label :send-message-button
|
||||
:on-press #(do (swap! context assoc :clear true)
|
||||
(clear-input chat-id refs)
|
||||
(>evt [:chat.ui/send-current-message]))}
|
||||
:main-icons2/arrow-up]]])
|
||||
;black background
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||
{:opacity bg-opacity}
|
||||
(styles/new-bottom-sheet-background window-height))}]]))])))])
|
||||
(styles/new-bottom-sheet-background window-height))}]
|
||||
[autocomplete-mentions suggestions]]))])))])
|
||||
|
|
|
@ -143,7 +143,8 @@
|
|||
:bottom bottom
|
||||
:background-color (colors/get-color :ui-background)
|
||||
:border-top-width 1
|
||||
:border-top-color (colors/get-color :ui-01)})
|
||||
:border-top-color (colors/get-color :ui-01)
|
||||
:z-index 3})
|
||||
|
||||
(defn new-input-bottom-sheet [window-height]
|
||||
(merge {:border-top-left-radius 20
|
||||
|
@ -155,7 +156,7 @@
|
|||
:height window-height
|
||||
:flex 1
|
||||
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)
|
||||
:z-index 1000}
|
||||
:z-index 2}
|
||||
(if platform/ios?
|
||||
{:shadow-radius 16
|
||||
:shadow-opacity 1
|
||||
|
@ -176,7 +177,7 @@
|
|||
{:flex-direction :row
|
||||
:padding-horizontal 20
|
||||
:elevation 2
|
||||
:z-index 2000
|
||||
:z-index 2
|
||||
:position :absolute
|
||||
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)
|
||||
;these 3 props play together, we need this magic to hide message text in the safe area
|
||||
|
@ -192,4 +193,4 @@
|
|||
:bottom 0
|
||||
:height window-height
|
||||
:background-color quo2.colors/neutral-95-opa-70
|
||||
:z-index 500})
|
||||
:z-index 1})
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
[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]
|
||||
|
@ -131,13 +134,14 @@
|
|||
destination])
|
||||
|
||||
"mention"
|
||||
(conj acc [react/text-class
|
||||
{:style {:color (cond
|
||||
(= content-type constants/content-type-system-text) colors/black
|
||||
:else colors/mention-incoming)}
|
||||
:on-press (when-not (= content-type constants/content-type-system-text)
|
||||
#(re-frame/dispatch [:chat.ui/show-profile literal]))}
|
||||
[mention-element literal]])
|
||||
(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)
|
||||
#(>evt [:chat.ui/show-profile literal]))}
|
||||
[mention-element literal]]])
|
||||
"status-tag"
|
||||
(conj acc [react/text-class
|
||||
{:style {:color colors/blue
|
||||
|
@ -334,7 +338,7 @@
|
|||
content]
|
||||
content)
|
||||
[link-preview/link-preview-wrapper (:links (:content message)) false false]]]
|
||||
; delivery status
|
||||
; delivery status
|
||||
[react/view (style/delivery-status)
|
||||
[message-delivery-status message]]]))
|
||||
|
||||
|
@ -706,7 +710,7 @@
|
|||
[message-content-wrapper message
|
||||
[unknown-content-type message]])
|
||||
|
||||
(defn chat-message [{:keys [display-photo? pinned pinned-by] :as message}]
|
||||
(defn chat-message [{:keys [display-photo? 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))
|
||||
|
@ -733,7 +737,7 @@
|
|||
(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})}
|
||||
[->message message {:ref on-long-press
|
||||
:modal false
|
||||
:on-long-press on-open-drawer}]
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
(defn message-author-userpic []
|
||||
(merge
|
||||
{:width (+ 16 photos/default-size)} ;; 16 is for the padding
|
||||
{:padding-left 8
|
||||
{:padding-left 0
|
||||
:padding-right 8}))
|
||||
|
||||
(def delivery-text
|
||||
|
@ -171,21 +171,8 @@
|
|||
:flex-direction :row-reverse})
|
||||
|
||||
(defn message-view
|
||||
[{:keys [content-type mentioned pinned]}]
|
||||
[{:keys [content-type]}]
|
||||
(merge
|
||||
{:border-radius 10}
|
||||
|
||||
(cond
|
||||
pinned {:background-color colors/pin-background}
|
||||
(= 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}
|
||||
:else {:background-color colors/white})
|
||||
|
||||
(when (= content-type constants/content-type-emoji)
|
||||
{:flex-direction :row})))
|
||||
|
||||
|
|
|
@ -419,7 +419,7 @@
|
|||
:keyboard-should-persist-taps :handled
|
||||
:onMomentumScrollBegin state/start-scrolling
|
||||
:onMomentumScrollEnd state/stop-scrolling
|
||||
;;TODO https://github.com/facebook/react-native/issues/30034
|
||||
;;TODO https://github.com/facebook/react-native/issues/30034
|
||||
:inverted (when platform/ios? true)
|
||||
:style (when platform/android? {:scaleY -1})})]))
|
||||
|
||||
|
@ -502,7 +502,7 @@
|
|||
:onMomentumScrollEnd state/stop-scrolling
|
||||
:scrollEventThrottle 16
|
||||
:on-scroll on-scroll
|
||||
;;TODO https://github.com/facebook/react-native/issues/30034
|
||||
;;TODO https://github.com/facebook/react-native/issues/30034
|
||||
:inverted (when platform/ios? true)
|
||||
:style (when platform/android? {:scaleY -1})})]
|
||||
(when @show-floating-scroll-down-button
|
||||
|
@ -602,7 +602,7 @@
|
|||
[accessory/view {:y position-y
|
||||
:on-update-inset on-update}
|
||||
[invitation-bar chat-id]])
|
||||
[components/autocomplete-mentions text-input-ref max-bottom-space]
|
||||
[components/autocomplete-mentions-old text-input-ref max-bottom-space]
|
||||
(when show-input?
|
||||
;; NOTE: this only accepts two children
|
||||
[accessory/view {:y position-y
|
||||
|
|
Loading…
Reference in New Issue