Try out FlashList

This commit is contained in:
xmflsct 2023-01-06 01:41:46 +01:00
parent bd3046cc2f
commit 8406a57143
13 changed files with 146 additions and 108 deletions

View File

@ -16,7 +16,7 @@ PODS:
- ExpoModulesCore - ExpoModulesCore
- EXNotifications (0.17.0): - EXNotifications (0.17.0):
- ExpoModulesCore - ExpoModulesCore
- Expo (47.0.10): - Expo (47.0.11):
- ExpoModulesCore - ExpoModulesCore
- ExpoCrypto (12.1.0): - ExpoCrypto (12.1.0):
- ExpoModulesCore - ExpoModulesCore
@ -400,6 +400,8 @@ PODS:
- React-Core - React-Core
- SDWebImage (~> 5.14.3) - SDWebImage (~> 5.14.3)
- SDWebImageWebPCoder (~> 0.9.1) - SDWebImageWebPCoder (~> 0.9.1)
- RNFlashList (1.4.0):
- React-Core
- RNGestureHandler (2.8.0): - RNGestureHandler (2.8.0):
- React-Core - React-Core
- RNReanimated (2.13.0): - RNReanimated (2.13.0):
@ -521,6 +523,7 @@ DEPENDENCIES:
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- RNFastImage (from `../node_modules/react-native-fast-image`) - RNFastImage (from `../node_modules/react-native-fast-image`)
- "RNFlashList (from `../node_modules/@shopify/flash-list`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../node_modules/react-native-reanimated`) - RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`) - RNScreens (from `../node_modules/react-native-screens`)
@ -680,6 +683,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-clipboard/clipboard" :path: "../node_modules/@react-native-clipboard/clipboard"
RNFastImage: RNFastImage:
:path: "../node_modules/react-native-fast-image" :path: "../node_modules/react-native-fast-image"
RNFlashList:
:path: "../node_modules/@shopify/flash-list"
RNGestureHandler: RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler" :path: "../node_modules/react-native-gesture-handler"
RNReanimated: RNReanimated:
@ -705,7 +710,7 @@ SPEC CHECKSUMS:
EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6 EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6
EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80 EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80
EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a
Expo: a694d89d2461fdfc6b977bf489bf7d341ed03bca Expo: dedd83acfd4d70cbec6ac2f1b4433462d95c70bc
ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3 ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3
ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437 ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437
ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318 ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318
@ -770,6 +775,7 @@ SPEC CHECKSUMS:
RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
RNFastImage: 756ab178acb5e3f11d8b0a931956fbd9da8d6e54 RNFastImage: 756ab178acb5e3f11d8b0a931956fbd9da8d6e54
RNFlashList: 399bf6a0db68f594ad2c86aaff3ea39564f39f8a
RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3 RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3
RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a
RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d

View File

@ -39,6 +39,7 @@
"@react-navigation/stack": "^6.3.10", "@react-navigation/stack": "^6.3.10",
"@sentry/react-native": "4.12.0", "@sentry/react-native": "4.12.0",
"@sharcoux/slider": "^6.1.1", "@sharcoux/slider": "^6.1.1",
"@shopify/flash-list": "^1.4.0",
"@tanstack/react-query": "^4.20.9", "@tanstack/react-query": "^4.20.9",
"axios": "^1.2.2", "axios": "^1.2.2",
"diff": "^5.1.0", "diff": "^5.1.0",

View File

