import React, { useCallback, useContext, useEffect, useMemo, } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { AppContext } from '@edx/frontend-platform/react'; import { Button, Spinner } from '@edx/paragon'; import { RequestStatus } from '../../data/constants'; import { DiscussionContext } from '../common/context'; import { selectconfigLoadingStatus, selectUserHasModerationPrivileges, selectUserIsStaff } from '../data/selectors'; import { fetchUserPosts } from '../learners/data/thunks'; import messages from '../messages'; import { filterPosts } from '../utils'; import { selectThreadFilters, selectThreadNextPage, selectThreadSorting, threadsLoadingStatus, } from './data/selectors'; import { fetchThreads } from './data/thunks'; import NoResults from './NoResults'; import { PostLink } from './post'; function PostsList({ posts, topics, intl, isTopicTab, parentIsLoading, }) { const dispatch = useDispatch(); const { courseId, page, } = useContext(DiscussionContext); const loadingStatus = useSelector(threadsLoadingStatus()); const { authenticatedUser } = useContext(AppContext); const orderBy = useSelector(selectThreadSorting()); const filters = useSelector(selectThreadFilters()); const nextPage = useSelector(selectThreadNextPage()); const showOwnPosts = page === 'my-posts'; const userHasModerationPrivileges = useSelector(selectUserHasModerationPrivileges); const userIsStaff = useSelector(selectUserIsStaff); const configStatus = useSelector(selectconfigLoadingStatus); const loadThreads = (topicIds, pageNum = undefined, isFilterChanged = false) => { const params = { orderBy, filters, page: pageNum, author: showOwnPosts ? authenticatedUser.username : null, countFlagged: (userHasModerationPrivileges || userIsStaff) || undefined, topicIds, isFilterChanged, }; if (showOwnPosts && filters.search === '') { dispatch(fetchUserPosts(courseId, params)); } else { dispatch(fetchThreads(courseId, params)); } }; useEffect(() => { if (topics !== undefined && configStatus === RequestStatus.SUCCESSFUL) { loadThreads(topics); } }, [courseId, filters, orderBy, page, JSON.stringify(topics), configStatus]); useEffect(() => { if (isTopicTab) { loadThreads(topics, 1, true); } }, [filters]); const checkIsSelected = (id) => window.location.pathname.includes(id); const pinnedPosts = useMemo(() => filterPosts(posts, 'pinned'), [posts]); const unpinnedPosts = useMemo(() => filterPosts(posts, 'unpinned'), [posts]); const postInstances = useCallback((sortedPosts) => ( sortedPosts.map((post, idx) => ( )) ), []); return ( <> {!parentIsLoading && postInstances(pinnedPosts)} {!parentIsLoading && postInstances(unpinnedPosts)} {posts?.length === 0 && loadingStatus === RequestStatus.SUCCESSFUL && } {loadingStatus === RequestStatus.IN_PROGRESS || parentIsLoading ? (
) : ( nextPage && loadingStatus === RequestStatus.SUCCESSFUL && ( ) )} ); } PostsList.propTypes = { posts: PropTypes.arrayOf(PropTypes.shape({ pinned: PropTypes.bool.isRequired, id: PropTypes.string.isRequired, })), topics: PropTypes.arrayOf(PropTypes.string), isTopicTab: PropTypes.bool, parentIsLoading: PropTypes.bool, intl: intlShape.isRequired, }; PostsList.defaultProps = { posts: [], topics: undefined, isTopicTab: false, parentIsLoading: undefined, }; export default injectIntl(PostsList);