From d1714fab26211d1c4f6d1cbb057a20427dba7d70 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Mon, 30 Jan 2023 00:25:46 +0100 Subject: [PATCH] Added fetched notice --- src/components/Timeline/Refresh.tsx | 5 ++ src/components/Timeline/index.tsx | 86 ++++++++++++++++++++++++++-- src/i18n/en/components/timeline.json | 7 ++- 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/components/Timeline/Refresh.tsx b/src/components/Timeline/Refresh.tsx index d97ea7db..386f635c 100644 --- a/src/components/Timeline/Refresh.tsx +++ b/src/components/Timeline/Refresh.tsx @@ -17,6 +17,7 @@ import Animated, { Extrapolate, interpolate, runOnJS, + SharedValue, useAnimatedReaction, useAnimatedStyle, useDerivedValue, @@ -28,6 +29,7 @@ export interface Props { flRef: RefObject> queryKey: QueryKeyTimeline fetchingActive: React.MutableRefObject + setFetchedCount: React.Dispatch> scrollY: Animated.SharedValue fetchingType: Animated.SharedValue<0 | 1 | 2> disableRefresh?: boolean @@ -42,6 +44,7 @@ const TimelineRefresh: React.FC = ({ flRef, queryKey, fetchingActive, + setFetchedCount, scrollY, fetchingType, disableRefresh = false, @@ -152,6 +155,8 @@ const TimelineRefresh: React.FC = ({ meta: {} }) .then(res => { + setFetchedCount(res.body.length) + if (!res.body.length) return queryClient.setQueryData< diff --git a/src/components/Timeline/index.tsx b/src/components/Timeline/index.tsx index 884d224e..91551afa 100644 --- a/src/components/Timeline/index.tsx +++ b/src/components/Timeline/index.tsx @@ -1,4 +1,5 @@ import ComponentSeparator from '@components/Separator' +import CustomText from '@components/Text' import TimelineDefault from '@components/Timeline/Default' import { useScrollToTop } from '@react-navigation/native' import { UseInfiniteQueryOptions } from '@tanstack/react-query' @@ -11,9 +12,20 @@ import { } from '@utils/storage/actions' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' -import React, { RefObject, useRef } from 'react' +import React, { RefObject, useRef, useState } from 'react' +import { useTranslation } from 'react-i18next' import { FlatList, FlatListProps, Platform, RefreshControl } from 'react-native' -import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated' +import Animated, { + Easing, + runOnJS, + useAnimatedScrollHandler, + useAnimatedStyle, + useDerivedValue, + useSharedValue, + withDelay, + withSequence, + withTiming +} from 'react-native-reanimated' import TimelineEmpty from './Empty' import TimelineFooter from './Footer' import TimelineRefresh, { SEPARATION_Y_1, SEPARATION_Y_2 } from './Refresh' @@ -42,9 +54,10 @@ const Timeline: React.FC = ({ readMarker = undefined, customProps }) => { - const { colors } = useTheme() + const { colors, theme } = useTheme() + const { t } = useTranslation('componentTimeline') - const { data, refetch, isFetching, isLoading, fetchNextPage, isFetchingNextPage } = + const { data, refetch, isFetching, isLoading, isRefetching, fetchNextPage, isFetchingNextPage } = useTimelineQuery({ ...queryKey[1], options: { @@ -58,6 +71,28 @@ const Timeline: React.FC = ({ const flRef = useRef(null) const fetchingActive = useRef(false) + const [fetchedCount, setFetchedCount] = useState(null) + const fetchedNoticeHeight = useSharedValue(100) + const fetchedNoticeTop = useDerivedValue(() => { + if ((!isLoading && !isRefetching && isFetching) || fetchedCount !== null) { + return withSequence( + withTiming(fetchedNoticeHeight.value + 16 + 4), + withDelay( + 2000, + withTiming(0, { easing: Easing.out(Easing.ease) }, finished => { + if (finished) { + runOnJS(setFetchedCount)(null) + } + }) + ) + ) + } else { + return 0 + } + }, [isLoading, isRefetching, isFetching, fetchedCount]) + const fetchedNoticeAnimate = useAnimatedStyle(() => ({ + transform: [{ translateY: fetchedNoticeTop.value }] + })) const scrollY = useSharedValue(0) const fetchingType = useSharedValue<0 | 1 | 2>(0) @@ -96,9 +131,9 @@ const Timeline: React.FC = ({ const firstItemId = viewableItems.filter(item => item.isViewable)[0]?.item.id if (!fetchingActive.current && firstItemId && firstItemId > (marker || '0')) { - setAccountStorage([{ key: readMarker, value: firstItemId }]) + // setAccountStorage([{ key: readMarker, value: firstItemId }]) } else { - // setAccountStorage([{ key: readMarker, value: '109519141378761752' }]) + setAccountStorage([{ key: readMarker, value: '109519141378761752' }]) } } } @@ -136,6 +171,7 @@ const Timeline: React.FC = ({ flRef={flRef} queryKey={queryKey} fetchingActive={fetchingActive} + setFetchedCount={setFetchedCount} scrollY={scrollY} fetchingType={fetchingType} disableRefresh={disableRefresh} @@ -176,6 +212,44 @@ const Timeline: React.FC = ({ {...androidRefreshControl} {...customProps} /> + {!disableRefresh ? ( + (fetchedNoticeHeight.value = height)} + > + 0 + ? t('refresh.fetched.found', { count: fetchedCount }) + : t('refresh.fetched.none') + : t('refresh.fetching') + } + /> + + ) : null} ) } diff --git a/src/i18n/en/components/timeline.json b/src/i18n/en/components/timeline.json index 9c551d7e..68b08b49 100644 --- a/src/i18n/en/components/timeline.json +++ b/src/i18n/en/components/timeline.json @@ -16,7 +16,12 @@ }, "refresh": { "fetchPreviousPage": "Newer from here", - "refetch": "To latest" + "refetch": "To latest", + "fetching": "Fetching newer toots ...", + "fetched": { + "none": "No newer toot", + "found": "Fetched {{count}} toots" + } }, "shared": { "actioned": {