mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Scroll to toot working
This commit is contained in:
@ -1,12 +1,5 @@
|
||||
import React, { useCallback } from 'react'
|
||||
import {
|
||||
ActivityIndicator,
|
||||
AppState,
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import React, { useCallback, useEffect, useRef } from 'react'
|
||||
import { ActivityIndicator, AppState, FlatList, StyleSheet } from 'react-native'
|
||||
import { setFocusHandler, useInfiniteQuery } from 'react-query'
|
||||
|
||||
import TimelineNotifications from 'src/components/Timelines/Timeline/Notifications'
|
||||
@ -14,14 +7,13 @@ 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
|
||||
import TimelineEmpty from './Timeline/Empty'
|
||||
|
||||
export interface Props {
|
||||
page: App.Pages
|
||||
hashtag?: string
|
||||
list?: string
|
||||
toot?: string
|
||||
toot?: Mastodon.Status
|
||||
account?: string
|
||||
disableRefresh?: boolean
|
||||
scrollEnabled?: boolean
|
||||
@ -48,15 +40,28 @@ const Timeline: React.FC<Props> = ({
|
||||
|
||||
const queryKey: App.QueryKey = [page, { page, hashtag, list, toot, account }]
|
||||
const {
|
||||
isLoading,
|
||||
isFetchingMore,
|
||||
isError,
|
||||
isSuccess,
|
||||
isLoading,
|
||||
isError,
|
||||
isFetchingMore,
|
||||
data,
|
||||
fetchMore
|
||||
fetchMore,
|
||||
refetch
|
||||
} = useInfiniteQuery(queryKey, timelineFetch)
|
||||
const flattenData = data ? data.flatMap(d => [...d?.toots]) : []
|
||||
// const flattenPointer = data ? data.flatMap(d => [d?.pointer]) : []
|
||||
const flattenPointer = data ? data.flatMap(d => [d?.pointer]) : []
|
||||
|
||||
const flRef = useRef<FlatList>(null)
|
||||
useEffect(() => {
|
||||
if (toot && isSuccess) {
|
||||
setTimeout(() => {
|
||||
flRef.current?.scrollToIndex({
|
||||
index: flattenPointer[0],
|
||||
viewOffset: 100
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
}, [isSuccess])
|
||||
|
||||
const flKeyExtrator = useCallback(({ id }) => id, [])
|
||||
const flRenderItem = useCallback(({ item }) => {
|
||||
@ -80,7 +85,7 @@ const Timeline: React.FC<Props> = ({
|
||||
},
|
||||
{ previous: true }
|
||||
),
|
||||
[disableRefresh, flattenData]
|
||||
[flattenData]
|
||||
)
|
||||
const flOnEndReach = useCallback(
|
||||
() =>
|
||||
@ -89,37 +94,49 @@ const Timeline: React.FC<Props> = ({
|
||||
direction: 'next',
|
||||
id: flattenData[flattenData.length - 1].id
|
||||
}),
|
||||
[disableRefresh, flattenData]
|
||||
[flattenData]
|
||||
)
|
||||
|
||||
let content
|
||||
if (!isSuccess) {
|
||||
content = <ActivityIndicator />
|
||||
} else if (isError) {
|
||||
content = <Text>Error message</Text>
|
||||
} else {
|
||||
content = (
|
||||
<>
|
||||
<FlatList
|
||||
data={flattenData}
|
||||
onRefresh={flOnRefresh}
|
||||
renderItem={flRenderItem}
|
||||
onEndReached={flOnEndReach}
|
||||
keyExtractor={flKeyExtrator}
|
||||
style={styles.flatList}
|
||||
scrollEnabled={scrollEnabled} // For timeline in Account view
|
||||
ItemSeparatorComponent={flItemSeparatorComponent}
|
||||
refreshing={!disableRefresh && isLoading}
|
||||
onEndReachedThreshold={!disableRefresh ? 1 : null}
|
||||
// require getItemLayout
|
||||
// {...(flattenPointer[0] && { initialScrollIndex: flattenPointer[0] })}
|
||||
/>
|
||||
{isFetchingMore && <ActivityIndicator />}
|
||||
</>
|
||||
const flFooter = useCallback(() => {
|
||||
if (isFetchingMore) {
|
||||
return <ActivityIndicator />
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}, [isFetchingMore])
|
||||
const onScrollToIndexFailed = useCallback(error => {
|
||||
const offset = error.averageItemLength * error.index
|
||||
flRef.current?.scrollToOffset({ offset })
|
||||
setTimeout(
|
||||
() =>
|
||||
flRef.current?.scrollToIndex({ index: error.index, viewOffset: 100 }),
|
||||
350
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return <View>{content}</View>
|
||||
return (
|
||||
<FlatList
|
||||
ref={flRef}
|
||||
data={flattenData}
|
||||
style={styles.flatList}
|
||||
onRefresh={flOnRefresh}
|
||||
renderItem={flRenderItem}
|
||||
onEndReached={flOnEndReach}
|
||||
keyExtractor={flKeyExtrator}
|
||||
ListFooterComponent={flFooter}
|
||||
scrollEnabled={scrollEnabled} // For timeline in Account view
|
||||
ItemSeparatorComponent={flItemSeparatorComponent}
|
||||
onEndReachedThreshold={!disableRefresh ? 0.75 : null}
|
||||
refreshing={!disableRefresh && isLoading && flattenData.length > 0}
|
||||
ListEmptyComponent={
|
||||
<TimelineEmpty
|
||||
isLoading={isLoading}
|
||||
isError={isError}
|
||||
refetch={refetch}
|
||||
/>
|
||||
}
|
||||
{...(toot && isSuccess && { onScrollToIndexFailed })}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
Reference in New Issue
Block a user