1 | import { useNavigation, useRoute } from '@react-navigation/core';
|
2 | import * as React from 'react';
|
3 |
|
4 | function getScrollableNode(ref) {
|
5 | if (ref.current == null) {
|
6 | return null;
|
7 | }
|
8 |
|
9 | if ('scrollToTop' in ref.current || 'scrollTo' in ref.current || 'scrollToOffset' in ref.current || 'scrollResponderScrollTo' in ref.current) {
|
10 |
|
11 | return ref.current;
|
12 | } else if ('getScrollResponder' in ref.current) {
|
13 |
|
14 |
|
15 | return ref.current.getScrollResponder();
|
16 | } else if ('getNode' in ref.current) {
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | return ref.current.getNode();
|
22 | } else {
|
23 | return ref.current;
|
24 | }
|
25 | }
|
26 |
|
27 | export default function useScrollToTop(ref) {
|
28 | const navigation = useNavigation();
|
29 | const route = useRoute();
|
30 | React.useEffect(() => {
|
31 | let current = navigation;
|
32 |
|
33 |
|
34 | while (current && current.getState().type !== 'tab') {
|
35 | current = current.getParent();
|
36 | }
|
37 |
|
38 | if (!current) {
|
39 | return;
|
40 | }
|
41 |
|
42 | const unsubscribe = current.addListener(
|
43 |
|
44 |
|
45 | 'tabPress', e => {
|
46 |
|
47 | const isFocused = navigation.isFocused();
|
48 |
|
49 |
|
50 | const isFirst = navigation === current || navigation.getState().routes[0].key === route.key;
|
51 |
|
52 |
|
53 | requestAnimationFrame(() => {
|
54 | const scrollable = getScrollableNode(ref);
|
55 |
|
56 | if (isFocused && isFirst && scrollable && !e.defaultPrevented) {
|
57 | if ('scrollToTop' in scrollable) {
|
58 | scrollable.scrollToTop();
|
59 | } else if ('scrollTo' in scrollable) {
|
60 | scrollable.scrollTo({
|
61 | y: 0,
|
62 | animated: true
|
63 | });
|
64 | } else if ('scrollToOffset' in scrollable) {
|
65 | scrollable.scrollToOffset({
|
66 | offset: 0,
|
67 | animated: true
|
68 | });
|
69 | } else if ('scrollResponderScrollTo' in scrollable) {
|
70 | scrollable.scrollResponderScrollTo({
|
71 | y: 0,
|
72 | animated: true
|
73 | });
|
74 | }
|
75 | }
|
76 | });
|
77 | });
|
78 | return unsubscribe;
|
79 | }, [navigation, ref, route.key]);
|
80 | }
|
81 |
|
\ | No newline at end of file |