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:
Lungu Cristian 2024-03-18 12:05:36 +02:00 committed by GitHub
parent 10c6bf7156
commit 02c7460a24
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 72 additions and 24 deletions

View File

@ -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
}

View File

@ -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';

View File

@ -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

View File

@ -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)}
[reanimated/view {:style (style/button-animation-container navigation-buttons-opacity)}
[quo/button
{:icon-only? true
:type :grey
:background :blur
: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)]
(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?}]
[reanimated/view {:style (style/button-animation-container navigation-buttons-opacity)}
[quo/button
{:icon-only? true
:type :grey
:background :blur
: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]]]))
:i/options]]]]))

View File

@ -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

View File

@ -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))

View File

@ -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)))