mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-13 10:16:01 +00:00
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) {
|
export function messagesListOnScroll(distanceFromListTop, chatListScrollY, callback) {
|
||||||
return function (event) {
|
return function (event) {
|
||||||
@ -12,3 +13,17 @@ export function messagesListOnScroll(distanceFromListTop, chatListScrollY, callb
|
|||||||
runOnJS(callback)(layoutHeight, newDistance);
|
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) {
|
export function interpolateNavigationViewOpacity(props) {
|
||||||
return useDerivedValue(function () {
|
return useDerivedValue(function () {
|
||||||
'worklet';
|
'worklet';
|
||||||
|
@ -32,6 +32,12 @@
|
|||||||
:height top-bar-height
|
:height top-bar-height
|
||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
|
(defn button-animation-container
|
||||||
|
[opacity-value]
|
||||||
|
(reanimated/apply-animations-to-style
|
||||||
|
{:opacity opacity-value}
|
||||||
|
{}))
|
||||||
|
|
||||||
;;;; Content
|
;;;; Content
|
||||||
|
|
||||||
(defn header-content-container
|
(defn header-content-container
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
[status-im.contexts.chat.messenger.messages.pin.banner.view :as pin.banner]
|
[status-im.contexts.chat.messenger.messages.pin.banner.view :as pin.banner]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
|
[utils.worklets.chat.messenger.messages :as messages.worklets]
|
||||||
[utils.worklets.chat.messenger.navigation :as worklets]))
|
[utils.worklets.chat.messenger.navigation :as worklets]))
|
||||||
|
|
||||||
(defn f-header-content-container
|
(defn f-header-content-container
|
||||||
@ -103,15 +104,22 @@
|
|||||||
:banner-opacity banner-opacity
|
:banner-opacity banner-opacity
|
||||||
:top-offset navigation-view-height}]]))
|
:top-offset navigation-view-height}]]))
|
||||||
|
|
||||||
(defn f-view
|
(defn view
|
||||||
[{:keys [distance-from-list-top chat-screen-layout-calculations-complete?]}]
|
[{: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])
|
(let [{:keys [chat-id chat-type] :as chat} (rf/sub [:chats/current-chat-chat-view])
|
||||||
all-loaded? (reanimated/use-shared-value false)
|
all-loaded? (reanimated/use-shared-value false)
|
||||||
all-loaded-sub (rf/sub [:chats/all-loaded? chat-id])
|
all-loaded-sub (rf/sub [:chats/all-loaded? chat-id])
|
||||||
top-insets (safe-area/get-top)
|
top-insets (safe-area/get-top)
|
||||||
top-bar-height messages.constants/top-bar-height
|
top-bar-height messages.constants/top-bar-height
|
||||||
navigation-view-height (+ top-bar-height top-insets)]
|
navigation-view-height (+ top-bar-height top-insets)
|
||||||
(reanimated/set-shared-value all-loaded? all-loaded-sub)
|
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
|
[rn/view
|
||||||
{:style (style/navigation-view navigation-view-height messages.constants/pinned-banner-height)}
|
{:style (style/navigation-view navigation-view-height messages.constants/pinned-banner-height)}
|
||||||
[:f> f-animated-background-and-pinned-banner
|
[:f> f-animated-background-and-pinned-banner
|
||||||
@ -120,27 +128,29 @@
|
|||||||
:distance-from-list-top distance-from-list-top
|
:distance-from-list-top distance-from-list-top
|
||||||
:all-loaded? all-loaded?}]
|
:all-loaded? all-loaded?}]
|
||||||
[rn/view {:style (style/header-container top-insets top-bar-height)}
|
[rn/view {:style (style/header-container top-insets top-bar-height)}
|
||||||
[quo/button
|
[reanimated/view {:style (style/button-animation-container navigation-buttons-opacity)}
|
||||||
{:icon-only? true
|
[quo/button
|
||||||
:type :grey
|
{:icon-only? true
|
||||||
:background :blur
|
:type :grey
|
||||||
:size 32
|
:background button-background
|
||||||
:accessibility-label :back-button
|
:size 32
|
||||||
:on-press #(rf/dispatch [:navigate-back])}
|
:accessibility-label :back-button
|
||||||
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]
|
:on-press #(rf/dispatch [:navigate-back])}
|
||||||
|
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]]
|
||||||
[:f> f-header-content-container
|
[:f> f-header-content-container
|
||||||
{:chat chat
|
{:chat chat
|
||||||
:distance-from-list-top distance-from-list-top
|
:distance-from-list-top distance-from-list-top
|
||||||
:all-loaded? all-loaded?
|
:all-loaded? all-loaded?
|
||||||
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
||||||
[quo/button
|
[reanimated/view {:style (style/button-animation-container navigation-buttons-opacity)}
|
||||||
{:icon-only? true
|
[quo/button
|
||||||
:type :grey
|
{:icon-only? true
|
||||||
:background :blur
|
:type :grey
|
||||||
:size 32
|
:background button-background
|
||||||
:accessibility-label :options-button
|
:size 32
|
||||||
:on-press (fn []
|
:accessibility-label :options-button
|
||||||
(rf/dispatch [:dismiss-keyboard])
|
:on-press (fn []
|
||||||
(rf/dispatch [:show-bottom-sheet
|
(rf/dispatch [:dismiss-keyboard])
|
||||||
{:content (fn [] [actions/chat-actions chat true])}]))}
|
(rf/dispatch [:show-bottom-sheet
|
||||||
:i/options]]]))
|
{:content (fn [] [actions/chat-actions chat true])}]))}
|
||||||
|
:i/options]]]]))
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
[rn/keyboard-avoiding-view
|
[rn/keyboard-avoiding-view
|
||||||
{:style style/keyboard-avoiding-container
|
{:style style/keyboard-avoiding-container
|
||||||
:keyboard-vertical-offset (- (:bottom insets))}
|
:keyboard-vertical-offset (- (:bottom insets))}
|
||||||
[:f> messages.navigation/f-view
|
[messages.navigation/view
|
||||||
{:distance-from-list-top distance-from-list-top
|
{:distance-from-list-top distance-from-list-top
|
||||||
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
||||||
[:f> list.view/f-messages-list-content
|
[:f> list.view/f-messages-list-content
|
||||||
|
@ -5,3 +5,9 @@
|
|||||||
(defn messages-list-on-scroll
|
(defn messages-list-on-scroll
|
||||||
[distance-from-list-top chat-list-scroll-y callback]
|
[distance-from-list-top chat-list-scroll-y callback]
|
||||||
(.messagesListOnScroll ^js worklets 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
|
top-bar-height
|
||||||
start-position))
|
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
|
(defn interpolate-navigation-view-opacity
|
||||||
[props]
|
[props]
|
||||||
(.interpolateNavigationViewOpacity ^js worklets (clj->js props)))
|
(.interpolateNavigationViewOpacity ^js worklets (clj->js props)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user