Files
frontend-app-discussions/src/discussions/posts/PostsView.jsx
Kshitij Sobti c9cb8dd0e7 feat: Add new breadcrumb navigation
Adds the new breadcrumb dropdown-based navigation UI. This allows browsing the category and topic structure using dropdowns.
2021-11-23 14:43:53 +05:30

108 lines
3.1 KiB
JavaScript

import React, { useContext, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router';
import { AppContext } from '@edx/frontend-platform/react';
import { Spinner } from '@edx/paragon';
import ScrollThreshold from '../../components/ScrollThreshold';
import { RequestStatus } from '../../data/constants';
import {
selectAllThreads,
selectThreadFilters,
selectThreadNextPage,
selectThreadSorting,
selectTopicThreads,
threadsLoadingStatus,
} from './data/selectors';
import { fetchThreads } from './data/thunks';
import PostFilterBar from './post-filter-bar/PostFilterBar';
import { PostLink } from './post';
function PostsView({ showOwnPosts }) {
const {
courseId,
topicId,
} = useParams();
const dispatch = useDispatch();
const { authenticatedUser } = useContext(AppContext);
const orderBy = useSelector(selectThreadSorting());
const filters = useSelector(selectThreadFilters());
const nextPage = useSelector(selectThreadNextPage());
const loadingStatus = useSelector(threadsLoadingStatus());
let posts = [];
if (topicId) {
posts = useSelector(selectTopicThreads(topicId));
} else {
posts = useSelector(selectAllThreads);
}
useEffect(() => {
// The courseId from the URL is the course we WANT to load.
dispatch(fetchThreads(courseId, {
topicIds: topicId ? [topicId] : null,
orderBy,
filters,
author: showOwnPosts ? authenticatedUser.username : null,
}));
}, [courseId, orderBy, filters, showOwnPosts, topicId]);
const loadMorePosts = async () => {
if (nextPage) {
dispatch(fetchThreads(courseId, {
topicIds: topicId ? [topicId] : null,
orderBy,
filters,
page: nextPage,
author: showOwnPosts ? authenticatedUser.username : null,
}));
}
};
let lastPinnedIdx = null;
return (
<div className="discussion-posts d-flex flex-column">
<PostFilterBar filterSelfPosts={showOwnPosts} />
<div className="list-group list-group-flush">
{posts && posts.map((post, idx) => {
if (post.pinned && lastPinnedIdx !== false) {
lastPinnedIdx = idx;
} else if (lastPinnedIdx != null && lastPinnedIdx !== false) {
lastPinnedIdx = false;
// Add a spacing after the group of pinned posts
return (
<React.Fragment key={post.id}>
<div className="p-1 bg-light-300" />
<PostLink post={post} key={post.id} />
</React.Fragment>
);
}
return (<PostLink post={post} key={post.id} />);
})}
{loadingStatus === RequestStatus.IN_PROGRESS ? (
<div className="d-flex justify-content-center p-4">
<Spinner animation="border" variant="primary" size="lg" />
</div>
) : (
nextPage && (
<ScrollThreshold onScroll={loadMorePosts} />
)
)}
</div>
</div>
);
}
PostsView.propTypes = {
showOwnPosts: PropTypes.bool,
};
PostsView.defaultProps = {
showOwnPosts: false,
};
export default PostsView;