tooot/src/components/Timelines/Timeline.tsx

120 lines
3.4 KiB
TypeScript

import React from 'react'
import { ActivityIndicator, AppState, FlatList, Text, View } from 'react-native'
import { setFocusHandler, useInfiniteQuery } from 'react-query'
import TimelineNotifications from 'src/components/Timelines/Timeline/Notifications'
import TimelineDefault from 'src/components/Timelines/Timeline/Default'
import TimelineConversation from 'src/components/Timelines/Timeline/Conversation'
import { timelineFetch } from 'src/utils/fetches/timelineFetch'
import TimelineSeparator from './Timeline/Separator'
// Opening nesting hashtag pages
export interface Props {
page: App.Pages
hashtag?: string
list?: string
toot?: string
account?: string
disableRefresh?: boolean
scrollEnabled?: boolean
}
const Timeline: React.FC<Props> = ({
page,
hashtag,
list,
toot,
account,
disableRefresh = false,
scrollEnabled = true
}) => {
setFocusHandler(handleFocus => {
const handleAppStateChange = (appState: string) => {
if (appState === 'active') {
handleFocus()
}
}
AppState.addEventListener('change', handleAppStateChange)
return () => AppState.removeEventListener('change', handleAppStateChange)
})
const queryKey: App.QueryKey = [page, { page, hashtag, list, toot, account }]
const {
isLoading,
isFetchingMore,
isError,
isSuccess,
data,
fetchMore
} = useInfiniteQuery(queryKey, timelineFetch)
const flattenData = data ? data.flatMap(d => [...d?.toots]) : []
// const flattenPointer = data ? data.flatMap(d => [d?.pointer]) : []
let content
if (!isSuccess) {
content = <ActivityIndicator />
} else if (isError) {
content = <Text>Error message</Text>
} else {
content = (
<>
<FlatList
style={{ minHeight: '100%' }}
scrollEnabled={scrollEnabled} // For timeline in Account view
data={flattenData}
keyExtractor={({ id }) => id}
renderItem={({ item, index, separators }) => {
switch (page) {
case 'Conversations':
return <TimelineConversation key={index} item={item} />
case 'Notifications':
return (
<TimelineNotifications
key={index}
notification={item}
queryKey={queryKey}
/>
)
default:
return (
<TimelineDefault
key={index}
item={item}
queryKey={queryKey}
/>
)
}
}}
ItemSeparatorComponent={() => <TimelineSeparator />}
// require getItemLayout
// {...(flattenPointer[0] && { initialScrollIndex: flattenPointer[0] })}
{...(!disableRefresh && {
onRefresh: () =>
fetchMore(
{
direction: 'prev',
id: flattenData[0].id
},
{ previous: true }
),
refreshing: isLoading,
onEndReached: () => {
fetchMore({
direction: 'next',
id: flattenData[flattenData.length - 1].id
})
},
onEndReachedThreshold: 0.5
})}
/>
{isFetchingMore && <ActivityIndicator />}
</>
)
}
return <View>{content}</View>
}
export default Timeline