From 8406a57143708cbfc265e9ff96c1a32bbaf9a1b3 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Fri, 6 Jan 2023 01:41:46 +0100 Subject: [PATCH] Try out FlashList --- ios/Podfile.lock | 10 +- package.json | 1 + src/components/Timeline/Refresh.tsx | 5 +- src/components/Timeline/index.tsx | 16 +-- .../Compose/Root/Footer/Attachments.tsx | 8 +- src/screens/Tabs/Me/FollowedTags.tsx | 6 +- src/screens/Tabs/Me/List/Accounts.tsx | 5 +- src/screens/Tabs/Me/SettingsLanguage.tsx | 5 +- .../Tabs/Shared/Account/Attachments.tsx | 107 +++++++++--------- src/screens/Tabs/Shared/History.tsx | 7 +- src/screens/Tabs/Shared/Toot.tsx | 31 ++--- src/screens/Tabs/Shared/Users.tsx | 6 +- yarn.lock | 47 +++++++- 13 files changed, 146 insertions(+), 108 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6aaa6e64..081eb913 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -16,7 +16,7 @@ PODS: - ExpoModulesCore - EXNotifications (0.17.0): - ExpoModulesCore - - Expo (47.0.10): + - Expo (47.0.11): - ExpoModulesCore - ExpoCrypto (12.1.0): - ExpoModulesCore @@ -400,6 +400,8 @@ PODS: - React-Core - SDWebImage (~> 5.14.3) - SDWebImageWebPCoder (~> 0.9.1) + - RNFlashList (1.4.0): + - React-Core - RNGestureHandler (2.8.0): - React-Core - RNReanimated (2.13.0): @@ -521,6 +523,7 @@ DEPENDENCIES: - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" - RNFastImage (from `../node_modules/react-native-fast-image`) + - "RNFlashList (from `../node_modules/@shopify/flash-list`)" - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) @@ -680,6 +683,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-clipboard/clipboard" RNFastImage: :path: "../node_modules/react-native-fast-image" + RNFlashList: + :path: "../node_modules/@shopify/flash-list" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNReanimated: @@ -705,7 +710,7 @@ SPEC CHECKSUMS: EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6 EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80 EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a - Expo: a694d89d2461fdfc6b977bf489bf7d341ed03bca + Expo: dedd83acfd4d70cbec6ac2f1b4433462d95c70bc ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3 ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437 ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318 @@ -770,6 +775,7 @@ SPEC CHECKSUMS: RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd RNFastImage: 756ab178acb5e3f11d8b0a931956fbd9da8d6e54 + RNFlashList: 399bf6a0db68f594ad2c86aaff3ea39564f39f8a RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3 RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d diff --git a/package.json b/package.json index 7dea8757..da021e0b 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@react-navigation/stack": "^6.3.10", "@sentry/react-native": "4.12.0", "@sharcoux/slider": "^6.1.1", + "@shopify/flash-list": "^1.4.0", "@tanstack/react-query": "^4.20.9", "axios": "^1.2.2", "diff": "^5.1.0", diff --git a/src/components/Timeline/Refresh.tsx b/src/components/Timeline/Refresh.tsx index 8cb0aa9c..c1c5fe8d 100644 --- a/src/components/Timeline/Refresh.tsx +++ b/src/components/Timeline/Refresh.tsx @@ -1,12 +1,13 @@ import haptics from '@components/haptics' import Icon from '@components/Icon' +import { FlashList } from '@shopify/flash-list' import { InfiniteData, useQueryClient } from '@tanstack/react-query' import { QueryKeyTimeline, TimelineData, useTimelineQuery } from '@utils/queryHooks/timeline' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { RefObject, useCallback, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import { FlatList, LayoutChangeEvent, Platform, StyleSheet, Text, View } from 'react-native' +import { LayoutChangeEvent, Platform, StyleSheet, Text, View } from 'react-native' import { Circle } from 'react-native-animated-spinkit' import Animated, { Extrapolate, @@ -19,7 +20,7 @@ import Animated, { } from 'react-native-reanimated' export interface Props { - flRef: RefObject> + flRef: RefObject> queryKey: QueryKeyTimeline scrollY: Animated.SharedValue fetchingType: Animated.SharedValue<0 | 1 | 2> diff --git a/src/components/Timeline/index.tsx b/src/components/Timeline/index.tsx index 7121652c..158c673f 100644 --- a/src/components/Timeline/index.tsx +++ b/src/components/Timeline/index.tsx @@ -1,5 +1,6 @@ import ComponentSeparator from '@components/Separator' import { useScrollToTop } from '@react-navigation/native' +import { FlashList, FlashListProps } from '@shopify/flash-list' import { UseInfiniteQueryOptions } from '@tanstack/react-query' import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline' import { flattenPages } from '@utils/queryHooks/utils' @@ -7,16 +8,16 @@ import { useGlobalStorageListener } from '@utils/storage/actions' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { RefObject, useRef } from 'react' -import { FlatList, FlatListProps, Platform, RefreshControl } from 'react-native' +import { Platform, RefreshControl } from 'react-native' import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated' import TimelineEmpty from './Empty' import TimelineFooter from './Footer' import TimelineRefresh, { SEPARATION_Y_1, SEPARATION_Y_2 } from './Refresh' -const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) +const AnimatedFlatList = Animated.createAnimatedComponent(FlashList) export interface Props { - flRef?: RefObject> + flRef?: RefObject> queryKey: QueryKeyTimeline queryOptions?: Omit< UseInfiniteQueryOptions, @@ -24,7 +25,7 @@ export interface Props { > disableRefresh?: boolean disableInfinity?: boolean - customProps: Partial> & Pick, 'renderItem'> + customProps: Partial> & Pick, 'renderItem'> } const Timeline: React.FC = ({ @@ -55,7 +56,7 @@ const Timeline: React.FC = ({ } }) - const flRef = useRef(null) + const flRef = useRef>(null) const scrollY = useSharedValue(0) const fetchingType = useSharedValue<0 | 1 | 2>(0) @@ -92,6 +93,7 @@ const Timeline: React.FC = ({ } }) + // @ts-ignore useScrollToTop(flRef) useGlobalStorageListener('account.active', () => flRef.current?.scrollToOffset({ offset: 0, animated: false }) @@ -108,12 +110,10 @@ const Timeline: React.FC = ({ /> !disableInfinity && !isFetchingNextPage && fetchNextPage()} onEndReachedThreshold={0.75} ListFooterComponent={ diff --git a/src/screens/Compose/Root/Footer/Attachments.tsx b/src/screens/Compose/Root/Footer/Attachments.tsx index 611e1685..6531223a 100644 --- a/src/screens/Compose/Root/Footer/Attachments.tsx +++ b/src/screens/Compose/Root/Footer/Attachments.tsx @@ -5,12 +5,13 @@ import { MAX_MEDIA_ATTACHMENTS } from '@components/mediaSelector' import CustomText from '@components/Text' import { useActionSheet } from '@expo/react-native-action-sheet' import { useNavigation } from '@react-navigation/native' +import { FlashList } from '@shopify/flash-list' import { StyleConstants } from '@utils/styles/constants' import layoutAnimation from '@utils/styles/layoutAnimation' import { useTheme } from '@utils/styles/ThemeManager' import React, { RefObject, useContext, useEffect, useRef } from 'react' import { useTranslation } from 'react-i18next' -import { FlatList, Pressable, StyleSheet, View } from 'react-native' +import { Pressable, StyleSheet, View } from 'react-native' import { Circle } from 'react-native-animated-spinkit' import FastImage from 'react-native-fast-image' import ComposeContext from '../../utils/createContext' @@ -30,7 +31,7 @@ const ComposeAttachments: React.FC = ({ accessibleRefAttachments }) => { const { colors } = useTheme() const navigation = useNavigation() - const flatListRef = useRef(null) + const flatListRef = useRef>(null) const sensitiveOnPress = () => composeDispatch({ @@ -222,10 +223,11 @@ const ComposeAttachments: React.FC = ({ accessibleRefAttachments }) => { {t('content.root.footer.attachments.sensitive')} - > = ({ navigation @@ -49,8 +49,8 @@ const TabMeFollowedTags: React.FC> }) return ( - ( > = ({ route: { params } @@ -51,7 +52,7 @@ const TabMeListAccounts: React.FC> }) return ( - ( > = ({ navigation @@ -33,7 +34,7 @@ const TabMeSettingsLanguage: React.FC { diff --git a/src/screens/Tabs/Shared/Account/Attachments.tsx b/src/screens/Tabs/Shared/Account/Attachments.tsx index 7387ffe0..255e34cc 100644 --- a/src/screens/Tabs/Shared/Account/Attachments.tsx +++ b/src/screens/Tabs/Shared/Account/Attachments.tsx @@ -9,7 +9,7 @@ import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { useContext } from 'react' import { Dimensions, Pressable, View } from 'react-native' -import { FlatList } from 'react-native-gesture-handler' +import { ScrollView } from 'react-native-gesture-handler' import AccountContext from './Context' const AccountAttachments: React.FC = () => { @@ -39,67 +39,66 @@ const AccountAttachments: React.FC = () => { if (!flattenData.length) return null return ( - - { - if (index === DISPLAY_AMOUNT - 1) { - return ( - { - account && navigation.push('Tab-Shared-Attachments', { account }) - }} - children={ - - } - /> - } - /> - ) - } else { - return ( - navigation.push('Tab-Shared-Toot', { toot: item })} - /> - ) - } - }} - showsHorizontalScrollIndicator={false} - /> - + {flattenData.map((item, index) => { + if (index === DISPLAY_AMOUNT - 1) { + return ( + { + account && navigation.push('Tab-Shared-Attachments', { account }) + }} + children={ + + } + /> + } + /> + ) + } else { + return ( + navigation.push('Tab-Shared-Toot', { toot: item })} + /> + ) + } + })} + ) } diff --git a/src/screens/Tabs/Shared/History.tsx b/src/screens/Tabs/Shared/History.tsx index adcfb96f..1ed49c25 100644 --- a/src/screens/Tabs/Shared/History.tsx +++ b/src/screens/Tabs/Shared/History.tsx @@ -6,6 +6,7 @@ import CustomText from '@components/Text' import TimelineAttachment from '@components/Timeline/Shared/Attachment' import StatusContext from '@components/Timeline/Shared/Context' import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created' +import { FlashList } from '@shopify/flash-list' import removeHTML from '@utils/helpers/removeHTML' import { TabSharedStackScreenProps } from '@utils/navigation/navigators' import { useStatusHistory } from '@utils/queryHooks/statusesHistory' @@ -14,7 +15,7 @@ import { useTheme } from '@utils/styles/ThemeManager' import { diffChars, diffWords } from 'diff' import React, { useEffect } from 'react' import { useTranslation } from 'react-i18next' -import { FlatList, View } from 'react-native' +import { View } from 'react-native' const SCRIPTS_WITHOUT_BOUNDARIES = [ 'my', @@ -158,8 +159,8 @@ const TabSharedHistory: React.FC ).length return ( - ( > = ({ navigation.setParams({ toot, queryKey: queryKey.local }) }, [hasRemoteContent]) - const flRef = useRef(null) + const flRef = useRef>(null) const scrolled = useRef(false) const match = urlMatcher(toot.url || toot.uri) @@ -258,14 +259,13 @@ const TabSharedToot: React.FC> = ({ const ARC = StyleConstants.Avatar.XS / 4 return ( - { const prev = query.data.pages[0].body[index - 1]?._level || 0 - const curr = item._level + const curr = item._level || 0 const next = query.data.pages[0].body[index + 1]?._level || 0 return ( @@ -273,7 +273,7 @@ const TabSharedToot: React.FC> = ({ style={{ paddingLeft: index > highlightIndex.current - ? Math.min(item._level - 1, MAX_LEVEL) * StyleConstants.Spacing.S + ? Math.min((item._level || 0) - 1, MAX_LEVEL) * StyleConstants.Spacing.S : undefined }} onLayout={({ @@ -386,8 +386,6 @@ const TabSharedToot: React.FC> = ({ ) }} - initialNumToRender={6} - maxToRenderPerBatch={3} ItemSeparatorComponent={({ leadingItem }) => { return ( <> @@ -416,21 +414,6 @@ const TabSharedToot: React.FC> = ({ ) }} - onScrollToIndexFailed={error => { - const offset = error.averageItemLength * error.index - flRef.current?.scrollToOffset({ offset }) - try { - error.index < query.data.pages[0].body.length && - setTimeout( - () => - flRef.current?.scrollToIndex({ - index: error.index, - viewOffset: 100 - }), - 500 - ) - } catch {} - }} ListFooterComponent={ > = ({ navigation, @@ -44,9 +44,9 @@ const TabSharedUsers: React.FC> = const [isSearching, setIsSearching] = useState(false) return ( - = 15.2.1" + react-native: ">= 0.30.0" + checksum: 6cba6a99fb487067c509112b94e3d4d3905d782bbcb7af2cffbd57c601a4650d670e4eee5fec18d195d58ff6ec01a47288c5510379a2f37da3c5fc0a58860441 + languageName: node + linkType: hard + "regenerate-unicode-properties@npm:^10.1.0": version: 10.1.0 resolution: "regenerate-unicode-properties@npm:10.1.0" @@ -11266,6 +11294,7 @@ __metadata: "@react-navigation/stack": ^6.3.10 "@sentry/react-native": 4.12.0 "@sharcoux/slider": ^6.1.1 + "@shopify/flash-list": ^1.4.0 "@tanstack/react-query": ^4.20.9 "@types/diff": ^5.0.2 "@types/linkify-it": ^3.0.2 @@ -11356,6 +11385,20 @@ __metadata: languageName: node linkType: hard +"ts-object-utils@npm:0.0.5": + version: 0.0.5 + resolution: "ts-object-utils@npm:0.0.5" + checksum: 83c48fbdaba392fb2c01cea53b267ed5538d2bb44fc6c3eecc10bcfabc1780bfa6ec8569b52bbf0140d9b521d9049d5f15884e12286918244d463d854dbc73cb + languageName: node + linkType: hard + +"tslib@npm:2.4.0": + version: 2.4.0 + resolution: "tslib@npm:2.4.0" + checksum: 8c4aa6a3c5a754bf76aefc38026134180c053b7bd2f81338cb5e5ebf96fefa0f417bff221592bf801077f5bf990562f6264fecbc42cd3309b33872cb6fc3b113 + languageName: node + linkType: hard + "tslib@npm:^1.9.0, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1"