import React, { useEffect } from 'react'; import immutable from 'immutable'; import { UR, EnrichedReaction } from 'getstream'; import { LoadMorePaginator, LoadMorePaginatorProps } from './LoadMorePaginator'; import { useFeedContext, DefaultUT, DefaultAT } from '../context'; import { smartRender, ElementOrComponentOrLiteralType } from '../utils'; export type ReactionListType = { /** The ID of the activity for which these reactions are */ activityId: string; /** The component that should render the reaction */ Reaction: ElementOrComponentOrLiteralType<{ reaction: EnrichedReaction; key?: string }>; /** The reaction kind that you want to display in this list, e.g `like` or `comment` */ reactionKind: string; /** Only needed for reposted activities where you want to show the reactions * of the original activity, not of the repost */ activityPath?: string[]; /** Show and load reactions starting with the oldest reaction first, instead * of the default where reactions are displayed and loaded most recent first. */ oldestToNewest?: boolean; /** By default pagination is done with a "Load more" button, you can use * [InfiniteScrollPaginator](/components/infinite-scroll) to enable infinite scrolling * #LoadMorePaginator (Component)# */ Paginator?: ElementOrComponentOrLiteralType; /** Reverse the order the reactions are displayed in. */ reverseOrder?: boolean; }; export const ReactionList = < UT extends DefaultUT = DefaultUT, AT extends DefaultAT = DefaultAT, CT extends UR = UR, RT extends UR = UR, CRT extends UR = UR, PT extends UR = UR >({ activityId, Reaction, reactionKind, activityPath: defaultActivityPath, oldestToNewest = false, Paginator = LoadMorePaginator, reverseOrder = false, }: ReactionListType) => { const feed = useFeedContext(); const activityPath = defaultActivityPath || feed.getActivityPath(activityId); const orderPrefix = oldestToNewest ? 'oldest' : 'latest'; const reactionsExtra = feed.activities.getIn([...activityPath, orderPrefix + '_reactions_extra']); const hasNextPage = reactionsExtra ? !!reactionsExtra.getIn([reactionKind, 'next'], '') : true; let reactions = feed.activities.getIn( [...activityPath, orderPrefix + '_reactions', reactionKind], immutable.List(), ) as immutable.List>; const refreshing = feed.activities.getIn( [...activityPath, orderPrefix + '_reactions_extra', reactionKind, 'refreshing'], false, ); if (reverseOrder) reactions = reactions.reverse(); const loadNextPage = () => { feed.loadNextReactions(activityId, reactionKind, activityPath, oldestToNewest); }; useEffect(() => { if (oldestToNewest && reactionsExtra) { loadNextPage(); } }, []); return ( <> {smartRender(Paginator, { loadNextPage, hasNextPage, refreshing, reverse: reverseOrder, children: reactions.map((reaction) => smartRender(Reaction, { reaction: reaction.toJS(), key: reaction.get('id'), }), ), })} ); };