From a336e8181c7ec470144772dbdbae3fd506a80f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=27fvlvte=27=20Fa=C5=82at?= Date: Wed, 22 Nov 2023 14:21:13 +0100 Subject: [PATCH 1/4] Migrated FlatList to typescript. --- src/components/FlatList/index.android.js | 78 ------------------- src/components/FlatList/index.android.tsx | 64 +++++++++++++++ .../FlatList/{index.js => index.ts} | 0 3 files changed, 64 insertions(+), 78 deletions(-) delete mode 100644 src/components/FlatList/index.android.js create mode 100644 src/components/FlatList/index.android.tsx rename src/components/FlatList/{index.js => index.ts} (100%) diff --git a/src/components/FlatList/index.android.js b/src/components/FlatList/index.android.js deleted file mode 100644 index fdb3a24667aa..000000000000 --- a/src/components/FlatList/index.android.js +++ /dev/null @@ -1,78 +0,0 @@ -import {useFocusEffect} from '@react-navigation/native'; -import PropTypes from 'prop-types'; -import React, {forwardRef, useCallback, useState} from 'react'; -import {FlatList} from 'react-native'; - -const propTypes = { - /** Same as for FlatList */ - onScroll: PropTypes.func, - - /** Same as for FlatList */ - onLayout: PropTypes.func, - - /** Same as for FlatList */ - // eslint-disable-next-line react/forbid-prop-types - maintainVisibleContentPosition: PropTypes.object, - - /** Passed via forwardRef so we can access the FlatList ref */ - innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({current: PropTypes.instanceOf(FlatList)})]).isRequired, -}; - -const defaultProps = { - /** Same as for FlatList */ - onScroll: undefined, - - /** Same as for FlatList */ - onLayout: undefined, - - /** Same as for FlatList */ - maintainVisibleContentPosition: undefined, -}; - -// FlatList wrapped with the freeze component will lose its scroll state when frozen (only for Android). -// CustomFlatList saves the offset and use it for scrollToOffset() when unfrozen. -function CustomFlatList(props) { - const [scrollPosition, setScrollPosition] = useState({}); - - const onScreenFocus = useCallback(() => { - if (!props.innerRef.current || !scrollPosition.offset) { - return; - } - if (props.innerRef.current && scrollPosition.offset) { - props.innerRef.current.scrollToOffset({offset: scrollPosition.offset, animated: false}); - } - }, [scrollPosition.offset, props.innerRef]); - - useFocusEffect( - useCallback(() => { - onScreenFocus(); - }, [onScreenFocus]), - ); - - return ( - props.onScroll(event)} - onMomentumScrollEnd={(event) => { - setScrollPosition({offset: event.nativeEvent.contentOffset.y}); - }} - ref={props.innerRef} - /> - ); -} - -CustomFlatList.propTypes = propTypes; -CustomFlatList.defaultProps = defaultProps; - -const CustomFlatListWithRef = forwardRef((props, ref) => ( - -)); - -CustomFlatListWithRef.displayName = 'CustomFlatListWithRef'; - -export default CustomFlatListWithRef; diff --git a/src/components/FlatList/index.android.tsx b/src/components/FlatList/index.android.tsx new file mode 100644 index 000000000000..9a735413426b --- /dev/null +++ b/src/components/FlatList/index.android.tsx @@ -0,0 +1,64 @@ +import {useFocusEffect} from '@react-navigation/native'; +import React, {ForwardedRef, forwardRef, useCallback, useState} from 'react'; +import {FlatList, FlatListProps} from 'react-native'; + +type CustomFlatListProps = { + /** Same as for FlatList */ + onScroll?: (...args: unknown[]) => unknown; + + /** Same as for FlatList */ + onLayout?: () => (...args: unknown[]) => unknown; + + /** Passed via forwardRef so we can access the FlatList ref */ + innerRef: ForwardedRef; +} & FlatListProps; + +// FlatList wrapped with the freeze component will lose its scroll state when frozen (only for Android). +// CustomFlatList saves the offset and use it for scrollToOffset() when unfrozen. +function CustomFlatList(props: CustomFlatListProps) { + const [scrollPosition, setScrollPosition] = useState<{offset?: number}>({}); + + const {innerRef} = props; + + const onScreenFocus = useCallback(() => { + if (typeof innerRef === 'function') { + return; + } + if (!innerRef?.current || !scrollPosition.offset) { + return; + } + if (innerRef.current && scrollPosition.offset) { + innerRef.current.scrollToOffset({offset: scrollPosition.offset, animated: false}); + } + }, [scrollPosition.offset, props.innerRef]); + + useFocusEffect( + useCallback(() => { + onScreenFocus(); + }, [onScreenFocus]), + ); + + return ( + props.onScroll?.(event)} + onMomentumScrollEnd={(event) => { + setScrollPosition({offset: event.nativeEvent.contentOffset.y}); + }} + ref={props.innerRef} + /> + ); +} + +CustomFlatList.displayName = 'CustomFlatListWithRef'; + +const CustomFlatListWithRef = forwardRef((props: CustomFlatListProps, ref: ForwardedRef) => ( + +)); + +export default CustomFlatListWithRef; diff --git a/src/components/FlatList/index.js b/src/components/FlatList/index.ts similarity index 100% rename from src/components/FlatList/index.js rename to src/components/FlatList/index.ts From 37892c6fa6fdfc282fdd6c8cc52894693bfc1f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=27fvlvte=27=20Fa=C5=82at?= Date: Wed, 22 Nov 2023 14:47:32 +0100 Subject: [PATCH 2/4] Linter solved. --- src/components/FlatList/index.android.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/FlatList/index.android.tsx b/src/components/FlatList/index.android.tsx index 9a735413426b..ff8dfb529a74 100644 --- a/src/components/FlatList/index.android.tsx +++ b/src/components/FlatList/index.android.tsx @@ -30,7 +30,7 @@ function CustomFlatList(props: CustomFlatListProps) { if (innerRef.current && scrollPosition.offset) { innerRef.current.scrollToOffset({offset: scrollPosition.offset, animated: false}); } - }, [scrollPosition.offset, props.innerRef]); + }, [scrollPosition.offset, innerRef]); useFocusEffect( useCallback(() => { From 77e3b8a202e73cb55ab15ee61147eee7140abdab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=27fvlvte=27=20Fa=C5=82at?= Date: Mon, 27 Nov 2023 10:40:17 +0100 Subject: [PATCH 3/4] Prettier fix. --- src/components/FlatList/index.android.tsx | 42 ++++++----------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/src/components/FlatList/index.android.tsx b/src/components/FlatList/index.android.tsx index ff8dfb529a74..a230fe28f76a 100644 --- a/src/components/FlatList/index.android.tsx +++ b/src/components/FlatList/index.android.tsx @@ -2,35 +2,24 @@ import {useFocusEffect} from '@react-navigation/native'; import React, {ForwardedRef, forwardRef, useCallback, useState} from 'react'; import {FlatList, FlatListProps} from 'react-native'; -type CustomFlatListProps = { - /** Same as for FlatList */ - onScroll?: (...args: unknown[]) => unknown; - - /** Same as for FlatList */ - onLayout?: () => (...args: unknown[]) => unknown; - - /** Passed via forwardRef so we can access the FlatList ref */ - innerRef: ForwardedRef; -} & FlatListProps; +type ScrollPosition = {offset?: number}; // FlatList wrapped with the freeze component will lose its scroll state when frozen (only for Android). // CustomFlatList saves the offset and use it for scrollToOffset() when unfrozen. -function CustomFlatList(props: CustomFlatListProps) { - const [scrollPosition, setScrollPosition] = useState<{offset?: number}>({}); - - const {innerRef} = props; +function CustomFlatList(props: FlatListProps, ref: ForwardedRef) { + const [scrollPosition, setScrollPosition] = useState({}); const onScreenFocus = useCallback(() => { - if (typeof innerRef === 'function') { + if (typeof ref === 'function') { return; } - if (!innerRef?.current || !scrollPosition.offset) { + if (!ref?.current || !scrollPosition.offset) { return; } - if (innerRef.current && scrollPosition.offset) { - innerRef.current.scrollToOffset({offset: scrollPosition.offset, animated: false}); + if (ref.current && scrollPosition.offset) { + ref.current.scrollToOffset({offset: scrollPosition.offset, animated: false}); } - }, [scrollPosition.offset, innerRef]); + }, [scrollPosition.offset, ref]); useFocusEffect( useCallback(() => { @@ -39,26 +28,17 @@ function CustomFlatList(props: CustomFlatListProps) { ); return ( - // eslint-disable-next-line react/jsx-props-no-spreading {...props} onScroll={(event) => props.onScroll?.(event)} onMomentumScrollEnd={(event) => { setScrollPosition({offset: event.nativeEvent.contentOffset.y}); }} - ref={props.innerRef} + ref={ref} /> ); } CustomFlatList.displayName = 'CustomFlatListWithRef'; - -const CustomFlatListWithRef = forwardRef((props: CustomFlatListProps, ref: ForwardedRef) => ( - -)); - -export default CustomFlatListWithRef; +export default forwardRef(CustomFlatList); From 50c02ebdb20a589e64b0e33e13a7dfb2f70e2904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=27fvlvte=27=20Fa=C5=82at?= Date: Mon, 4 Dec 2023 09:47:51 +0100 Subject: [PATCH 4/4] Applied changes from main. --- src/components/FlatList/index.android.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/FlatList/index.android.tsx b/src/components/FlatList/index.android.tsx index a230fe28f76a..84345f6e0ed4 100644 --- a/src/components/FlatList/index.android.tsx +++ b/src/components/FlatList/index.android.tsx @@ -1,25 +1,24 @@ import {useFocusEffect} from '@react-navigation/native'; -import React, {ForwardedRef, forwardRef, useCallback, useState} from 'react'; +import React, {ForwardedRef, forwardRef, useCallback, useContext} from 'react'; import {FlatList, FlatListProps} from 'react-native'; - -type ScrollPosition = {offset?: number}; +import {ActionListContext} from '@pages/home/ReportScreenContext'; // FlatList wrapped with the freeze component will lose its scroll state when frozen (only for Android). // CustomFlatList saves the offset and use it for scrollToOffset() when unfrozen. function CustomFlatList(props: FlatListProps, ref: ForwardedRef) { - const [scrollPosition, setScrollPosition] = useState({}); + const {scrollPosition, setScrollPosition} = useContext(ActionListContext); const onScreenFocus = useCallback(() => { if (typeof ref === 'function') { return; } - if (!ref?.current || !scrollPosition.offset) { + if (!ref?.current || !scrollPosition?.offset) { return; } if (ref.current && scrollPosition.offset) { ref.current.scrollToOffset({offset: scrollPosition.offset, animated: false}); } - }, [scrollPosition.offset, ref]); + }, [scrollPosition?.offset, ref]); useFocusEffect( useCallback(() => {