lbry-desktop/ui/component/commentsReplies/view.jsx
infinite-persistence 74986a8b3a
Comments: simplify blocked replies display
Previously, we decide when to display "Show More" based on the current fetched reply count vs. total replies in Commentron. It was already troublesome as `comment.List` and `comment.replies` give different values (one includes blocked content, while another does not).

Now, we are further filtering the list with Commentron blocklists (personal, admin, moderator), so it is not feasible to run the logic based on reply count.

## Solution
- Keep track of number of remaining pages instead and use that to determine when to display "Show More".
  - While it doesn't solve the "Show N replies" mismatch (YT has this problem too), it prevents the button from lingering.
- In the event that all replies are blocked, just show an empty space (same as YT). I didn't like the previous version that cluttered the space with "comment(s) blocked".
2021-08-24 16:55:36 +08:00

126 lines
3.9 KiB
JavaScript

// @flow
import * as ICONS from 'constants/icons';
import React from 'react';
import Comment from 'component/comment';
import Button from 'component/button';
import Spinner from 'component/spinner';
type Props = {
fetchedReplies: Array<any>,
uri: string,
parentId: string,
claimIsMine: boolean,
myChannels: ?Array<ChannelClaim>,
linkedCommentId?: string,
commentingEnabled: boolean,
threadDepth: number,
numDirectReplies: number, // Total replies for parentId as reported by 'comment[replies]'. Includes blocked items.
isFetchingByParentId: { [string]: boolean },
onShowMore?: () => void,
hasMore: boolean,
};
function CommentsReplies(props: Props) {
const {
uri,
parentId,
fetchedReplies,
claimIsMine,
myChannels,
linkedCommentId,
commentingEnabled,
threadDepth,
numDirectReplies,
isFetchingByParentId,
onShowMore,
hasMore,
} = props;
const [isExpanded, setExpanded] = React.useState(true);
function showMore() {
if (onShowMore) {
onShowMore();
}
}
// todo: implement comment_list --mine in SDK so redux can grab with selectCommentIsMine
function isMyComment(channelId: string) {
if (myChannels != null && channelId != null) {
for (let i = 0; i < myChannels.length; i++) {
if (myChannels[i].claim_id === channelId) {
return true;
}
}
}
return false;
}
const displayedComments = fetchedReplies;
return (
Boolean(numDirectReplies) && (
<div className="comment__replies-container">
{Boolean(numDirectReplies) && !isExpanded && (
<div className="comment__actions--nested">
<Button
className="comment__action"
label={__('Show Replies')}
onClick={() => setExpanded(!isExpanded)}
icon={isExpanded ? ICONS.UP : ICONS.DOWN}
/>
</div>
)}
{isExpanded && (
<div>
<div className="comment__replies">
<Button className="comment__threadline" aria-label="Hide Replies" onClick={() => setExpanded(false)} />
<ul className="comments--replies">
{displayedComments &&
displayedComments.map((comment) => {
return (
<Comment
threadDepth={threadDepth}
uri={uri}
authorUri={comment.channel_url}
author={comment.channel_name}
claimId={comment.claim_id}
commentId={comment.comment_id}
key={comment.comment_id}
message={comment.comment}
timePosted={comment.timestamp * 1000}
claimIsMine={claimIsMine}
commentIsMine={comment.channel_id && isMyComment(comment.channel_id)}
linkedCommentId={linkedCommentId}
commentingEnabled={commentingEnabled}
supportAmount={comment.support_amount}
numDirectReplies={comment.replies}
isModerator={comment.is_moderator}
isGlobalMod={comment.is_global_mod}
/>
);
})}
</ul>
</div>
</div>
)}
{isExpanded && fetchedReplies && hasMore && (
<div className="comment__actions--nested">
<Button button="link" label={__('Show more')} onClick={showMore} className="button--uri-indicator" />
</div>
)}
{isFetchingByParentId[parentId] && (
<div className="comment__replies-container">
<div className="comment__actions--nested">
<Spinner type="small" />
</div>
</div>
)}
</div>
)
);
}
export default CommentsReplies;