nicolium: what about testing stuff before committing?
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -220,14 +220,17 @@ const TimelineStatus: React.FC<ITimelineStatus> = (props): React.JSX.Element =>
|
||||
);
|
||||
};
|
||||
|
||||
type IBaseTimeline = Pick<IScrollableList, 'emptyMessageIcon' | 'emptyMessageText'>;
|
||||
type IBaseTimeline = Pick<
|
||||
IScrollableList,
|
||||
'emptyMessageIcon' | 'emptyMessageText' | 'onTopItemChanged'
|
||||
>;
|
||||
|
||||
interface ITimeline extends IBaseTimeline {
|
||||
query: ReturnType<typeof useHomeTimeline>;
|
||||
contextType?: FilterContextType;
|
||||
}
|
||||
|
||||
const Timeline: React.FC<ITimeline> = ({ query, contextType = 'public' }) => {
|
||||
const Timeline: React.FC<ITimeline> = ({ query, contextType = 'public', ...props }) => {
|
||||
const node = useRef<VirtuosoHandle | null>(null);
|
||||
|
||||
const {
|
||||
@ -293,6 +296,7 @@ const Timeline: React.FC<ITimeline> = ({ query, contextType = 'public' }) => {
|
||||
ref={node}
|
||||
hasMore={hasNextPage}
|
||||
onLoadMore={fetchNextPage}
|
||||
{...props}
|
||||
>
|
||||
{(entries || []).map(renderEntry)}
|
||||
</ScrollableList>
|
||||
|
||||
@ -70,6 +70,8 @@ interface IScrollableList extends VirtuosoProps<any, any> {
|
||||
onScrollToTop?: () => void;
|
||||
/** Callback when the list is scrolled. */
|
||||
onScroll?: () => void;
|
||||
/** Callback when the topmost visible item index changes. */
|
||||
onTopItemChanged?: (index: number) => void;
|
||||
/** Placeholder component to render while loading. */
|
||||
placeholderComponent?: React.ComponentType | React.NamedExoticComponent;
|
||||
/** Number of placeholders to render while loading. */
|
||||
@ -104,6 +106,7 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(
|
||||
onScroll,
|
||||
onScrollToTop,
|
||||
onLoadMore,
|
||||
onTopItemChanged,
|
||||
className,
|
||||
listClassName,
|
||||
itemClassName,
|
||||
@ -220,6 +223,7 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(
|
||||
// HACK: using the first index can be buggy.
|
||||
// Track the second item instead, unless the endIndex comes before it (eg one 1 item in view).
|
||||
topIndex.current = Math.min(range.startIndex + 1, range.endIndex);
|
||||
onTopItemChanged?.(topIndex.current);
|
||||
handleScroll();
|
||||
};
|
||||
|
||||
|
||||
@ -14,7 +14,12 @@ interface StreamConfig {
|
||||
params?: StreamingParams;
|
||||
}
|
||||
|
||||
const useTimeline = (timelineId: string, fetcher: TimelineFetcher, streamConfig?: StreamConfig) => {
|
||||
const useTimeline = (
|
||||
timelineId: string,
|
||||
fetcher: TimelineFetcher,
|
||||
streamConfig?: StreamConfig,
|
||||
restoring?: boolean,
|
||||
) => {
|
||||
const timeline = useStoreTimeline(timelineId);
|
||||
const timelineActions = useTimelinesActions();
|
||||
|
||||
@ -30,11 +35,11 @@ const useTimeline = (timelineId: string, fetcher: TimelineFetcher, streamConfig?
|
||||
try {
|
||||
const response = await fetcher();
|
||||
importEntities({ statuses: response.items });
|
||||
timelineActions.expandTimeline(timelineId, response.items, !!response.next, true);
|
||||
timelineActions.expandTimeline(timelineId, response.items, !!response.next, true, restoring);
|
||||
} catch (error) {
|
||||
timelineActions.setError(timelineId, true);
|
||||
}
|
||||
}, [timelineId]);
|
||||
}, [timelineId, restoring]);
|
||||
|
||||
const fetchNextPage = useCallback(async () => {
|
||||
timelineActions.setLoading(timelineId, true);
|
||||
|
||||
@ -17,14 +17,19 @@ import type {
|
||||
WrenchedTimelineParams,
|
||||
} from 'pl-api';
|
||||
|
||||
const useHomeTimeline = (params?: Omit<HomeTimelineParams, keyof PaginationParams>) => {
|
||||
const useHomeTimeline = (
|
||||
params?: Omit<HomeTimelineParams, keyof PaginationParams>,
|
||||
maxId?: string,
|
||||
) => {
|
||||
const client = useClient();
|
||||
const stream = 'home';
|
||||
|
||||
return useTimeline(
|
||||
'home',
|
||||
(paginationParams) => client.timelines.homeTimeline({ ...params, ...paginationParams }),
|
||||
(paginationParams) =>
|
||||
client.timelines.homeTimeline({ ...params, ...(paginationParams || { max_id: maxId }) }),
|
||||
{ stream },
|
||||
!!maxId,
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -23,8 +23,8 @@ type TimelineEntry =
|
||||
}
|
||||
| {
|
||||
type: 'gap';
|
||||
sinceId: string;
|
||||
maxId: string;
|
||||
sinceId?: string;
|
||||
minId: string;
|
||||
};
|
||||
|
||||
interface TimelineData {
|
||||
@ -46,6 +46,7 @@ interface State {
|
||||
statuses: Array<Status>,
|
||||
hasMore?: boolean,
|
||||
initialFetch?: boolean,
|
||||
restoring?: boolean,
|
||||
) => void;
|
||||
receiveStreamingStatus: (timelineId: string, status: Status) => void;
|
||||
deleteStatus: (statusId: string) => void;
|
||||
@ -144,13 +145,19 @@ const useTimelinesStore = create<State>()(
|
||||
mutative((set) => ({
|
||||
timelines: {} as Record<string, TimelineData>,
|
||||
actions: {
|
||||
expandTimeline: (timelineId, statuses, hasMore, initialFetch = false) =>
|
||||
expandTimeline: (timelineId, statuses, hasMore, initialFetch = false, restoring = false) =>
|
||||
set((state) => {
|
||||
const timeline = state.timelines[timelineId] ?? createEmptyTimeline();
|
||||
const entries = processPage(statuses);
|
||||
|
||||
if (initialFetch) timeline.entries = entries;
|
||||
else timeline.entries.push(...entries);
|
||||
if (restoring) {
|
||||
timeline.entries.unshift({
|
||||
type: 'gap',
|
||||
minId: statuses[0].id,
|
||||
});
|
||||
}
|
||||
timeline.isPending = false;
|
||||
timeline.isFetching = false;
|
||||
if (typeof hasMore === 'boolean') {
|
||||
|
||||
Reference in New Issue
Block a user