mirror of
https://github.com/tooot-app/app
synced 2025-03-12 01:20:06 +01:00
Improve notify animation
This commit is contained in:
parent
7559196e42
commit
646b539949
@ -20,7 +20,6 @@ import Animated, {
|
||||
SharedValue,
|
||||
useAnimatedReaction,
|
||||
useAnimatedStyle,
|
||||
useDerivedValue,
|
||||
useSharedValue,
|
||||
withTiming
|
||||
} from 'react-native-reanimated'
|
||||
@ -28,10 +27,10 @@ import Animated, {
|
||||
export interface Props {
|
||||
flRef: RefObject<FlatList<any>>
|
||||
queryKey: QueryKeyTimeline
|
||||
fetchingActive: React.MutableRefObject<boolean>
|
||||
isFetchingPrev: SharedValue<boolean>
|
||||
setFetchedCount: React.Dispatch<React.SetStateAction<number | null>>
|
||||
scrollY: Animated.SharedValue<number>
|
||||
fetchingType: Animated.SharedValue<0 | 1 | 2>
|
||||
scrollY: SharedValue<number>
|
||||
fetchingType: SharedValue<0 | 1 | 2>
|
||||
disableRefresh?: boolean
|
||||
readMarker?: 'read_marker_following'
|
||||
}
|
||||
@ -43,7 +42,7 @@ export const SEPARATION_Y_2 = -(CONTAINER_HEIGHT * 1.5 + StyleConstants.Font.Siz
|
||||
const TimelineRefresh: React.FC<Props> = ({
|
||||
flRef,
|
||||
queryKey,
|
||||
fetchingActive,
|
||||
isFetchingPrev,
|
||||
setFetchedCount,
|
||||
scrollY,
|
||||
fetchingType,
|
||||
@ -58,20 +57,11 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
}
|
||||
|
||||
const PREV_PER_BATCH = 1
|
||||
const prevActive = useRef<boolean>(false)
|
||||
const prevCache = useRef<(Mastodon.Status | Mastodon.Notification | Mastodon.Conversation)[]>()
|
||||
const prevStatusId = useRef<Mastodon.Status['id']>()
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const { refetch, isRefetching } = useTimelineQuery({ ...queryKey[1] })
|
||||
|
||||
useDerivedValue(() => {
|
||||
if (prevActive.current || isRefetching) {
|
||||
fetchingActive.current = true
|
||||
} else {
|
||||
fetchingActive.current = false
|
||||
}
|
||||
}, [prevActive.current, isRefetching])
|
||||
const { refetch } = useTimelineQuery({ ...queryKey[1] })
|
||||
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const { colors } = useTheme()
|
||||
@ -99,7 +89,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
const arrowStage = useSharedValue(0)
|
||||
useAnimatedReaction(
|
||||
() => {
|
||||
if (fetchingActive.current) {
|
||||
if (isFetchingPrev.value) {
|
||||
return false
|
||||
}
|
||||
switch (arrowStage.value) {
|
||||
@ -131,13 +121,12 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
if (data) {
|
||||
runOnJS(haptics)('Light')
|
||||
}
|
||||
},
|
||||
[fetchingActive.current]
|
||||
}
|
||||
)
|
||||
|
||||
const fetchAndScrolled = useSharedValue(false)
|
||||
const runFetchPrevious = async () => {
|
||||
if (prevActive.current) return
|
||||
if (isFetchingPrev.value) return
|
||||
|
||||
const firstPage =
|
||||
queryClient.getQueryData<
|
||||
@ -146,7 +135,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
>
|
||||
>(queryKey)?.pages[0]
|
||||
|
||||
prevActive.current = true
|
||||
isFetchingPrev.value = true
|
||||
prevStatusId.current = firstPage?.body[0]?.id
|
||||
|
||||
await queryFunctionTimeline({
|
||||
@ -154,7 +143,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
pageParam: firstPage?.links?.prev,
|
||||
meta: {}
|
||||
})
|
||||
.then(res => {
|
||||
.then(async res => {
|
||||
setFetchedCount(res.body.length)
|
||||
|
||||
if (!res.body.length) return
|
||||
@ -177,7 +166,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
})
|
||||
.then(async nextLength => {
|
||||
if (!nextLength) {
|
||||
prevActive.current = false
|
||||
isFetchingPrev.value = false
|
||||
return
|
||||
}
|
||||
|
||||
@ -214,7 +203,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
}
|
||||
})
|
||||
}
|
||||
prevActive.current = false
|
||||
isFetchingPrev.value = false
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ import { FlatList, FlatListProps, Platform, RefreshControl } from 'react-native'
|
||||
import Animated, {
|
||||
Easing,
|
||||
runOnJS,
|
||||
useAnimatedReaction,
|
||||
useAnimatedScrollHandler,
|
||||
useAnimatedStyle,
|
||||
useDerivedValue,
|
||||
@ -70,26 +71,44 @@ const Timeline: React.FC<Props> = ({
|
||||
})
|
||||
|
||||
const flRef = useRef<FlatList>(null)
|
||||
const fetchingActive = useRef<boolean>(false)
|
||||
const isFetchingPrev = useSharedValue<boolean>(false)
|
||||
const [fetchedCount, setFetchedCount] = useState<number | null>(null)
|
||||
const fetchedNoticeHeight = useSharedValue<number>(100)
|
||||
const notifiedFetchedNotice = useSharedValue<boolean>(false)
|
||||
useAnimatedReaction(
|
||||
() => isFetchingPrev.value,
|
||||
(curr, prev) => {
|
||||
if (curr === true && prev === false) {
|
||||
notifiedFetchedNotice.value = true
|
||||
}
|
||||
}
|
||||
)
|
||||
useAnimatedReaction(
|
||||
() => fetchedCount,
|
||||
(curr, prev) => {
|
||||
if (curr !== null && prev === null) {
|
||||
notifiedFetchedNotice.value = false
|
||||
}
|
||||
},
|
||||
[fetchedCount]
|
||||
)
|
||||
const fetchedNoticeTop = useDerivedValue(() => {
|
||||
if ((!isLoading && !isRefetching && isFetching) || fetchedCount !== null) {
|
||||
if (notifiedFetchedNotice.value || fetchedCount !== null) {
|
||||
return withSequence(
|
||||
withTiming(fetchedNoticeHeight.value + 16 + 4),
|
||||
withDelay(
|
||||
2000,
|
||||
withTiming(0, { easing: Easing.out(Easing.ease) }, finished => {
|
||||
if (finished) {
|
||||
runOnJS(setFetchedCount)(null)
|
||||
}
|
||||
})
|
||||
withTiming(
|
||||
0,
|
||||
{ easing: Easing.out(Easing.ease) },
|
||||
finished => finished && runOnJS(setFetchedCount)(null)
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}, [isLoading, isRefetching, isFetching, fetchedCount])
|
||||
}, [fetchedCount])
|
||||
const fetchedNoticeAnimate = useAnimatedStyle(() => ({
|
||||
transform: [{ translateY: fetchedNoticeTop.value }]
|
||||
}))
|
||||
@ -130,7 +149,12 @@ const Timeline: React.FC<Props> = ({
|
||||
const marker = readMarker ? getAccountStorage.string(readMarker) : undefined
|
||||
|
||||
const firstItemId = viewableItems.filter(item => item.isViewable)[0]?.item.id
|
||||
if (!fetchingActive.current && firstItemId && firstItemId > (marker || '0')) {
|
||||
if (
|
||||
!isFetchingPrev.value &&
|
||||
!isRefetching &&
|
||||
firstItemId &&
|
||||
firstItemId > (marker || '0')
|
||||
) {
|
||||
setAccountStorage([{ key: readMarker, value: firstItemId }])
|
||||
} else {
|
||||
// setAccountStorage([{ key: readMarker, value: '109519141378761752' }])
|
||||
@ -170,7 +194,7 @@ const Timeline: React.FC<Props> = ({
|
||||
<TimelineRefresh
|
||||
flRef={flRef}
|
||||
queryKey={queryKey}
|
||||
fetchingActive={fetchingActive}
|
||||
isFetchingPrev={isFetchingPrev}
|
||||
setFetchedCount={setFetchedCount}
|
||||
scrollY={scrollY}
|
||||
fetchingType={fetchingType}
|
||||
@ -238,7 +262,7 @@ const Timeline: React.FC<Props> = ({
|
||||
}) => (fetchedNoticeHeight.value = height)}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
fontStyle='S'
|
||||
style={{ color: colors.primaryDefault }}
|
||||
children={
|
||||
fetchedCount !== null
|
||||
|
Loading…
x
Reference in New Issue
Block a user