diff --git a/src/status_im2/contexts/chat/composer/constants.cljs b/src/status_im2/contexts/chat/composer/constants.cljs index ef24109dfc..d101cea05a 100644 --- a/src/status_im2/contexts/chat/composer/constants.cljs +++ b/src/status_im2/contexts/chat/composer/constants.cljs @@ -17,9 +17,15 @@ (def ^:const empty-opacity 0.7) -(def ^:const images-container-height 76) +(def ^:const images-padding-top 12) +(def ^:const images-padding-bottom 8) +(def ^:const images-container-height + (+ actions-container-height images-padding-top images-padding-bottom)) -(def ^:const links-container-height 76) +(def ^:const links-padding-top 12) +(def ^:const links-padding-bottom 8) +(def ^:const links-container-height + (+ actions-container-height links-padding-top links-padding-bottom)) (def ^:const reply-container-height 32) diff --git a/src/status_im2/contexts/chat/composer/effects.cljs b/src/status_im2/contexts/chat/composer/effects.cljs index 4160a98a7e..9ff63c82a7 100644 --- a/src/status_im2/contexts/chat/composer/effects.cljs +++ b/src/status_im2/contexts/chat/composer/effects.cljs @@ -168,20 +168,13 @@ (defn link-previews [{:keys [sending-links?]} {:keys [text-value maximized?]} - {:keys [height saved-height last-height]} + {:keys [height saved-height]} {:keys [link-previews?]}] (rn/use-effect (fn [] (if-not @maximized? - (let [value (if link-previews? - constants/links-container-height - (- constants/links-container-height))] - (when (not= @sending-links? link-previews?) - (reanimated/animate height (+ (reanimated/get-shared-value saved-height) value)) - (reanimated/set-shared-value saved-height - (+ (reanimated/get-shared-value saved-height) value)) - (reanimated/set-shared-value last-height - (+ (reanimated/get-shared-value last-height) value)))) + (when (not= @sending-links? link-previews?) + (reanimated/animate height (reanimated/get-shared-value saved-height))) (let [curr-text @text-value] (reset! text-value (str @text-value " ")) (js/setTimeout #(reset! text-value curr-text) 100))) @@ -191,7 +184,7 @@ (defn use-images [{:keys [sending-images? input-ref]} {:keys [text-value maximized?]} - {:keys [container-opacity height saved-height last-height]} + {:keys [container-opacity height saved-height]} {:keys [images]}] (rn/use-effect (fn [] @@ -200,15 +193,8 @@ (when (and (not @sending-images?) (seq images) @input-ref) (.focus ^js @input-ref)) (if-not @maximized? - (let [value (if (seq images) - constants/images-container-height - (- constants/images-container-height))] - (when (not= @sending-images? (boolean (seq images))) - (reanimated/animate height (+ (reanimated/get-shared-value saved-height) value)) - (reanimated/set-shared-value saved-height - (+ (reanimated/get-shared-value saved-height) value)) - (reanimated/set-shared-value last-height - (+ (reanimated/get-shared-value last-height) value)))) + (when (not= @sending-images? (boolean (seq images))) + (reanimated/animate height (reanimated/get-shared-value saved-height))) (let [curr-text @text-value] (reset! text-value (str @text-value " ")) (js/setTimeout #(reset! text-value curr-text) 100))) diff --git a/src/status_im2/contexts/chat/composer/gesture.cljs b/src/status_im2/contexts/chat/composer/gesture.cljs index 6a127a39c5..3d786ad845 100644 --- a/src/status_im2/contexts/chat/composer/gesture.cljs +++ b/src/status_im2/contexts/chat/composer/gesture.cljs @@ -59,7 +59,6 @@ [{:keys [input-ref] :as props} {:keys [gesture-enabled?] :as state} {:keys [height saved-height last-height opacity background-y container-opacity] :as animations} - {:keys [images link-previews?]} {:keys [max-height lines] :as dimensions} keyboard-shown] (let [expanding? (atom true) @@ -82,7 +81,7 @@ (gesture/on-update (fn [event] (let [translation (oops/oget event "translationY") - min-height (utils/get-min-height lines images link-previews?) + min-height (utils/get-min-height lines) new-height (- (reanimated/get-shared-value saved-height) translation) bounded-height (utils.number/value-in-range new-height min-height max-height)] (when keyboard-shown diff --git a/src/status_im2/contexts/chat/composer/gradients/style.cljs b/src/status_im2/contexts/chat/composer/gradients/style.cljs index 5163246bd6..54796ba3e2 100644 --- a/src/status_im2/contexts/chat/composer/gradients/style.cljs +++ b/src/status_im2/contexts/chat/composer/gradients/style.cljs @@ -4,24 +4,27 @@ [react-native.reanimated :as reanimated] [status-im2.contexts.chat.composer.constants :as constants])) -(defn top-gradient-style - [opacity z-index] +(defn- top-gradient-style + [opacity z-index showing-extra-space?] (reanimated/apply-animations-to-style {:opacity opacity} - {:height 80 + {:height (when (pos-int? z-index) 80) :position :absolute :z-index z-index - :top 0 + :top (+ constants/bar-container-height + (if showing-extra-space? + constants/edit-container-height + 0)) :left 0 :right 0})) (defn top-gradient - [opacity z-index] + [opacity z-index showing-extra-space?] {:colors [(colors/theme-colors colors/white-opa-0 colors/neutral-95-opa-0) (colors/theme-colors colors/white colors/neutral-95)] :start {:x 0 :y 1} :end {:x 0 :y 0} - :style (top-gradient-style opacity z-index)}) + :style (top-gradient-style opacity z-index showing-extra-space?)}) (def bottom-gradient-style {:height constants/line-height diff --git a/src/status_im2/contexts/chat/composer/gradients/view.cljs b/src/status_im2/contexts/chat/composer/gradients/view.cljs index 383956ed85..165b24c069 100644 --- a/src/status_im2/contexts/chat/composer/gradients/view.cljs +++ b/src/status_im2/contexts/chat/composer/gradients/view.cljs @@ -3,22 +3,25 @@ [react-native.core :as rn] [react-native.linear-gradient :as linear-gradient] [react-native.reanimated :as reanimated] - [status-im2.contexts.chat.composer.gradients.style :as style])) - + [status-im2.contexts.chat.composer.gradients.style :as style] + [utils.re-frame :as rf])) (defn f-view [{:keys [input-ref]} {:keys [gradient-z-index]} {:keys [gradient-opacity]} show-bottom-gradient?] - [:<> - [reanimated/linear-gradient (style/top-gradient gradient-opacity @gradient-z-index)] - (when show-bottom-gradient? - [rn/touchable-without-feedback - {:on-press #(when @input-ref (.focus ^js @input-ref)) - :accessibility-label :bottom-gradient} - [linear-gradient/linear-gradient (style/bottom-gradient)]])]) + (let [showing-extra-space? (boolean (or (rf/sub [:chats/edit-message]) + (rf/sub [:chats/reply-message])))] + [:<> + [reanimated/linear-gradient + (style/top-gradient gradient-opacity @gradient-z-index showing-extra-space?)] + (when show-bottom-gradient? + [rn/pressable + {:on-press #(when @input-ref (.focus ^js @input-ref)) + :accessibility-label :bottom-gradient} + [linear-gradient/linear-gradient (style/bottom-gradient)]])])) + (defn view [props state animations show-bottom-gradient?] [:f> f-view props state animations show-bottom-gradient?]) - diff --git a/src/status_im2/contexts/chat/composer/handlers.cljs b/src/status_im2/contexts/chat/composer/handlers.cljs index 4dc9e6a15f..dd58dd4d5f 100644 --- a/src/status_im2/contexts/chat/composer/handlers.cljs +++ b/src/status_im2/contexts/chat/composer/handlers.cljs @@ -43,14 +43,12 @@ {:keys [images link-previews? reply]}] (when-not @recording? (let [lines (utils/calc-lines (- @content-height constants/extra-content-offset)) - min-height (utils/get-min-height lines images link-previews?) + min-height (utils/get-min-height lines) reopen-height (utils/calc-reopen-height text-value min-height max-height content-height - saved-height - images - link-previews?)] + saved-height)] (reset! focused? false) (rf/dispatch [:chat.ui/set-input-focused false]) (reanimated/set-shared-value last-height reopen-height) @@ -72,21 +70,19 @@ [event {:keys [maximized? lock-layout? text-value]} {:keys [height saved-height opacity background-y]} - {:keys [images link-previews?]} {:keys [content-height window-height max-height]} keyboard-shown] (when keyboard-shown - (let [event-size (oops/oget event "nativeEvent.contentSize.height") - content-size (+ event-size constants/extra-content-offset) - lines (utils/calc-lines event-size) - content-size (if (or (= lines 1) (empty? @text-value)) - constants/input-height - (if (= lines 2) constants/multiline-minimized-height content-size)) - new-height (utils.number/value-in-range content-size - constants/input-height - max-height) - bottom-content-height (utils/calc-bottom-content-height images link-previews?) - new-height (min (+ new-height bottom-content-height) max-height)] + (let [event-size (oops/oget event "nativeEvent.contentSize.height") + content-size (+ event-size constants/extra-content-offset) + lines (utils/calc-lines event-size) + content-size (if (or (= lines 1) (empty? @text-value)) + constants/input-height + (if (= lines 2) constants/multiline-minimized-height content-size)) + new-height (utils.number/value-in-range content-size + constants/input-height + max-height) + new-height (min new-height max-height)] (reset! content-height content-size) (when (utils/update-height? content-size height max-height maximized?) (reanimated/animate height new-height) diff --git a/src/status_im2/contexts/chat/composer/images/style.cljs b/src/status_im2/contexts/chat/composer/images/style.cljs index 1ee9987da0..5657a39cdd 100644 --- a/src/status_im2/contexts/chat/composer/images/style.cljs +++ b/src/status_im2/contexts/chat/composer/images/style.cljs @@ -1,10 +1,11 @@ (ns status-im2.contexts.chat.composer.images.style (:require - [quo.foundations.colors :as colors])) + [quo.foundations.colors :as colors] + [status-im2.contexts.chat.composer.constants :as constants])) (def image-container - {:padding-top 12 - :padding-bottom 8 + {:padding-top constants/images-padding-top + :padding-bottom constants/images-padding-bottom :padding-right 12}) (defn remove-photo-container @@ -32,4 +33,3 @@ {:width 56 :height 56 :border-radius 12}) - diff --git a/src/status_im2/contexts/chat/composer/link_preview/style.cljs b/src/status_im2/contexts/chat/composer/link_preview/style.cljs index fb9a4ddbff..068a13d65b 100644 --- a/src/status_im2/contexts/chat/composer/link_preview/style.cljs +++ b/src/status_im2/contexts/chat/composer/link_preview/style.cljs @@ -1,13 +1,12 @@ -(ns status-im2.contexts.chat.composer.link-preview.style) +(ns status-im2.contexts.chat.composer.link-preview.style + (:require [status-im2.contexts.chat.composer.constants :as constants])) (def padding-horizontal 20) -(def preview-list-padding-top 12) -(def preview-list-padding-bottom 8) (def preview-height 56) (def preview-list - {:padding-top preview-list-padding-top - :padding-bottom preview-list-padding-bottom + {:padding-top constants/links-padding-top + :padding-bottom constants/links-padding-bottom :margin-horizontal (- padding-horizontal) ;; Keep a high index, otherwise the parent gesture detector used by the ;; composer grabs the initiating gesture event. diff --git a/src/status_im2/contexts/chat/composer/mentions/view.cljs b/src/status_im2/contexts/chat/composer/mentions/view.cljs index 2b0134abbd..56f2abbcd9 100644 --- a/src/status_im2/contexts/chat/composer/mentions/view.cljs +++ b/src/status_im2/contexts/chat/composer/mentions/view.cljs @@ -31,18 +31,19 @@ (defn- f-view [suggestions-atom props state animations max-height cursor-pos images link-previews? reply edit] - (let [suggestions (rf/sub [:chat/mention-suggestions]) - opacity (reanimated/use-shared-value (if (seq suggestions) 1 0)) - size (count suggestions) - data {:keyboard-height @(:kb-height state) - :insets (safe-area/get-insets) - :curr-height (reanimated/get-shared-value (:height animations)) - :window-height (:height (rn/get-window)) - :images images - :link-previews? link-previews? - :reply reply - :edit edit} - mentions-pos (utils/calc-suggestions-position cursor-pos max-height size state data)] + (let [suggestions (rf/sub [:chat/mention-suggestions]) + opacity (reanimated/use-shared-value (if (seq suggestions) 1 0)) + size (count suggestions) + data {:keyboard-height @(:kb-height state) + :insets (safe-area/get-insets) + :curr-height (reanimated/get-shared-value (:height animations)) + :window-height (:height (rn/get-window)) + :images images + :link-previews? link-previews? + :reply reply + :edit edit} + mentions-pos + (utils/calc-suggestions-position cursor-pos max-height size state data images link-previews?)] (rn/use-effect (fn [] (if (seq suggestions) diff --git a/src/status_im2/contexts/chat/composer/style.cljs b/src/status_im2/contexts/chat/composer/style.cljs index e61a593e4a..8b5daa321e 100644 --- a/src/status_im2/contexts/chat/composer/style.cljs +++ b/src/status_im2/contexts/chat/composer/style.cljs @@ -7,6 +7,8 @@ [react-native.reanimated :as reanimated] [status-im2.contexts.chat.composer.constants :as constants])) +(def border-top-radius 20) + (defn shadow [focused? theme] (if platform/ios? @@ -27,8 +29,8 @@ (reanimated/apply-animations-to-style {:opacity container-opacity} (merge - {:border-top-left-radius 20 - :border-top-right-radius 20 + {:border-top-left-radius border-top-radius + :border-top-right-radius border-top-radius :padding-horizontal 20 :background-color (colors/theme-colors colors/white colors/neutral-95 theme) :z-index 3 @@ -55,7 +57,8 @@ [height max-height] (reanimated/apply-animations-to-style {:height height} - {:max-height max-height})) + {:max-height max-height + :z-index 1})) (defn input-view [{:keys [recording?]}] @@ -68,19 +71,17 @@ (defn input-text [{:keys [saved-emoji-kb-extra-height]} {:keys [focused? maximized?]} - {:keys [link-previews? images]} {:keys [max-height theme]}] - (merge typography/paragraph-1 - {:color (colors/theme-colors :black :white theme) - :text-align-vertical :top - :position (if @saved-emoji-kb-extra-height :relative :absolute) - :top 0 - :left 0 - :right (when (or focused? platform/ios?) 0) - :max-height (- max-height - (if link-previews? constants/links-container-height 0) - (if (seq images) constants/images-container-height 0)) - :padding-bottom (when @maximized? 0)})) + (assoc typography/paragraph-1 + :color (colors/theme-colors :black :white theme) + :text-align-vertical :top + :position (if @saved-emoji-kb-extra-height :relative :absolute) + :top 0 + :left 0 + :right (when (or focused? platform/ios?) 0) + :max-height max-height + :padding-bottom (when @maximized? 0))) + (defn background [opacity background-y window-height] (reanimated/apply-animations-to-style @@ -102,8 +103,8 @@ :left 0 :right 0 :bottom 0 - :border-top-right-radius 20 - :border-top-left-radius 20 + :border-top-right-radius border-top-radius + :border-top-left-radius border-top-radius :overflow :hidden})) (defn blur-view diff --git a/src/status_im2/contexts/chat/composer/utils.cljs b/src/status_im2/contexts/chat/composer/utils.cljs index 3bc9e5d196..5cc2adcf58 100644 --- a/src/status_im2/contexts/chat/composer/utils.cljs +++ b/src/status_im2/contexts/chat/composer/utils.cljs @@ -57,43 +57,40 @@ (defn calc-top-content-height [reply? edit?] - (let [height (if reply? constants/reply-container-height 0) - height (if edit? (+ height constants/edit-container-height) height)] - height)) + (cond-> 0 + reply? (+ constants/reply-container-height) + edit? (+ constants/edit-container-height))) (defn calc-bottom-content-height [images link-previews?] - (let [height (if (seq images) constants/images-container-height 0) - height (if link-previews? (+ height constants/links-container-height) height)] - height)) + (cond-> 0 + (seq images) (+ constants/images-container-height) + link-previews? (+ constants/links-container-height))) (defn calc-reopen-height - [text-value min-height max-height content-height saved-height images link-previews?] + [text-value min-height max-height content-height saved-height] (if (empty? @text-value) min-height - (let [bottom-content-height (calc-bottom-content-height images link-previews?) - input-height (min (+ @content-height bottom-content-height) - (reanimated/get-shared-value saved-height))] + (let [input-height (min @content-height + (reanimated/get-shared-value saved-height))] (min max-height input-height)))) (defn get-min-height - [lines images link-previews?] - (let [input-height (if (> lines 1) - constants/multiline-minimized-height - constants/input-height) - bottom-content-height (calc-bottom-content-height images link-previews?)] - (+ input-height bottom-content-height))) + [lines] + (if (> lines 1) + constants/multiline-minimized-height + constants/input-height)) (defn calc-max-height - [{:keys [reply edit]} window-height kb-height insets] - (let [margin-top (if platform/ios? (:top insets) (+ 10 (:top insets))) - max-height (- window-height - margin-top - kb-height - constants/bar-container-height - constants/actions-container-height) - max-height (- max-height (calc-top-content-height reply edit))] - max-height)) + [{:keys [reply edit images link-previews?]} window-height kb-height insets] + (let [margin-top (if platform/ios? (:top insets) (+ 10 (:top insets)))] + (- window-height + margin-top + kb-height + constants/bar-container-height + constants/actions-container-height + (calc-top-content-height reply edit) + (calc-bottom-content-height images link-previews?)))) (defn empty-input? [text images link-previews? reply? audio?] @@ -124,21 +121,12 @@ sub-text-lines-in-view (- sub-text-lines scrolled-lines)] (* sub-text-lines-in-view constants/line-height))) -(defn calc-shell-neg-y - [insets maximized? extra-height] - (let [padding 12 - neg-y (if @maximized? -50 0)] - (- (+ constants/bar-container-height - constants/actions-container-height - (:bottom insets) - padding - extra-height - neg-y)))) - (defn calc-suggestions-position [cursor-pos max-height size {:keys [maximized?]} - {:keys [insets curr-height window-height keyboard-height reply edit]}] + {:keys [insets curr-height window-height keyboard-height reply edit]} + images + link-previews?] (let [base (+ constants/composer-default-height (:bottom insets) 8) base (+ base (- curr-height constants/input-height)) base (+ base (calc-top-content-height reply edit)) @@ -152,7 +140,8 @@ (+ constants/actions-container-height (:bottom insets)) (+ constants/actions-container-height (:bottom insets) (- max-height cursor-pos) 18)) (if (< (+ base container-height) view-height) - base + (let [bottom-content-height (calc-bottom-content-height images link-previews?)] + (+ base bottom-content-height)) (+ constants/actions-container-height (:bottom insets) (- curr-height cursor-pos) 18))))) (defn init-props diff --git a/src/status_im2/contexts/chat/composer/view.cljs b/src/status_im2/contexts/chat/composer/view.cljs index 7272a42aeb..d3c6c8bce0 100644 --- a/src/status_im2/contexts/chat/composer/view.cljs +++ b/src/status_im2/contexts/chat/composer/view.cljs @@ -86,7 +86,7 @@ [sub-view/shell-button state scroll-to-bottom-fn show-floating-scroll-down-button?] [gesture/gesture-detector {:gesture - (drag-gesture/drag-gesture props state animations subscriptions dimensions keyboard-shown)} + (drag-gesture/drag-gesture props state animations dimensions keyboard-shown)} [reanimated/view {:style (style/sheet-container insets state animations theme) :on-layout #(handler/layout % state blur-height)} @@ -97,7 +97,9 @@ [edit/view state]]) [reanimated/touchable-opacity {:active-opacity 1 - :on-press (when @(:input-ref props) #(.focus ^js @(:input-ref props))) + :on-press (fn [] + (when-let [ref @(:input-ref props)] + (.focus ^js ref))) :style (style/input-container (:height animations) max-height) :accessibility-label :message-input-container} [rn/selectable-text-input @@ -113,7 +115,6 @@ :on-content-size-change #(handler/content-size-change % state animations - subscriptions dimensions (or keyboard-shown (:edit subscriptions))) @@ -122,23 +123,21 @@ :on-selection-change #(handler/selection-change % props state) :on-selection #(selection/on-selection % props state) :keyboard-appearance (quo.theme/theme-value :light :dark) - :max-height max-height :max-font-size-multiplier 1 :multiline true :placeholder (i18n/label :t/type-something) :placeholder-text-color (colors/theme-colors colors/neutral-30 colors/neutral-50) :style (style/input-text props state - subscriptions {:max-height max-height :theme theme}) :max-length constants/max-text-size - :accessibility-label :chat-message-input}]] - (when chat-screen-loaded? - [:<> - [gradients/view props state animations show-bottom-gradient?] - [link-preview/view] - [images/images-list]])] + :accessibility-label :chat-message-input}]]] + (when chat-screen-loaded? + [:<> + [gradients/view props state animations show-bottom-gradient?] + [link-preview/view] + [images/images-list]]) [:f> actions/view props state animations window-height insets scroll-to-bottom-fn subscriptions]]]]]))