tooot/src/screens/Tabs/Shared/Toot.tsx

121 lines
3.4 KiB
TypeScript
Raw Normal View History

2021-02-08 23:47:20 +01:00
import Timeline from '@components/Timeline'
2021-02-27 16:33:54 +01:00
import TimelineDefault from '@components/Timeline/Default'
import { useNavigation } from '@react-navigation/native'
2021-08-29 15:25:38 +02:00
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
2021-02-27 16:33:54 +01:00
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
2022-01-03 21:25:53 +01:00
import React, { useCallback, useEffect, useRef, useState } from 'react'
2021-02-27 16:33:54 +01:00
import { FlatList } from 'react-native'
import { InfiniteQueryObserver, useQueryClient } from 'react-query'
2022-01-08 11:19:24 +01:00
import * as Sentry from 'sentry-expo'
2020-10-29 14:52:28 +01:00
2021-08-29 15:25:38 +02:00
const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
2020-10-29 14:52:28 +01:00
route: {
2021-02-13 01:26:02 +01:00
params: { toot, rootQueryKey }
2020-10-29 14:52:28 +01:00
}
2020-10-31 21:04:46 +01:00
}) => {
2021-02-27 16:33:54 +01:00
const queryKey: QueryKeyTimeline = [
'Timeline',
{ page: 'Toot', toot: toot.id }
]
const flRef = useRef<FlatList>(null)
2022-01-03 21:25:53 +01:00
const [itemsLength, setItemsLength] = useState(0)
2021-02-27 16:33:54 +01:00
const scrolled = useRef(false)
const navigation = useNavigation()
const queryClient = useQueryClient()
const observer = new InfiniteQueryObserver(queryClient, { queryKey })
useEffect(() => {
const unsubscribe = observer.subscribe(result => {
if (result.isSuccess) {
const flattenData = result.data?.pages
? // @ts-ignore
result.data.pages.flatMap(d => [...d.body])
: []
2022-01-03 21:25:53 +01:00
setItemsLength(flattenData.length)
2021-02-27 16:33:54 +01:00
// Auto go back when toot page is empty
if (flattenData.length === 0) {
navigation.goBack()
}
if (!scrolled.current) {
scrolled.current = true
2022-01-30 22:51:03 +01:00
const pointer = flattenData.findIndex(({ id }) => id === toot.id)
2022-01-08 11:19:24 +01:00
try {
pointer < flattenData.length &&
setTimeout(() => {
flRef.current?.scrollToIndex({
index: pointer,
viewOffset: 100
})
}, 500)
} catch (err) {
if (Math.random() < 0.1) {
Sentry.Native.setExtras({
type: 'original',
2021-12-31 12:09:03 +01:00
index: pointer,
2022-01-08 11:19:24 +01:00
itemsLength: flattenData.length,
flattenData
2021-12-31 12:09:03 +01:00
})
2022-01-08 11:19:24 +01:00
Sentry.Native.captureException(err)
}
}
2021-02-27 16:33:54 +01:00
}
}
})
return () => unsubscribe()
2022-01-08 11:19:24 +01:00
}, [scrolled.current])
2021-02-27 16:33:54 +01:00
// Toot page auto scroll to selected toot
2022-01-03 21:25:53 +01:00
const onScrollToIndexFailed = useCallback(
error => {
const offset = error.averageItemLength * error.index
flRef.current?.scrollToOffset({ offset })
2022-01-08 11:19:24 +01:00
try {
error.index < itemsLength &&
setTimeout(
() =>
flRef.current?.scrollToIndex({
index: error.index,
viewOffset: 100
}),
500
)
} catch (err) {
if (Math.random() < 0.1) {
Sentry.Native.setExtras({
type: 'onScrollToIndexFailed',
index: error.index,
itemsLength
})
Sentry.Native.captureException(err)
}
}
2022-01-03 21:25:53 +01:00
},
[itemsLength]
)
2021-02-27 16:33:54 +01:00
const renderItem = useCallback(
({ item }) => (
<TimelineDefault
item={item}
queryKey={queryKey}
rootQueryKey={rootQueryKey}
highlighted={toot.id === item.id}
/>
),
[]
)
2021-02-13 01:26:02 +01:00
return (
<Timeline
2021-02-27 16:33:54 +01:00
flRef={flRef}
queryKey={queryKey}
2021-03-10 10:22:53 +01:00
customProps={{ renderItem, onScrollToIndexFailed }}
2021-02-13 01:26:02 +01:00
disableRefresh
disableInfinity
/>
)
2020-10-29 14:52:28 +01:00
}
2020-10-31 21:04:46 +01:00
2021-01-30 01:29:15 +01:00
export default TabSharedToot