@ -1,12 +1,13 @@
import haptics from '@components/haptics' import haptics from '@components/haptics'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import { FlashList } from '@shopify/flash-list'
import { InfiniteData, useQueryClient } from '@tanstack/react-query' import { InfiniteData, useQueryClient } from '@tanstack/react-query'
import { QueryKeyTimeline, TimelineData, useTimelineQuery } from '@utils/queryHooks/timeline' import { QueryKeyTimeline, TimelineData, useTimelineQuery } from '@utils/queryHooks/timeline'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useCallback, useRef, useState } from 'react' import React, { RefObject, useCallback, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' 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 { Circle } from 'react-native-animated-spinkit'
import Animated, { import Animated, {
Extrapolate, Extrapolate,
@ -19,7 +20,7 @@ import Animated, {
} from 'react-native-reanimated' } from 'react-native-reanimated'
export interface Props { export interface Props {
flRef: RefObject<FlatList<any>> flRef: RefObject<FlashList<any>>
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
scrollY: Animated.SharedValue<number> scrollY: Animated.SharedValue<number>
fetchingType: Animated.SharedValue<0 | 1 | 2> fetchingType: Animated.SharedValue<0 | 1 | 2>

View File

@ -1,5 +1,6 @@
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import { useScrollToTop } from '@react-navigation/native' import { useScrollToTop } from '@react-navigation/native'
import { FlashList, FlashListProps } from '@shopify/flash-list'
import { UseInfiniteQueryOptions } from '@tanstack/react-query' import { UseInfiniteQueryOptions } from '@tanstack/react-query'
import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline' import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
import { flattenPages } from '@utils/queryHooks/utils' import { flattenPages } from '@utils/queryHooks/utils'
@ -7,16 +8,16 @@ import { useGlobalStorageListener } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useRef } from 'react' 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 Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated'
import TimelineEmpty from './Empty' import TimelineEmpty from './Empty'
import TimelineFooter from './Footer' import TimelineFooter from './Footer'
import TimelineRefresh, { SEPARATION_Y_1, SEPARATION_Y_2 } from './Refresh' import TimelineRefresh, { SEPARATION_Y_1, SEPARATION_Y_2 } from './Refresh'
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) const AnimatedFlatList = Animated.createAnimatedComponent(FlashList)
export interface Props { export interface Props {
flRef?: RefObject<FlatList<any>> flRef?: RefObject<FlashList<any>>
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
queryOptions?: Omit< queryOptions?: Omit<
UseInfiniteQueryOptions<any>, UseInfiniteQueryOptions<any>,
@ -24,7 +25,7 @@ export interface Props {
> >
disableRefresh?: boolean disableRefresh?: boolean
disableInfinity?: boolean disableInfinity?: boolean
customProps: Partial<FlatListProps<any>> & Pick<FlatListProps<any>, 'renderItem'> customProps: Partial<FlashListProps<any>> & Pick<FlashListProps<any>, 'renderItem'>
} }
const Timeline: React.FC<Props> = ({ const Timeline: React.FC<Props> = ({
@ -55,7 +56,7 @@ const Timeline: React.FC<Props> = ({
} }
}) })
const flRef = useRef<FlatList>(null) const flRef = useRef<FlashList<any>>(null)
const scrollY = useSharedValue(0) const scrollY = useSharedValue(0)
const fetchingType = useSharedValue<0 | 1 | 2>(0) const fetchingType = useSharedValue<0 | 1 | 2>(0)
@ -92,6 +93,7 @@ const Timeline: React.FC<Props> = ({
} }
}) })
// @ts-ignore
useScrollToTop(flRef) useScrollToTop(flRef)
useGlobalStorageListener('account.active', () => useGlobalStorageListener('account.active', () =>
flRef.current?.scrollToOffset({ offset: 0, animated: false }) flRef.current?.scrollToOffset({ offset: 0, animated: false })
@ -108,12 +110,10 @@ const Timeline: React.FC<Props> = ({
/> />
<AnimatedFlatList <AnimatedFlatList
ref={customFLRef || flRef} ref={customFLRef || flRef}
estimatedItemSize={200}
scrollEventThrottle={16} scrollEventThrottle={16}
onScroll={onScroll} onScroll={onScroll}
windowSize={7}
data={flattenPages(data)} data={flattenPages(data)}
initialNumToRender={6}
maxToRenderPerBatch={3}
onEndReached={() => !disableInfinity && !isFetchingNextPage && fetchNextPage()} onEndReached={() => !disableInfinity && !isFetchingNextPage && fetchNextPage()}
onEndReachedThreshold={0.75} onEndReachedThreshold={0.75}
ListFooterComponent={ ListFooterComponent={

View File

@ -5,12 +5,13 @@ import { MAX_MEDIA_ATTACHMENTS } from '@components/mediaSelector'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { useActionSheet } from '@expo/react-native-action-sheet' import { useActionSheet } from '@expo/react-native-action-sheet'
import { useNavigation } from '@react-navigation/native' import { useNavigation } from '@react-navigation/native'
import { FlashList } from '@shopify/flash-list'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import layoutAnimation from '@utils/styles/layoutAnimation' import layoutAnimation from '@utils/styles/layoutAnimation'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useContext, useEffect, useRef } from 'react' import React, { RefObject, useContext, useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next' 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 { Circle } from 'react-native-animated-spinkit'
import FastImage from 'react-native-fast-image' import FastImage from 'react-native-fast-image'
import ComposeContext from '../../utils/createContext' import ComposeContext from '../../utils/createContext'
@ -30,7 +31,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
const { colors } = useTheme() const { colors } = useTheme()
const navigation = useNavigation<any>() const navigation = useNavigation<any>()
const flatListRef = useRef<FlatList>(null) const flatListRef = useRef<FlashList<any>>(null)
const sensitiveOnPress = () => const sensitiveOnPress = () =>
composeDispatch({ composeDispatch({
@ -222,10 +223,11 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
{t('content.root.footer.attachments.sensitive')} {t('content.root.footer.attachments.sensitive')}
</CustomText> </CustomText>
</Pressable> </Pressable>
<FlatList <FlashList
horizontal horizontal
ref={flatListRef} ref={flatListRef}
decelerationRate={0} decelerationRate={0}
estimatedItemSize={100}
pagingEnabled={false} pagingEnabled={false}
snapToAlignment='center' snapToAlignment='center'
renderItem={renderAttachment} renderItem={renderAttachment}

View File

@ -3,12 +3,12 @@ import haptics from '@components/haptics'
import ComponentHashtag from '@components/Hashtag' import ComponentHashtag from '@components/Hashtag'
import { displayMessage } from '@components/Message' import { displayMessage } from '@components/Message'
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import { FlashList } from '@shopify/flash-list'
import { TabMeStackScreenProps } from '@utils/navigation/navigators' import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import { useFollowedTagsQuery, useTagsMutation } from '@utils/queryHooks/tags' import { useFollowedTagsQuery, useTagsMutation } from '@utils/queryHooks/tags'
import { flattenPages } from '@utils/queryHooks/utils' import { flattenPages } from '@utils/queryHooks/utils'
import React, { useEffect } from 'react' import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList } from 'react-native-gesture-handler'
const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>> = ({ const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>> = ({
navigation navigation
@ -49,8 +49,8 @@ const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>>
}) })
return ( return (
<FlatList <FlashList
style={{ flex: 1 }} estimatedItemSize={70}
data={flattenData} data={flattenData}
renderItem={({ item }) => ( renderItem={({ item }) => (
<ComponentHashtag <ComponentHashtag

View File

@ -3,6 +3,7 @@ import Button from '@components/Button'
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { displayMessage } from '@components/Message' import { displayMessage } from '@components/Message'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { FlashList } from '@shopify/flash-list'
import { TabMeStackScreenProps } from '@utils/navigation/navigators' import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import { import {
QueryKeyListAccounts, QueryKeyListAccounts,
@ -14,7 +15,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react' import React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, View } from 'react-native' import { View } from 'react-native'
const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>> = ({ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>> = ({
route: { params } route: { params }
@ -51,7 +52,7 @@ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>>
}) })
return ( return (
<FlatList <FlashList
data={flattenPages(data)} data={flattenPages(data)}
renderItem={({ item, index }) => ( renderItem={({ item, index }) => (
<ComponentAccount <ComponentAccount

View File

@ -1,13 +1,14 @@
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { MenuRow } from '@components/Menu' import { MenuRow } from '@components/Menu'
import { LOCALES } from '@i18n/locales' import { LOCALES } from '@i18n/locales'
import { FlashList } from '@shopify/flash-list'
import { TabMeStackScreenProps } from '@utils/navigation/navigators' import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import { setChannels } from '@utils/push/constants' import { setChannels } from '@utils/push/constants'
import { getGlobalStorage, useGlobalStorage } from '@utils/storage/actions' import { getGlobalStorage, useGlobalStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import React from 'react' import React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, Platform } from 'react-native' import { Platform } from 'react-native'
const TabMeSettingsLanguage: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Language'>> = ({ const TabMeSettingsLanguage: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Language'>> = ({
navigation navigation
@ -33,7 +34,7 @@ const TabMeSettingsLanguage: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Lan
} }
return ( return (
<FlatList <FlashList
style={{ flex: 1, paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }} style={{ flex: 1, paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }}
data={languages} data={languages}
renderItem={({ item }) => { renderItem={({ item }) => {

View File

@ -9,7 +9,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext } from 'react' import React, { useContext } from 'react'
import { Dimensions, Pressable, View } from 'react-native' 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' import AccountContext from './Context'
const AccountAttachments: React.FC = () => { const AccountAttachments: React.FC = () => {
@ -39,67 +39,66 @@ const AccountAttachments: React.FC = () => {
if (!flattenData.length) return null if (!flattenData.length) return null
return ( return (
<View <ScrollView
style={{ style={{
flex: 1, flex: 1,
flexDirection: 'row',
height: width + StyleConstants.Spacing.Global.PagePadding * 2, height: width + StyleConstants.Spacing.Global.PagePadding * 2,
paddingVertical: StyleConstants.Spacing.Global.PagePadding, paddingVertical: StyleConstants.Spacing.Global.PagePadding,
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: colors.border borderTopColor: colors.border
}} }}
horizontal
showsHorizontalScrollIndicator={false}
> >
<FlatList {flattenData.map((item, index) => {
horizontal if (index === DISPLAY_AMOUNT - 1) {
data={flattenData} return (
renderItem={({ item, index }) => { <Pressable
if (index === DISPLAY_AMOUNT - 1) { key={index}
return ( onPress={() => {
<Pressable account && navigation.push('Tab-Shared-Attachments', { account })
onPress={() => { }}
account && navigation.push('Tab-Shared-Attachments', { account }) children={
}} <View
children={ style={{
<View marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
style={{ backgroundColor: colors.backgroundOverlayInvert,
marginHorizontal: StyleConstants.Spacing.Global.PagePadding, width: width,
backgroundColor: colors.backgroundOverlayInvert, height: width,
width: width, justifyContent: 'center',
height: width, alignItems: 'center'
justifyContent: 'center', }}
alignItems: 'center' children={
}} <Icon
children={ name='MoreHorizontal'
<Icon color={colors.primaryOverlay}
name='MoreHorizontal' size={StyleConstants.Font.Size.L * 1.5}
color={colors.primaryOverlay} />
size={StyleConstants.Font.Size.L * 1.5} }
/> />
} }
/> />
} )
/> } else {
) return (
} else { <GracefullyImage
return ( key={index}
<GracefullyImage uri={{
uri={{ original: item.media_attachments[0]?.preview_url || item.media_attachments[0]?.url,
original: remote: item.media_attachments[0]?.remote_url
item.media_attachments[0]?.preview_url || item.media_attachments[0]?.url, }}
remote: item.media_attachments[0]?.remote_url blurhash={
}} item.media_attachments[0] && (item.media_attachments[0].blurhash || undefined)
blurhash={ }
item.media_attachments[0] && (item.media_attachments[0].blurhash || undefined) dimension={{ width: width, height: width }}
} style={{ marginLeft: StyleConstants.Spacing.Global.PagePadding }}
dimension={{ width: width, height: width }} onPress={() => navigation.push('Tab-Shared-Toot', { toot: item })}
style={{ marginLeft: StyleConstants.Spacing.Global.PagePadding }} />
onPress={() => navigation.push('Tab-Shared-Toot', { toot: item })} )
/> }
) })}
} </ScrollView>
}}
showsHorizontalScrollIndicator={false}
/>
</View>
) )
} }

View File

@ -6,6 +6,7 @@ import CustomText from '@components/Text'
import TimelineAttachment from '@components/Timeline/Shared/Attachment' import TimelineAttachment from '@components/Timeline/Shared/Attachment'
import StatusContext from '@components/Timeline/Shared/Context' import StatusContext from '@components/Timeline/Shared/Context'
import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created' import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created'
import { FlashList } from '@shopify/flash-list'
import removeHTML from '@utils/helpers/removeHTML' import removeHTML from '@utils/helpers/removeHTML'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators' import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { useStatusHistory } from '@utils/queryHooks/statusesHistory' import { useStatusHistory } from '@utils/queryHooks/statusesHistory'
@ -14,7 +15,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
import { diffChars, diffWords } from 'diff' import { diffChars, diffWords } from 'diff'
import React, { useEffect } from 'react' import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, View } from 'react-native' import { View } from 'react-native'
const SCRIPTS_WITHOUT_BOUNDARIES = [ const SCRIPTS_WITHOUT_BOUNDARIES = [
'my', 'my',
@ -158,8 +159,8 @@ const TabSharedHistory: React.FC<TabSharedStackScreenProps<'Tab-Shared-History'>
).length ).length
return ( return (
<FlatList <FlashList
style={{ flex: 1, minHeight: '100%' }} estimatedItemSize={100}
data={dataReversed} data={dataReversed}
renderItem={({ item, index }) => ( renderItem={({ item, index }) => (
<ContentView <ContentView

View File

@ -3,6 +3,7 @@ import Icon from '@components/Icon'
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import TimelineDefault from '@components/Timeline/Default' import TimelineDefault from '@components/Timeline/Default'
import { FlashList } from '@shopify/flash-list'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import apiGeneral from '@utils/api/general' import apiGeneral from '@utils/api/general'
import apiInstance from '@utils/api/instance' import apiInstance from '@utils/api/instance'
@ -15,7 +16,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { useEffect, useRef, useState } from 'react' import React, { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Alert, FlatList, Pressable, View } from 'react-native' import { Alert, Pressable, View } from 'react-native'
import { Circle } from 'react-native-animated-spinkit' import { Circle } from 'react-native-animated-spinkit'
import { Path, Svg } from 'react-native-svg' import { Path, Svg } from 'react-native-svg'
@ -69,7 +70,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
navigation.setParams({ toot, queryKey: queryKey.local }) navigation.setParams({ toot, queryKey: queryKey.local })
}, [hasRemoteContent]) }, [hasRemoteContent])
const flRef = useRef<FlatList>(null) const flRef = useRef<FlashList<Mastodon.Status>>(null)
const scrolled = useRef(false) const scrolled = useRef(false)
const match = urlMatcher(toot.url || toot.uri) const match = urlMatcher(toot.url || toot.uri)
@ -258,14 +259,13 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
const ARC = StyleConstants.Avatar.XS / 4 const ARC = StyleConstants.Avatar.XS / 4
return ( return (
<FlatList <FlashList
ref={flRef} ref={flRef}
scrollEventThrottle={16} estimatedItemSize={100}
windowSize={7}
data={query.data.pages?.[0].body} data={query.data.pages?.[0].body}
renderItem={({ item, index }) => { renderItem={({ item, index }) => {
const prev = query.data.pages[0].body[index - 1]?._level || 0 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 const next = query.data.pages[0].body[index + 1]?._level || 0
return ( return (
@ -273,7 +273,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
style={{ style={{
paddingLeft: paddingLeft:
index > highlightIndex.current 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 : undefined
}} }}
onLayout={({ onLayout={({
@ -386,8 +386,6 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
</View> </View>
) )
}} }}
initialNumToRender={6}
maxToRenderPerBatch={3}
ItemSeparatorComponent={({ leadingItem }) => { ItemSeparatorComponent={({ leadingItem }) => {
return ( return (
<> <>
@ -416,21 +414,6 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
</> </>
) )
}} }}
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={ ListFooterComponent={
<View <View
style={{ style={{

View File

@ -3,6 +3,7 @@ import { HeaderLeft } from '@components/Header'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { FlashList } from '@shopify/flash-list'
import apiInstance from '@utils/api/instance' import apiInstance from '@utils/api/instance'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators' import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { SearchResult } from '@utils/queryHooks/search' import { SearchResult } from '@utils/queryHooks/search'
@ -14,7 +15,6 @@ import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { View } from 'react-native' import { View } from 'react-native'
import { Circle, Flow } from 'react-native-animated-spinkit' import { Circle, Flow } from 'react-native-animated-spinkit'
import { FlatList } from 'react-native-gesture-handler'
const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> = ({ const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> = ({
navigation, navigation,
@ -44,9 +44,9 @@ const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> =
const [isSearching, setIsSearching] = useState(false) const [isSearching, setIsSearching] = useState(false)
return ( return (
<FlatList <FlashList
windowSize={7}
data={flattenPages(data)} data={flattenPages(data)}
estimatedItemSize={72}
style={{ style={{
minHeight: '100%', minHeight: '100%',
paddingVertical: StyleConstants.Spacing.Global.PagePadding paddingVertical: StyleConstants.Spacing.Global.PagePadding

View File

@ -3309,6 +3309,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@shopify/flash-list@npm:^1.4.0":
version: 1.4.0
resolution: "@shopify/flash-list@npm:1.4.0"
dependencies:
recyclerlistview: 4.2.0
tslib: 2.4.0
peerDependencies:
"@babel/runtime": "*"
react: "*"
react-native: "*"
checksum: c6510b0d6ae6404fe92ede0c918ba184bc2b27ed39c627eebad16a6542792cb34e750e2004e1a9ce165f9d729f1af0555cba1e4c224fd52bfd2a600fdc9e2a65
languageName: node
linkType: hard
"@sideway/address@npm:^4.1.3": "@sideway/address@npm:^4.1.3":
version: 4.1.4 version: 4.1.4
resolution: "@sideway/address@npm:4.1.4" resolution: "@sideway/address@npm:4.1.4"
@ -7643,7 +7657,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lodash.debounce@npm:^4.0.8": "lodash.debounce@npm:4.0.8, lodash.debounce@npm:^4.0.8":
version: 4.0.8 version: 4.0.8
resolution: "lodash.debounce@npm:4.0.8" resolution: "lodash.debounce@npm:4.0.8"
checksum: a3f527d22c548f43ae31c861ada88b2637eb48ac6aa3eb56e82d44917971b8aa96fbb37aa60efea674dc4ee8c42074f90f7b1f772e9db375435f6c83a19b3bc6 checksum: a3f527d22c548f43ae31c861ada88b2637eb48ac6aa3eb56e82d44917971b8aa96fbb37aa60efea674dc4ee8c42074f90f7b1f772e9db375435f6c83a19b3bc6
@ -9251,7 +9265,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"prop-types@npm:*, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": "prop-types@npm:*, prop-types@npm:15.8.1, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
version: 15.8.1 version: 15.8.1
resolution: "prop-types@npm:15.8.1" resolution: "prop-types@npm:15.8.1"
dependencies: dependencies:
@ -9963,6 +9977,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"recyclerlistview@npm:4.2.0":
version: 4.2.0
resolution: "recyclerlistview@npm:4.2.0"
dependencies:
lodash.debounce: 4.0.8
prop-types: 15.8.1
ts-object-utils: 0.0.5
peerDependencies:
react: ">= 15.2.1"
react-native: ">= 0.30.0"
checksum: 6cba6a99fb487067c509112b94e3d4d3905d782bbcb7af2cffbd57c601a4650d670e4eee5fec18d195d58ff6ec01a47288c5510379a2f37da3c5fc0a58860441
languageName: node
linkType: hard
"regenerate-unicode-properties@npm:^10.1.0": "regenerate-unicode-properties@npm:^10.1.0":
version: 10.1.0 version: 10.1.0
resolution: "regenerate-unicode-properties@npm:10.1.0" resolution: "regenerate-unicode-properties@npm:10.1.0"
@ -11266,6 +11294,7 @@ __metadata:
"@react-navigation/stack": ^6.3.10 "@react-navigation/stack": ^6.3.10
"@sentry/react-native": 4.12.0 "@sentry/react-native": 4.12.0
"@sharcoux/slider": ^6.1.1 "@sharcoux/slider": ^6.1.1
"@shopify/flash-list": ^1.4.0
"@tanstack/react-query": ^4.20.9 "@tanstack/react-query": ^4.20.9
"@types/diff": ^5.0.2 "@types/diff": ^5.0.2
"@types/linkify-it": ^3.0.2 "@types/linkify-it": ^3.0.2
@ -11356,6 +11385,20 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "tslib@npm:^1.9.0, tslib@npm:^1.9.3":
version: 1.14.1 version: 1.14.1
resolution: "tslib@npm:1.14.1" resolution: "tslib@npm:1.14.1"