Use scrollable multiline text-input in contact request form (#19383)
* tweak: augment bottom-sheet component to be aware of keyboard height * tweak: augment quo input component to allow for styling of the input, the input container, and container * tweak: augment contact request input to grow until max screen size is reached for the bottom-sheet * tweak: handle blurring the contact request input when keyboard is dismissed on android * tidy: refactor with the use-keyboard hook * tweak: use on-layout for measuring sheet max-height * tweak: remove use of input-style and flex-direction column * tidy: remove unused requires * tidy: use container-style prop * tidy: fix formatting * fix: default layout-height to window-height
This commit is contained in:
parent
3dfd9df935
commit
d24eb96c9d
|
@ -60,11 +60,11 @@
|
|||
"Custom properties that must be removed from properties map passed to InputText."
|
||||
[:type :blur? :error? :right-icon :left-icon :disabled? :small? :button
|
||||
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur
|
||||
:container-style :ref])
|
||||
:container-style :input-container-style :ref])
|
||||
|
||||
(defn- base-input
|
||||
[{:keys [blur? error? right-icon left-icon disabled? small? button
|
||||
label char-limit multiline? clearable? on-focus on-blur container-style
|
||||
label char-limit multiline? clearable? on-focus on-blur container-style input-container-style
|
||||
on-change-text on-char-limit-reach weight default-value on-clear]
|
||||
:as props}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
|
@ -119,7 +119,8 @@
|
|||
:current-chars char-count
|
||||
:char-limit char-limit
|
||||
:theme theme}])
|
||||
[rn/view {:style (style/input-container colors-by-status small? disabled?)}
|
||||
[rn/view
|
||||
{:style (merge (style/input-container colors-by-status small? disabled?) input-container-style)}
|
||||
(when-let [{:keys [icon-name]} left-icon]
|
||||
[left-accessory
|
||||
{:variant-colors variant-colors
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[react-native.hooks :as hooks]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im.common.bottom-sheet.style :as style]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def duration 450)
|
||||
|
@ -66,19 +67,23 @@
|
|||
gradient-cover? customization-color hide-handle? blur-radius]
|
||||
:or {border-radius 12}}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
{window-height :height} (rn/get-window)
|
||||
[sheet-height set-sheet-height] (rn/use-state 0)
|
||||
[layout-height set-layout-height] (rn/use-state window-height)
|
||||
handle-sheet-height (rn/use-callback (fn [e]
|
||||
(when (= sheet-height 0)
|
||||
(set-sheet-height
|
||||
(get-layout-height e))))
|
||||
[sheet-height])
|
||||
handle-layout-height (rn/use-callback (fn [e]
|
||||
(-> (get-layout-height e)
|
||||
(set-layout-height))))
|
||||
[item-height set-item-height] (rn/use-state 0)
|
||||
handle-item-height (rn/use-callback (fn [e]
|
||||
(when (= item-height 0)
|
||||
(set-item-height
|
||||
(get-layout-height e))))
|
||||
[item-height])
|
||||
{window-height :height} (rn/get-window)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
translate-y (reanimated/use-shared-value window-height)
|
||||
sheet-gesture (rn/use-memo #(get-sheet-gesture translate-y
|
||||
|
@ -96,7 +101,8 @@
|
|||
bottom (if selected-item-smaller-than-sheet?
|
||||
(+ sheet-height bottom-margin)
|
||||
(:bottom insets))
|
||||
sheet-max-height (- window-height (:top insets))
|
||||
sheet-max-height (- layout-height
|
||||
(:top insets))
|
||||
content-padding-bottom (or padding-bottom-override
|
||||
(+ (:bottom insets) bottom-margin))]
|
||||
(rn/use-effect
|
||||
|
@ -109,7 +115,9 @@
|
|||
(on-close))
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
true))
|
||||
[rn/view {:style {:flex 1}}
|
||||
[rn/view
|
||||
{:style {:flex 1}
|
||||
:on-layout handle-layout-height}
|
||||
;; backdrop
|
||||
[rn/pressable
|
||||
{:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
(def message-input-wrapper
|
||||
{:padding-vertical 8
|
||||
:flex-shrink 1
|
||||
:padding-horizontal 20})
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.contact.contact-request.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
|
@ -15,6 +16,7 @@
|
|||
customization-color customization-color
|
||||
full-name (profile.utils/displayed-name profile)
|
||||
profile-picture (profile.utils/photo profile)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
[message set-message] (rn/use-state "")
|
||||
on-message-change (rn/use-callback #(set-message %))
|
||||
on-message-submit (rn/use-callback (fn []
|
||||
|
@ -27,6 +29,14 @@
|
|||
:text (i18n/label
|
||||
:t/contact-request-was-sent)}]))
|
||||
[public-key message])]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(let [listener (.addListener rn/keyboard
|
||||
"keyboardDidHide"
|
||||
(fn [_event]
|
||||
(when (and platform/android? @input-ref)
|
||||
(.blur ^js @input-ref))))]
|
||||
#(.remove ^js listener))))
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:type :context-tag
|
||||
|
@ -39,17 +49,21 @@
|
|||
(i18n/label :t/contact-request-message-prompt)]
|
||||
[rn/view {:style style/message-input-wrapper}
|
||||
[quo/input
|
||||
{:type :text
|
||||
:multiline? true
|
||||
:char-limit constants/contact-request-message-max-length
|
||||
:max-length constants/contact-request-message-max-length
|
||||
:placeholder (i18n/label :t/type-something)
|
||||
:auto-focus true
|
||||
:accessibility-label :contact-request-message
|
||||
:label (i18n/label :t/message)
|
||||
:on-change-text on-message-change}]]
|
||||
{:type :text
|
||||
:ref #(reset! input-ref %)
|
||||
:multiline? true
|
||||
:char-limit constants/contact-request-message-max-length
|
||||
:max-length constants/contact-request-message-max-length
|
||||
:placeholder (i18n/label :t/type-something)
|
||||
:auto-focus true
|
||||
:accessibility-label :contact-request-message
|
||||
:label (i18n/label :t/message)
|
||||
:on-change-text on-message-change
|
||||
:container-style {:flex-shrink 1}
|
||||
:input-container-style {:flex-shrink 1}}]]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
{:container-style {:style {:flex 1}}
|
||||
:actions :one-action
|
||||
:button-one-props {:disabled? (string/blank? message)
|
||||
:accessibility-label :send-contact-request
|
||||
:customization-color customization-color
|
||||
|
|
|
@ -92,19 +92,21 @@
|
|||
(def bottom-sheet
|
||||
(reagent/reactify-component
|
||||
(fn []
|
||||
(let [{:keys [sheets hide?]} (rf/sub [:bottom-sheet])
|
||||
sheet (last sheets)
|
||||
{:keys [theme]} sheet
|
||||
insets (safe-area/get-insets)
|
||||
user-theme (theme/get-theme)]
|
||||
(let [{:keys [sheets hide?]} (rf/sub [:bottom-sheet])
|
||||
sheet (last sheets)
|
||||
{:keys [theme]} sheet
|
||||
insets (safe-area/get-insets)
|
||||
user-theme (theme/get-theme)
|
||||
keyboard-vertical-offset (- (max 20 (:bottom insets)))]
|
||||
^{:key (str "sheet" @reloader/cnt)}
|
||||
[theme/provider {:theme (or theme user-theme)}
|
||||
[inactive]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style {:position :relative :flex 1}
|
||||
:keyboard-vertical-offset (- (max 20 (:bottom insets)))}
|
||||
:keyboard-vertical-offset keyboard-vertical-offset}
|
||||
(when sheet
|
||||
[bottom-sheet/view {:insets insets :hide? hide?}
|
||||
[bottom-sheet/view
|
||||
{:insets insets :hide? hide?}
|
||||
sheet])]]))
|
||||
functional-compiler))
|
||||
|
||||
|
|
Loading…
Reference in New Issue