lbry-desktop/ui/component/commentsReplies/view.jsx
infinite-persistence 5742e1c2ca
Handle representation of blocked replies
## Issue
- `Comment.replies` currently represent all replies, while `comment.List` returns a filtered version, so the actual replies could be less.
- The actual replies is represented by `total_filtered_items`, but we only get that after making a fetch. So, users could click "Show more" but get nothing.

## Fix
- Stop showing "Show more" based on `total_filtered_items`.
- If there is a balance, display 1 dummy comment to represent all blocked replies. This handles the case of "Show more" being displayed but ended up with 0 replies if all replies were blocked.

## Future
Note that `Comment.replies` might be changed to represented filtered comments in the near future (refer to Beamer), so the GUI is made such that the dummy just won't appear when that change happens.
2021-07-14 15:11:44 +08:00

140 lines
4.5 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';
import ChannelThumbnail from 'component/channelThumbnail';
type Props = {
fetchedReplies: Array<any>,
totalReplies: number,
uri: string,
parentId: string,
claimIsMine: boolean,
myChannels: ?Array<ChannelClaim>,
linkedCommentId?: string,
commentingEnabled: boolean,
threadDepth: number,
numDirectReplies: number,
isFetchingByParentId: { [string]: boolean },
onShowMore?: () => void,
};
function CommentsReplies(props: Props) {
const {
uri,
parentId,
fetchedReplies,
totalReplies,
claimIsMine,
myChannels,
linkedCommentId,
commentingEnabled,
threadDepth,
numDirectReplies,
isFetchingByParentId,
onShowMore,
} = 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>
)}
{fetchedReplies && displayedComments && isExpanded && (
<div>
<div className="comment__replies">
<Button className="comment__threadline" aria-label="Hide Replies" onClick={() => setExpanded(false)} />
<ul className="comments--replies">
{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}
/>
);
})}
{totalReplies < numDirectReplies && (
<li className="comment comment--reply">
<div className="comment__content">
<div className="comment__thumbnail-wrapper">
<ChannelThumbnail xsmall className="comment__author-thumbnail" />
</div>
<div className="comment__body-container comment--blocked">
<div className="comment__meta">
<em>---</em>
</div>
<div>
<em>{__('Comment(s) blocked.')}</em>
</div>
</div>
</div>
</li>
)}
</ul>
</div>
</div>
)}
{isExpanded && fetchedReplies && displayedComments.length < totalReplies && (
<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;