1
0
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:
Zhiyuan Zheng
2020-12-12 12:49:29 +01:00
parent 0fa9f87f66
commit 81a21d1d07
13 changed files with 140 additions and 116 deletions

View File

@ -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({