nicolium: reintroduce pull to refresh to timelines
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -3,6 +3,7 @@ import clsx from 'clsx';
|
||||
import React, { useMemo, useRef, useState } from 'react';
|
||||
import { defineMessages, FormattedList, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import PullToRefresh from '@/components/pull-to-refresh';
|
||||
import ScrollTopButton from '@/components/scroll-top-button';
|
||||
import ScrollableList, { type IScrollableList } from '@/components/scrollable-list';
|
||||
import Status, { StatusFollowedTagInfo } from '@/components/statuses/status';
|
||||
@ -397,6 +398,7 @@ const Timeline: React.FC<ITimeline> = ({
|
||||
isFetching,
|
||||
isPending,
|
||||
hasNextPage,
|
||||
refetch,
|
||||
} = query;
|
||||
|
||||
const handleMoveUp = (index: number) => {
|
||||
@ -542,21 +544,23 @@ const Timeline: React.FC<ITimeline> = ({
|
||||
{featuredStatusIds && featuredStatusIds.length > 3 && entries?.length > 0 && (
|
||||
<SkipPinned onClick={handleSkipPinned} />
|
||||
)}
|
||||
<ScrollableList
|
||||
id='status-list'
|
||||
key='scrollable-list'
|
||||
scrollKey={timelineId}
|
||||
isLoading={isFetching}
|
||||
showLoading={isPending}
|
||||
placeholderComponent={() => <PlaceholderTimelineStatus />}
|
||||
placeholderCount={20}
|
||||
ref={node}
|
||||
hasMore={hasNextPage}
|
||||
onLoadMore={fetchNextPage}
|
||||
{...props}
|
||||
>
|
||||
{renderedEntries}
|
||||
</ScrollableList>
|
||||
<PullToRefresh onRefresh={refetch} isPullable={!isFetching}>
|
||||
<ScrollableList
|
||||
id='status-list'
|
||||
key='scrollable-list'
|
||||
scrollKey={timelineId}
|
||||
isLoading={isFetching}
|
||||
showLoading={isPending}
|
||||
placeholderComponent={() => <PlaceholderTimelineStatus />}
|
||||
placeholderCount={20}
|
||||
ref={node}
|
||||
hasMore={hasNextPage}
|
||||
onLoadMore={fetchNextPage}
|
||||
{...props}
|
||||
>
|
||||
{renderedEntries}
|
||||
</ScrollableList>
|
||||
</PullToRefresh>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -33,16 +33,25 @@ const useTimeline = (
|
||||
fetchInitial();
|
||||
}, [timelineId]);
|
||||
|
||||
const fetchInitial = useCallback(async () => {
|
||||
timelineActions.setLoading(timelineId, true);
|
||||
try {
|
||||
const response = await fetcher();
|
||||
importEntities({ statuses: response.items });
|
||||
timelineActions.expandTimeline(timelineId, response.items, !!response.next, true, restoring);
|
||||
} catch (error) {
|
||||
timelineActions.setError(timelineId, true);
|
||||
}
|
||||
}, [timelineId, restoring]);
|
||||
const fetchInitial = useCallback(
|
||||
async (isRestoring = restoring) => {
|
||||
timelineActions.setLoading(timelineId, true);
|
||||
try {
|
||||
const response = await fetcher();
|
||||
importEntities({ statuses: response.items });
|
||||
timelineActions.expandTimeline(
|
||||
timelineId,
|
||||
response.items,
|
||||
!!response.next,
|
||||
true,
|
||||
isRestoring,
|
||||
);
|
||||
} catch (error) {
|
||||
timelineActions.setError(timelineId, true);
|
||||
}
|
||||
},
|
||||
[timelineId, restoring],
|
||||
);
|
||||
|
||||
const fetchNextPage = useCallback(async () => {
|
||||
timelineActions.setLoading(timelineId, true);
|
||||
@ -82,9 +91,14 @@ const useTimeline = (
|
||||
[timelineId, fetcher],
|
||||
);
|
||||
|
||||
const refetch = useCallback(() => {
|
||||
timelineActions.resetTimeline(timelineId);
|
||||
return fetchInitial(false);
|
||||
}, [timelineId, fetchInitial]);
|
||||
|
||||
return useMemo(
|
||||
() => ({ ...timeline, timelineId, fetchNextPage, dequeueEntries, fillGap }),
|
||||
[timeline, timelineId, fetchNextPage, dequeueEntries, fillGap],
|
||||
() => ({ ...timeline, timelineId, fetchNextPage, dequeueEntries, fillGap, refetch }),
|
||||
[timeline, timelineId, fetchNextPage, dequeueEntries, fillGap, refetch],
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { useRef } from 'react';
|
||||
|
||||
import { useClient } from '@/hooks/use-client';
|
||||
|
||||
import { useTimeline } from './use-timeline';
|
||||
@ -23,11 +25,21 @@ const useHomeTimeline = (
|
||||
) => {
|
||||
const client = useClient();
|
||||
const stream = 'user';
|
||||
const restoreMaxId = useRef(maxId);
|
||||
|
||||
return useTimeline(
|
||||
'home',
|
||||
(paginationParams) =>
|
||||
client.timelines.homeTimeline({ ...params, ...(paginationParams || { max_id: maxId }) }),
|
||||
(paginationParams) => {
|
||||
const initialPagination = restoreMaxId.current ? { max_id: restoreMaxId.current } : undefined;
|
||||
if (paginationParams == null) {
|
||||
restoreMaxId.current = undefined;
|
||||
}
|
||||
|
||||
return client.timelines.homeTimeline({
|
||||
...params,
|
||||
...(paginationParams ?? initialPagination),
|
||||
});
|
||||
},
|
||||
{ stream },
|
||||
!!maxId,
|
||||
);
|
||||
|
||||
@ -72,6 +72,7 @@ interface State {
|
||||
replacePendingStatus: (idempotencyKey: string, status: Status) => void;
|
||||
deletePendingStatus: (idempotencyKey: string) => void;
|
||||
filterTimelines: (accountId: string) => void;
|
||||
resetTimeline: (timelineId: string) => void;
|
||||
};
|
||||
}
|
||||
|
||||
@ -397,6 +398,10 @@ const useTimelinesStore = create<State>()(
|
||||
timeline.queuedCount = timeline.queuedEntries.length;
|
||||
}
|
||||
}),
|
||||
resetTimeline: (timelineId) =>
|
||||
set((state) => {
|
||||
state.timelines[timelineId] = createEmptyTimeline();
|
||||
}),
|
||||
},
|
||||
})),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user