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.
This commit is contained in:
parent
4731588a3c
commit
5742e1c2ca
5 changed files with 42 additions and 7 deletions
|
@ -1514,6 +1514,7 @@
|
||||||
"Create A Channel": "Create A Channel",
|
"Create A Channel": "Create A Channel",
|
||||||
"At least 10 views are required to earn the reward, consume more!": "At least 10 views are required to earn the reward, consume more!",
|
"At least 10 views are required to earn the reward, consume more!": "At least 10 views are required to earn the reward, consume more!",
|
||||||
"Blocked %channel%": "Blocked %channel%",
|
"Blocked %channel%": "Blocked %channel%",
|
||||||
|
"Comment(s) blocked.": "Comment(s) blocked.",
|
||||||
"You earned %lbc% for streaming your first video.": "You earned %lbc% for streaming your first video.",
|
"You earned %lbc% for streaming your first video.": "You earned %lbc% for streaming your first video.",
|
||||||
"You earned %lbc% for successfully completing The Journey L4: Perfect Harmony.": "You earned %lbc% for successfully completing The Journey L4: Perfect Harmony.",
|
"You earned %lbc% for successfully completing The Journey L4: Perfect Harmony.": "You earned %lbc% for successfully completing The Journey L4: Perfect Harmony.",
|
||||||
"You earned %lbc% for successfully completing The Journey L3: Bliss.": "You earned %lbc% for successfully completing The Journey L3: Bliss.",
|
"You earned %lbc% for successfully completing The Journey L3: Bliss.": "You earned %lbc% for successfully completing The Journey L3: Bliss.",
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectClaimIsMine, selectMyChannelClaims } from 'lbry-redux';
|
import { makeSelectClaimIsMine, selectMyChannelClaims } from 'lbry-redux';
|
||||||
import { selectIsFetchingCommentsByParentId, makeSelectRepliesForParentId } from 'redux/selectors/comments';
|
import {
|
||||||
|
selectIsFetchingCommentsByParentId,
|
||||||
|
makeSelectRepliesForParentId,
|
||||||
|
makeSelectTotalRepliesForParentId,
|
||||||
|
} from 'redux/selectors/comments';
|
||||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||||
import CommentsReplies from './view';
|
import CommentsReplies from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
comments: makeSelectRepliesForParentId(props.parentId)(state),
|
fetchedReplies: makeSelectRepliesForParentId(props.parentId)(state),
|
||||||
|
totalReplies: makeSelectTotalRepliesForParentId(props.parentId)(state),
|
||||||
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
|
||||||
commentingEnabled: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true,
|
commentingEnabled: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true,
|
||||||
myChannels: selectMyChannelClaims(state),
|
myChannels: selectMyChannelClaims(state),
|
||||||
|
|
|
@ -4,9 +4,11 @@ import React from 'react';
|
||||||
import Comment from 'component/comment';
|
import Comment from 'component/comment';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
|
import ChannelThumbnail from 'component/channelThumbnail';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
comments: Array<any>,
|
fetchedReplies: Array<any>,
|
||||||
|
totalReplies: number,
|
||||||
uri: string,
|
uri: string,
|
||||||
parentId: string,
|
parentId: string,
|
||||||
claimIsMine: boolean,
|
claimIsMine: boolean,
|
||||||
|
@ -23,7 +25,8 @@ function CommentsReplies(props: Props) {
|
||||||
const {
|
const {
|
||||||
uri,
|
uri,
|
||||||
parentId,
|
parentId,
|
||||||
comments,
|
fetchedReplies,
|
||||||
|
totalReplies,
|
||||||
claimIsMine,
|
claimIsMine,
|
||||||
myChannels,
|
myChannels,
|
||||||
linkedCommentId,
|
linkedCommentId,
|
||||||
|
@ -54,7 +57,7 @@ function CommentsReplies(props: Props) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const displayedComments = comments;
|
const displayedComments = fetchedReplies;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
Boolean(numDirectReplies) && (
|
Boolean(numDirectReplies) && (
|
||||||
|
@ -69,7 +72,7 @@ function CommentsReplies(props: Props) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{comments && displayedComments && isExpanded && (
|
{fetchedReplies && displayedComments && isExpanded && (
|
||||||
<div>
|
<div>
|
||||||
<div className="comment__replies">
|
<div className="comment__replies">
|
||||||
<Button className="comment__threadline" aria-label="Hide Replies" onClick={() => setExpanded(false)} />
|
<Button className="comment__threadline" aria-label="Hide Replies" onClick={() => setExpanded(false)} />
|
||||||
|
@ -96,11 +99,28 @@ function CommentsReplies(props: Props) {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
{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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isExpanded && comments && displayedComments.length < numDirectReplies && (
|
{isExpanded && fetchedReplies && displayedComments.length < totalReplies && (
|
||||||
<div className="comment__actions--nested">
|
<div className="comment__actions--nested">
|
||||||
<Button button="link" label={__('Show more')} onClick={showMore} className="button--uri-indicator" />
|
<Button button="link" label={__('Show more')} onClick={showMore} className="button--uri-indicator" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -356,6 +356,11 @@ export const makeSelectRepliesForParentId = (id: string) =>
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const makeSelectTotalRepliesForParentId = (parentId: string) =>
|
||||||
|
createSelector(selectState, (state) => {
|
||||||
|
return state.totalRepliesByParentId[parentId] || 0;
|
||||||
|
});
|
||||||
|
|
||||||
export const makeSelectTotalCommentsCountForUri = (uri: string) =>
|
export const makeSelectTotalCommentsCountForUri = (uri: string) =>
|
||||||
createSelector(selectState, selectCommentsByUri, (state, byUri) => {
|
createSelector(selectState, selectCommentsByUri, (state, byUri) => {
|
||||||
const claimId = byUri[uri];
|
const claimId = byUri[uri];
|
||||||
|
|
|
@ -441,3 +441,7 @@ $thumbnailWidthSmall: 1rem;
|
||||||
.comment__tip-input {
|
.comment__tip-input {
|
||||||
margin: var(--spacing-s) 0;
|
margin: var(--spacing-s) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.comment--blocked {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue