Fix chat text input animation lags
Remove picker panel from input Clean pan state Fixes #11031 Do not use pan state on android iOs panel switching do not change height Revert "Remove picker panel from input" This reverts commit 0ab2c1544b70f8c491424376268f572696bd284a. Change reactions space keeper method Audio Do not use accessory view on Android Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
parent
eeff44eea7
commit
7bb7b48db7
|
@ -11,8 +11,10 @@
|
|||
[quo.components.safe-area :refer [use-safe-area]]))
|
||||
|
||||
(def tabbar-height tabs.styles/minimized-tabs-height)
|
||||
(def duration 250)
|
||||
|
||||
(defn create-pan-responder [y pan-active]
|
||||
(when-not platform/android?
|
||||
(js->clj (.-panHandlers
|
||||
^js (.create
|
||||
^js rn/pan-responder
|
||||
|
@ -21,13 +23,17 @@
|
|||
:onPanResponderMove (fn [_ ^js state]
|
||||
(animated/set-value y (.-moveY state)))
|
||||
:onPanResponderRelease (fn []
|
||||
(animated/set-value pan-active 0)
|
||||
(js/setTimeout
|
||||
#(animated/set-value y 0)
|
||||
100))
|
||||
:onPanResponderEnd (fn []
|
||||
(animated/set-value pan-active 0))}))))
|
||||
:onPanResponderTerminate (fn []
|
||||
(animated/set-value pan-active 0)
|
||||
(js/setTimeout
|
||||
#(animated/set-value y 0)
|
||||
100))})))))
|
||||
|
||||
(def view
|
||||
(def ios-view
|
||||
(reagent/adapt-react-class
|
||||
(react/memo
|
||||
(fn [props]
|
||||
|
@ -39,7 +45,6 @@
|
|||
children :children} (bean/bean props)
|
||||
{keyboard-height :height
|
||||
keyboard-max-height :max-height
|
||||
duration :duration
|
||||
keyboard-end-position :end-position} (use-keyboard-dimension)
|
||||
{:keys [bottom]} (use-safe-area)
|
||||
{on-layout :on-layout
|
||||
|
@ -64,15 +69,13 @@
|
|||
:easing (:keyboard animated/easings)})
|
||||
0
|
||||
panel-on-screen))
|
||||
[duration panel-on-screen])
|
||||
[panel-on-screen])
|
||||
delta-y (animated/clamp (animated/add drag-diff animated-y) max-delta 0)
|
||||
on-update (react/callback
|
||||
(fn []
|
||||
on-update (fn []
|
||||
(when on-update-inset
|
||||
(on-update-inset (+ bar-height panel-height))))
|
||||
[panel-height bar-height])
|
||||
children (react/get-children children)]
|
||||
(react/effect! on-update)
|
||||
(react/effect! on-update [panel-height bar-height])
|
||||
(animated/code!
|
||||
(fn []
|
||||
(when has-panel
|
||||
|
@ -86,12 +89,7 @@
|
|||
(animated/delay
|
||||
(animated/set anim-visible (if visible 1 0))
|
||||
(if visible delay 0)))
|
||||
[visible keyboard-max-height duration])
|
||||
(rn/use-back-handler
|
||||
(fn []
|
||||
(when visible
|
||||
(on-close))
|
||||
visible))
|
||||
[visible keyboard-max-height delay])
|
||||
(reagent/as-element
|
||||
[animated/view {:style {:position :absolute
|
||||
:left 0
|
||||
|
@ -104,3 +102,44 @@
|
|||
[rn/view {:style {:flex 1
|
||||
:height (when (pos? panel-height) panel-height)}}
|
||||
(second children)]]))))))
|
||||
|
||||
(def android-view
|
||||
(reagent/adapt-react-class
|
||||
(react/memo
|
||||
(fn [props]
|
||||
(let [{on-update-inset :onUpdateInset
|
||||
on-close :onClose
|
||||
has-panel :hasPanel
|
||||
children :children} (bean/bean props)
|
||||
{keyboard-max-height :max-height} (use-keyboard-dimension)
|
||||
{:keys [bottom]} (use-safe-area)
|
||||
{on-layout :on-layout
|
||||
bar-height :height} (rn/use-layout)
|
||||
|
||||
visible has-panel
|
||||
panel-on-screen (* -1 (- keyboard-max-height bottom tabbar-height))
|
||||
max-delta (min 0 (if has-panel panel-on-screen 0))
|
||||
panel-height (* -1 max-delta)
|
||||
on-update (fn []
|
||||
(when on-update-inset
|
||||
(on-update-inset (+ bar-height panel-height))))
|
||||
children (react/get-children children)]
|
||||
(react/effect! on-update [panel-height bar-height])
|
||||
(rn/use-back-handler
|
||||
(fn []
|
||||
(when visible
|
||||
(on-close))
|
||||
visible))
|
||||
(reagent/as-element
|
||||
[animated/view {:style {:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:background-color (:ui-background @colors/theme)}}
|
||||
[rn/view {:on-layout on-layout}
|
||||
(first children)]
|
||||
[rn/view {:style {:flex 1
|
||||
:height (when (pos? panel-height) panel-height)}}
|
||||
(second children)]]))))))
|
||||
|
||||
(def view (if platform/android? android-view ios-view))
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
[clojure.string :as string]))
|
||||
|
||||
(def panel->icons {:extensions :main-icons/commands
|
||||
:images :main-icons/photo
|
||||
:audio :main-icons/speech})
|
||||
:images :main-icons/photo})
|
||||
|
||||
(defn touchable-icon [{:keys [panel active set-active accessibility-label]}]
|
||||
[pressable/pressable {:type :scale
|
||||
|
@ -38,6 +37,8 @@
|
|||
[icons/icon :main-icons/keyboard (styles/icon false)]
|
||||
[icons/icon :main-icons/stickers (styles/icon false)])]])
|
||||
|
||||
;; TODO(Ferossgp): Move this into audio panel.
|
||||
;; Instead of not changing panel we can show a placeholder with no permission
|
||||
(defn- request-record-audio-permission [set-active panel]
|
||||
(re-frame/dispatch
|
||||
[:request-permissions
|
||||
|
@ -58,9 +59,9 @@
|
|||
(input-focus)
|
||||
(request-record-audio-permission set-active panel))}
|
||||
[rn/view {:style (styles/in-input-touchable-icon)}
|
||||
[icons/icon
|
||||
(panel->icons panel)
|
||||
(styles/icon (= active panel))]]])
|
||||
(if (= active panel)
|
||||
[icons/icon :main-icons/keyboard (styles/icon false)]
|
||||
[icons/icon :main-icons/speech (styles/icon false)])]])
|
||||
|
||||
(defn send-button [{:keys [on-send-press]}]
|
||||
[pressable/pressable {:type :scale
|
||||
|
|
|
@ -104,7 +104,8 @@
|
|||
|
||||
(defn in-input-buttons []
|
||||
{:flex-direction :row
|
||||
:height 34})
|
||||
:height 34
|
||||
:overflow :hidden})
|
||||
|
||||
(defn send-icon-color []
|
||||
colors/white)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.i18n :as i18n]
|
||||
[quo.platform :as platform]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
@ -341,17 +340,14 @@
|
|||
[message-content-wrapper message
|
||||
[unknown-content-type message]])
|
||||
|
||||
(defn chat-message [message set-active-panel]
|
||||
(defn chat-message [message space-keeper]
|
||||
[reactions/with-reaction-picker
|
||||
{:message message
|
||||
:reactions @(re-frame/subscribe [:chats/message-reactions (:message-id message)])
|
||||
:picker-on-open (fn []
|
||||
;; NOTE(Ferossgp): Because of soft-input adjustResize there are some problems on android
|
||||
(when (and platform/ios? (pos? @(re-frame/subscribe [:keyboard-height])))
|
||||
(set-active-panel :keep-space)))
|
||||
(space-keeper true))
|
||||
:picker-on-close (fn []
|
||||
(when platform/ios?
|
||||
(set-active-panel nil)))
|
||||
(space-keeper false))
|
||||
:send-emoji (fn [{:keys [emoji-id]}]
|
||||
(re-frame/dispatch [::models.reactions/send-emoji-reaction
|
||||
{:message-id (:message-id message)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[status-im.ui.screens.chat.sheets :as sheets]
|
||||
[quo.animated :as animated]
|
||||
[quo.react-native :as rn]
|
||||
[quo.platform :as platform]
|
||||
[status-im.ui.screens.chat.audio-message.views :as audio-message]
|
||||
[quo.react :as quo.react]
|
||||
[status-im.ui.screens.chat.message.message :as message]
|
||||
|
@ -27,8 +28,7 @@
|
|||
[status-im.ui.components.invite.chat :as invite.chat]
|
||||
[status-im.ui.screens.chat.components.accessory :as accessory]
|
||||
[status-im.ui.screens.chat.components.input :as components]
|
||||
[status-im.ui.screens.chat.message.datemark :as message-datemark])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
[status-im.ui.screens.chat.message.datemark :as message-datemark]))
|
||||
|
||||
(defn topbar [current-chat]
|
||||
[topbar/topbar
|
||||
|
@ -137,14 +137,16 @@
|
|||
first-not-visible)))))
|
||||
(debounce/debounce-and-dispatch [:chat.ui/message-visibility-changed e] 5000))
|
||||
|
||||
(defview messages-view
|
||||
[{:keys [group-chat chat-id public?] :as chat} bottom-space pan-handler set-active-panel]
|
||||
(letsubs [messages [:chats/current-chat-messages-stream]
|
||||
no-messages? [:chats/current-chat-no-messages?]
|
||||
current-public-key [:multiaccount/public-key]]
|
||||
(defn messages-view
|
||||
[{:keys [chat bottom-space pan-responder space-keeper]}]
|
||||
(let [{:keys [group-chat chat-id public?]} chat
|
||||
|
||||
messages @(re-frame/subscribe [:chats/current-chat-messages-stream])
|
||||
no-messages? @(re-frame/subscribe [:chats/current-chat-no-messages?])
|
||||
current-public-key @(re-frame/subscribe [:multiaccount/public-key])]
|
||||
[list/flat-list
|
||||
(merge
|
||||
pan-handler
|
||||
pan-responder
|
||||
{:key-fn #(or (:message-id %) (:value %))
|
||||
:ref #(reset! messages-list-ref %)
|
||||
:header (when (and group-chat (not public?))
|
||||
|
@ -167,13 +169,13 @@
|
|||
:group-chat group-chat
|
||||
:public? public?
|
||||
:current-public-key current-public-key)
|
||||
set-active-panel])))
|
||||
space-keeper])))
|
||||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:on-end-reached #(re-frame/dispatch [:chat.ui/load-more-messages])
|
||||
:on-scroll-to-index-failed #() ;;don't remove this
|
||||
:content-container-style {:padding-top (+ @bottom-space 16)
|
||||
:content-container-style {:padding-top (+ bottom-space 16)
|
||||
:padding-bottom 16}
|
||||
:scrollIndicatorInsets {:top @bottom-space}
|
||||
:scrollIndicatorInsets {:top bottom-space}
|
||||
:keyboardDismissMode "interactive"
|
||||
:keyboard-should-persist-taps :handled})]))
|
||||
|
||||
|
@ -191,19 +193,33 @@
|
|||
|
||||
(defn chat []
|
||||
(let [bottom-space (reagent/atom 0)
|
||||
panel-space (reagent/atom 0)
|
||||
active-panel (reagent/atom nil)
|
||||
position-y (animated/value 0)
|
||||
pan-state (animated/value 0)
|
||||
text-input-ref (quo.react/create-ref)
|
||||
on-update (partial reset! bottom-space)
|
||||
on-update (partial reset! panel-space)
|
||||
pan-responder (accessory/create-pan-responder position-y pan-state)
|
||||
space-keeper (fn [state]
|
||||
;; NOTE: Only iOs now because we use soft input resize screen on android
|
||||
(when platform/ios?
|
||||
(cond
|
||||
(and state
|
||||
(< @bottom-space @panel-space)
|
||||
(not @active-panel))
|
||||
(reset! bottom-space @panel-space)
|
||||
|
||||
(and (not state)
|
||||
(< @panel-space @bottom-space))
|
||||
(do
|
||||
(some-> ^js (quo.react/current-ref text-input-ref) .focus)
|
||||
(reset! panel-space @bottom-space)
|
||||
(reset! bottom-space 0)))))
|
||||
set-active-panel (fn [panel]
|
||||
(rn/configure-next
|
||||
(:ease-opacity-200 rn/custom-animations))
|
||||
(when (and (not panel)
|
||||
(= :keep-space @active-panel))
|
||||
(some-> ^js (quo.react/current-ref text-input-ref) .focus))
|
||||
(reset! active-panel panel)
|
||||
(reagent/flush)
|
||||
(when panel
|
||||
(js/setTimeout #(react/dismiss-keyboard!) 100)))]
|
||||
(fn []
|
||||
|
@ -215,7 +231,10 @@
|
|||
[react/view {:style {:flex 1}}
|
||||
(when-not group-chat
|
||||
[add-contact-bar chat-id])
|
||||
[messages-view current-chat bottom-space pan-responder set-active-panel]]]
|
||||
[messages-view {:chat current-chat
|
||||
:bottom-space (max @bottom-space @panel-space)
|
||||
:pan-responder pan-responder
|
||||
:space-keeper space-keeper}]]]
|
||||
(when show-input?
|
||||
[accessory/view {:y position-y
|
||||
:pan-state pan-state
|
||||
|
|
Loading…
Reference in New Issue