Fix chat navigation buttons when scrolling to top (#19097)
* fix: change nav buttons to :photo when scrolled to top Signed-off-by: Cristian Lungu <lungucristian95@gmail.com> * fix: renamed to use-messages-scrolled-to-threshold Signed-off-by: Cristian Lungu <lungucristian95@gmail.com> * fix: nav buttons are shown without flicker on mount Signed-off-by: Cristian Lungu <lungucristian95@gmail.com> --------- Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>
This commit is contained in:
parent
10c6bf7156
commit
02c7460a24
|
@ -1,4 +1,5 @@
|
|||
import { withTiming, runOnJS } from 'react-native-reanimated';
|
||||
import { useAnimatedReaction, withTiming, runOnJS } from 'react-native-reanimated';
|
||||
import { useState } from "react"
|
||||
|
||||
export function messagesListOnScroll(distanceFromListTop, chatListScrollY, callback) {
|
||||
return function (event) {
|
||||
|
@ -12,3 +13,17 @@ export function messagesListOnScroll(distanceFromListTop, chatListScrollY, callb
|
|||
runOnJS(callback)(layoutHeight, newDistance);
|
||||
};
|
||||
}
|
||||
|
||||
export function useMessagesScrolledToThreshold(distanceFromListTop, threshold) {
|
||||
const [scrolledToThreshold, setScrolledToThreshold] = useState(false)
|
||||
|
||||
useAnimatedReaction(function () {
|
||||
return distanceFromListTop.value <= threshold;
|
||||
}, function (current) {
|
||||
if(current !== scrolledToThreshold) {
|
||||
runOnJS(setScrolledToThreshold)(current)
|
||||
}
|
||||
}, [scrolledToThreshold])
|
||||
|
||||
return scrolledToThreshold
|
||||
}
|
||||
|
|
|
@ -19,6 +19,13 @@ export function navigationHeaderPosition(distanceFromListTop, isAllLoaded, topBa
|
|||
});
|
||||
}
|
||||
|
||||
export function navigationButtonsCompleteOpacity(isCalculationComplete) {
|
||||
return useDerivedValue(function () {
|
||||
'worklet'
|
||||
return isCalculationComplete.value ? withTiming(1) : 0
|
||||
})
|
||||
}
|
||||
|
||||
export function interpolateNavigationViewOpacity(props) {
|
||||
return useDerivedValue(function () {
|
||||
'worklet';
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
:height top-bar-height
|
||||
:align-items :center})
|
||||
|
||||
(defn button-animation-container
|
||||
[opacity-value]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:opacity opacity-value}
|
||||
{}))
|
||||
|
||||
;;;; Content
|
||||
|
||||
(defn header-content-container
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[status-im.contexts.chat.messenger.messages.pin.banner.view :as pin.banner]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.worklets.chat.messenger.messages :as messages.worklets]
|
||||
[utils.worklets.chat.messenger.navigation :as worklets]))
|
||||
|
||||
(defn f-header-content-container
|
||||
|
@ -103,15 +104,22 @@
|
|||
:banner-opacity banner-opacity
|
||||
:top-offset navigation-view-height}]]))
|
||||
|
||||
(defn f-view
|
||||
(defn view
|
||||
[{:keys [distance-from-list-top chat-screen-layout-calculations-complete?]}]
|
||||
(let [{:keys [chat-id chat-type] :as chat} (rf/sub [:chats/current-chat-chat-view])
|
||||
all-loaded? (reanimated/use-shared-value false)
|
||||
all-loaded-sub (rf/sub [:chats/all-loaded? chat-id])
|
||||
top-insets (safe-area/get-top)
|
||||
top-bar-height messages.constants/top-bar-height
|
||||
navigation-view-height (+ top-bar-height top-insets)]
|
||||
(reanimated/set-shared-value all-loaded? all-loaded-sub)
|
||||
navigation-view-height (+ top-bar-height top-insets)
|
||||
navigation-buttons-opacity (worklets/navigation-buttons-complete-opacity
|
||||
chat-screen-layout-calculations-complete?)
|
||||
reached-threshold? (messages.worklets/use-messages-scrolled-to-threshold
|
||||
distance-from-list-top
|
||||
top-bar-height)
|
||||
button-background (if reached-threshold? :photo :blur)]
|
||||
(rn/use-effect (fn [] (reanimated/set-shared-value all-loaded? all-loaded-sub))
|
||||
[all-loaded-sub])
|
||||
[rn/view
|
||||
{:style (style/navigation-view navigation-view-height messages.constants/pinned-banner-height)}
|
||||
[:f> f-animated-background-and-pinned-banner
|
||||
|
@ -120,27 +128,29 @@
|
|||
:distance-from-list-top distance-from-list-top
|
||||
:all-loaded? all-loaded?}]
|
||||
[rn/view {:style (style/header-container top-insets top-bar-height)}
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background :blur
|
||||
:size 32
|
||||
:accessibility-label :back-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]
|
||||
[reanimated/view {:style (style/button-animation-container navigation-buttons-opacity)}
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background button-background
|
||||
:size 32
|
||||
:accessibility-label :back-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]]
|
||||
[:f> f-header-content-container
|
||||
{:chat chat
|
||||
:distance-from-list-top distance-from-list-top
|
||||
:all-loaded? all-loaded?
|
||||
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background :blur
|
||||
:size 32
|
||||
:accessibility-label :options-button
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [actions/chat-actions chat true])}]))}
|
||||
:i/options]]]))
|
||||
[reanimated/view {:style (style/button-animation-container navigation-buttons-opacity)}
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background button-background
|
||||
:size 32
|
||||
:accessibility-label :options-button
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [actions/chat-actions chat true])}]))}
|
||||
:i/options]]]]))
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
[rn/keyboard-avoiding-view
|
||||
{:style style/keyboard-avoiding-container
|
||||
:keyboard-vertical-offset (- (:bottom insets))}
|
||||
[:f> messages.navigation/f-view
|
||||
[messages.navigation/view
|
||||
{:distance-from-list-top distance-from-list-top
|
||||
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
||||
[:f> list.view/f-messages-list-content
|
||||
|
|
|
@ -5,3 +5,9 @@
|
|||
(defn messages-list-on-scroll
|
||||
[distance-from-list-top chat-list-scroll-y callback]
|
||||
(.messagesListOnScroll ^js worklets distance-from-list-top chat-list-scroll-y callback))
|
||||
|
||||
(defn use-messages-scrolled-to-threshold
|
||||
[distance-from-list-top threshold]
|
||||
(.useMessagesScrolledToThreshold ^js worklets
|
||||
distance-from-list-top
|
||||
threshold))
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
top-bar-height
|
||||
start-position))
|
||||
|
||||
(defn navigation-buttons-complete-opacity
|
||||
[chat-screen-layout-calculations-complete?]
|
||||
(.navigationButtonsCompleteOpacity ^js worklets chat-screen-layout-calculations-complete?))
|
||||
|
||||
(defn interpolate-navigation-view-opacity
|
||||
[props]
|
||||
(.interpolateNavigationViewOpacity ^js worklets (clj->js props)))
|
||||
|
|
Loading…
Reference in New Issue