1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00
Added trending in the "public" tab
This commit is contained in:
xmflsct
2022-12-11 01:08:38 +01:00
parent 1ece7b3fe3
commit 44379504eb
23 changed files with 508 additions and 598 deletions

View File

@ -6,17 +6,11 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useCallback, useRef } from 'react'
import { FlatList, FlatListProps, Platform, RefreshControl } from 'react-native'
import Animated, {
useAnimatedScrollHandler,
useSharedValue
} from 'react-native-reanimated'
import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated'
import { useSelector } from 'react-redux'
import TimelineEmpty from './Timeline/Empty'
import TimelineFooter from './Timeline/Footer'
import TimelineRefresh, {
SEPARATION_Y_1,
SEPARATION_Y_2
} from './Timeline/Refresh'
import TimelineRefresh, { SEPARATION_Y_1, SEPARATION_Y_2 } from './Timeline/Refresh'
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList)
@ -26,8 +20,7 @@ export interface Props {
disableRefresh?: boolean
disableInfinity?: boolean
lookback?: Extract<App.Pages, 'Following' | 'Local' | 'LocalPublic'>
customProps: Partial<FlatListProps<any>> &
Pick<FlatListProps<any>, 'renderItem'>
customProps: Partial<FlatListProps<any>> & Pick<FlatListProps<any>, 'renderItem'>
}
const Timeline: React.FC<Props> = ({
@ -39,30 +32,24 @@ const Timeline: React.FC<Props> = ({
}) => {
const { colors } = useTheme()
const {
data,
refetch,
isFetching,
isLoading,
fetchNextPage,
isFetchingNextPage
} = useTimelineQuery({
...queryKey[1],
options: {
notifyOnChangeProps: Platform.select({
ios: ['dataUpdatedAt', 'isFetching'],
android: ['dataUpdatedAt', 'isFetching', 'isLoading']
}),
getNextPageParam: lastPage =>
lastPage?.links?.next && {
max_id: lastPage.links.next
}
}
})
const { data, refetch, isFetching, isLoading, fetchNextPage, isFetchingNextPage } =
useTimelineQuery({
...queryKey[1],
options: {
notifyOnChangeProps: Platform.select({
ios: ['dataUpdatedAt', 'isFetching'],
android: ['dataUpdatedAt', 'isFetching', 'isLoading']
}),
getNextPageParam: lastPage =>
lastPage?.links?.next && {
...(lastPage.links.next.isOffset
? { offset: lastPage.links.next.id }
: { max_id: lastPage.links.next.id })
}
}
})
const flattenData = data?.pages
? data.pages?.flatMap(page => [...page.body])
: []
const flattenData = data?.pages ? data.pages?.flatMap(page => [...page.body]) : []
const onEndReached = useCallback(
() => !disableInfinity && !isFetchingNextPage && fetchNextPage(),
@ -134,10 +121,7 @@ const Timeline: React.FC<Props> = ({
onEndReached={onEndReached}
onEndReachedThreshold={0.75}
ListFooterComponent={
<TimelineFooter
queryKey={queryKey}
disableInfinity={disableInfinity}
/>
<TimelineFooter queryKey={queryKey} disableInfinity={disableInfinity} />
}
ListEmptyComponent={<TimelineEmpty queryKey={queryKey} />}
ItemSeparatorComponent={({ leadingItem }) =>
@ -145,9 +129,7 @@ const Timeline: React.FC<Props> = ({
<ComponentSeparator extraMarginLeft={0} />
) : (
<ComponentSeparator
extraMarginLeft={
StyleConstants.Avatar.M + StyleConstants.Spacing.S
}
extraMarginLeft={StyleConstants.Avatar.M + StyleConstants.Spacing.S}
/>
)
}

View File

@ -21,7 +21,11 @@ const TimelineFooter = React.memo(
enabled: !disableInfinity,
notifyOnChangeProps: ['hasNextPage'],
getNextPageParam: lastPage =>
lastPage?.links?.next && { max_id: lastPage.links.next }
lastPage?.links?.next && {
...(lastPage.links.next.isOffset
? { offset: lastPage.links.next.id }
: { max_id: lastPage.links.next.id })
}
}
})
@ -43,11 +47,7 @@ const TimelineFooter = React.memo(
<Trans
i18nKey='componentTimeline:end.message'
components={[
<Icon
name='Coffee'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
/>
<Icon name='Coffee' size={StyleConstants.Font.Size.S} color={colors.secondary} />
]}
/>
</CustomText>

View File

@ -1,10 +1,6 @@
import haptics from '@components/haptics'
import Icon from '@components/Icon'
import {
QueryKeyTimeline,
TimelineData,
useTimelineQuery
} from '@utils/queryHooks/timeline'
import { QueryKeyTimeline, TimelineData, useTimelineQuery } from '@utils/queryHooks/timeline'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useCallback, useRef, useState } from 'react'
@ -31,14 +27,8 @@ export interface Props {
}
const CONTAINER_HEIGHT = StyleConstants.Spacing.M * 2.5
export const SEPARATION_Y_1 = -(
CONTAINER_HEIGHT / 2 +
StyleConstants.Font.Size.S / 2
)
export const SEPARATION_Y_2 = -(
CONTAINER_HEIGHT * 1.5 +
StyleConstants.Font.Size.S / 2
)
export const SEPARATION_Y_1 = -(CONTAINER_HEIGHT / 2 + StyleConstants.Font.Size.S / 2)
export const SEPARATION_Y_2 = -(CONTAINER_HEIGHT * 1.5 + StyleConstants.Font.Size.S / 2)
const TimelineRefresh: React.FC<Props> = ({
flRef,
@ -57,87 +47,77 @@ const TimelineRefresh: React.FC<Props> = ({
const fetchingLatestIndex = useRef(0)
const refetchActive = useRef(false)
const {
refetch,
isFetching,
isLoading,
fetchPreviousPage,
hasPreviousPage,
isFetchingNextPage
} = useTimelineQuery({
...queryKey[1],
options: {
getPreviousPageParam: firstPage =>
firstPage?.links?.prev && {
min_id: firstPage.links.prev,
// https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
limit: '3'
const { refetch, isFetching, isLoading, fetchPreviousPage, hasPreviousPage, isFetchingNextPage } =
useTimelineQuery({
...queryKey[1],
options: {
getPreviousPageParam: firstPage =>
firstPage?.links?.prev && {
...(firstPage.links.prev.isOffset
? { offset: firstPage.links.prev.id }
: { max_id: firstPage.links.prev.id }),
// https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
limit: '3'
},
select: data => {
if (refetchActive.current) {
data.pageParams = [data.pageParams[0]]
data.pages = [data.pages[0]]
refetchActive.current = false
}
return data
},
select: data => {
if (refetchActive.current) {
data.pageParams = [data.pageParams[0]]
data.pages = [data.pages[0]]
refetchActive.current = false
}
return data
},
onSuccess: () => {
if (fetchingLatestIndex.current > 0) {
if (fetchingLatestIndex.current > 5) {
clearFirstPage()
fetchingLatestIndex.current = 0
} else {
if (hasPreviousPage) {
fetchPreviousPage()
fetchingLatestIndex.current++
} else {
onSuccess: () => {
if (fetchingLatestIndex.current > 0) {
if (fetchingLatestIndex.current > 5) {
clearFirstPage()
fetchingLatestIndex.current = 0
} else {
if (hasPreviousPage) {
fetchPreviousPage()
fetchingLatestIndex.current++
} else {
clearFirstPage()
fetchingLatestIndex.current = 0
}
}
}
}
}
}
})
})
const { t } = useTranslation('componentTimeline')
const { colors } = useTheme()
const queryClient = useQueryClient()
const clearFirstPage = () => {
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
queryKey,
data => {
if (data?.pages[0] && data.pages[0].body.length === 0) {
return {
pages: data.pages.slice(1),
pageParams: data.pageParams.slice(1)
}
} else {
return data
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(queryKey, data => {
if (data?.pages[0] && data.pages[0].body.length === 0) {
return {
pages: data.pages.slice(1),
pageParams: data.pageParams.slice(1)
}
} else {
return data
}
)
})
}
const prepareRefetch = () => {
refetchActive.current = true
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
queryKey,
data => {
if (data) {
data.pageParams = [undefined]
const newFirstPage: TimelineData = { body: [] }
for (let page of data.pages) {
// @ts-ignore
newFirstPage.body.push(...page.body)
if (newFirstPage.body.length > 10) break
}
data.pages = [newFirstPage]
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(queryKey, data => {
if (data) {
data.pageParams = [undefined]
const newFirstPage: TimelineData = { body: [] }
for (let page of data.pages) {
// @ts-ignore
newFirstPage.body.push(...page.body)
if (newFirstPage.body.length > 10) break
}
return data
data.pages = [newFirstPage]
}
)
return data
})
}
const callRefetch = async () => {
await refetch()
@ -161,10 +141,7 @@ const TimelineRefresh: React.FC<Props> = ({
]
}))
const arrowTop = useAnimatedStyle(() => ({
marginTop:
scrollY.value < SEPARATION_Y_2
? withTiming(CONTAINER_HEIGHT)
: withTiming(0)
marginTop: scrollY.value < SEPARATION_Y_2 ? withTiming(CONTAINER_HEIGHT) : withTiming(0)
}))
const arrowStage = useSharedValue(0)
@ -241,8 +218,7 @@ const TimelineRefresh: React.FC<Props> = ({
const headerPadding = useAnimatedStyle(
() => ({
paddingTop:
fetchingLatestIndex.current !== 0 ||
(isFetching && !isLoading && !isFetchingNextPage)
fetchingLatestIndex.current !== 0 || (isFetching && !isLoading && !isFetchingNextPage)
? withTiming(StyleConstants.Spacing.M * 2.5)
: withTiming(0)
}),
@ -254,10 +230,7 @@ const TimelineRefresh: React.FC<Props> = ({
<View style={styles.base}>
{isFetching ? (
<View style={styles.container2}>
<Circle
size={StyleConstants.Font.Size.L}
color={colors.secondary}
/>
<Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
</View>
) : (
<>