Add channel subscriptions count below author. (#6867)

* Add channel subscriptions count below author.

* Replace subscribers with followers

* Make sure subCount gets called only once in FileTitleSection.
This commit is contained in:
Franco Montenegro 2021-08-19 12:25:45 -03:00 committed by GitHub
parent 882c9ca022
commit 618b9a4d3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 5 deletions

View file

@ -2090,6 +2090,8 @@
"Expand Comments": "Expand Comments", "Expand Comments": "Expand Comments",
"Expand": "Expand", "Expand": "Expand",
"Load More": "Load More", "Load More": "Load More",
"%channelSubCount% Followers": "%channelSubCount% Followers",
"%channelSubCount% Follower": "%channelSubCount% Follower",
"Collection": "Collection", "Collection": "Collection",
"%channelName% isn't live right now, but the chat is! Check back later to watch the stream.": "%channelName% isn't live right now, but the chat is! Check back later to watch the stream.", "%channelName% isn't live right now, but the chat is! Check back later to watch the stream.": "%channelName% isn't live right now, but the chat is! Check back later to watch the stream.",
"Review": "Review", "Review": "Review",

View file

@ -5,13 +5,21 @@ import ClaimPreview from 'component/claimPreview';
type Props = { type Props = {
channelUri: string, channelUri: string,
hideActions?: boolean, hideActions?: boolean,
channelSubCount?: number,
}; };
function ClaimAuthor(props: Props) { function ClaimAuthor(props: Props) {
const { channelUri, hideActions } = props; const { channelUri, hideActions, channelSubCount } = props;
return channelUri ? ( return channelUri ? (
<ClaimPreview uri={channelUri} type="inline" properties={false} hideMenu hideActions={hideActions} /> <ClaimPreview
uri={channelUri}
type="inline"
properties={false}
hideMenu
hideActions={hideActions}
channelSubCount={channelSubCount}
/>
) : ( ) : (
<div className="claim-preview--inline claim-preview__title">{__('Anonymous')}</div> <div className="claim-preview--inline claim-preview__title">{__('Anonymous')}</div>
); );

View file

@ -91,6 +91,7 @@ type Props = {
date?: any, date?: any,
containerId?: string, // ID or name of the container (e.g. ClaimList, HOC, etc.) that this is in. containerId?: string, // ID or name of the container (e.g. ClaimList, HOC, etc.) that this is in.
indexInContainer?: number, // The index order of this component within 'containerId'. indexInContainer?: number, // The index order of this component within 'containerId'.
channelSubCount?: number,
}; };
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => { const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
@ -154,6 +155,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
disableNavigation, disableNavigation,
containerId, containerId,
indexInContainer, indexInContainer,
channelSubCount,
} = props; } = props;
const isCollection = claim && claim.value_type === 'collection'; const isCollection = claim && claim.value_type === 'collection';
const collectionClaimId = isCollection && claim && claim.claim_id; const collectionClaimId = isCollection && claim && claim.claim_id;
@ -166,6 +168,18 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip'; const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip';
const canonicalUrl = claim && claim.canonical_url; const canonicalUrl = claim && claim.canonical_url;
const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0; const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0;
const channelSubscribers = React.useMemo(() => {
if (channelSubCount === undefined) {
return <span />;
}
return (
<span className="claim-preview__channel-sub-count">
{channelSubCount === 1
? __('%channelSubCount% Follower', { channelSubCount })
: __('%channelSubCount% Followers', { channelSubCount })}
</span>
);
}, [channelSubCount]);
let isValid = false; let isValid = false;
if (uri) { if (uri) {
try { try {
@ -399,6 +413,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
</div> </div>
<ClaimPreviewSubtitle uri={uri} type={type} /> <ClaimPreviewSubtitle uri={uri} type={type} />
{(pending || !!reflectingProgress) && <PublishPending uri={uri} />} {(pending || !!reflectingProgress) && <PublishPending uri={uri} />}
{channelSubscribers}
</div> </div>
{type !== 'small' && ( {type !== 'small' && (
<div className="claim-preview__actions"> <div className="claim-preview__actions">

View file

@ -1,4 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc';
import { makeSelectTitleForUri, makeSelectClaimForUri } from 'lbry-redux'; import { makeSelectTitleForUri, makeSelectClaimForUri } from 'lbry-redux';
import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content'; import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content';
import { makeSelectViewersForId } from 'redux/selectors/livestream'; import { makeSelectViewersForId } from 'redux/selectors/livestream';
@ -7,11 +8,21 @@ import FileTitleSection from './view';
const select = (state, props) => { const select = (state, props) => {
const claim = makeSelectClaimForUri(props.uri)(state); const claim = makeSelectClaimForUri(props.uri)(state);
const viewers = claim && makeSelectViewersForId(claim.claim_id)(state); const viewers = claim && makeSelectViewersForId(claim.claim_id)(state);
const channelClaimId = claim && claim.signing_channel ? claim.signing_channel.claim_id : undefined;
const channelUri = claim && claim.signing_channel ? claim.signing_channel.canonical_url : undefined;
const subCount = channelUri && makeSelectSubCountForUri(channelUri)(state);
return { return {
viewers, viewers,
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state), title: makeSelectTitleForUri(props.uri)(state),
channelClaimId,
subCount,
}; };
}; };
export default connect(select)(FileTitleSection); const perform = (dispatch) => ({
fetchSubCount: (claimId) => dispatch(doFetchSubCount(claimId)),
});
export default connect(select, perform)(FileTitleSection);

View file

@ -23,12 +23,32 @@ type Props = {
livestream?: boolean, livestream?: boolean,
isLive?: boolean, isLive?: boolean,
viewers?: number, viewers?: number,
subCount: number,
channelClaimId?: string,
fetchSubCount: (string) => void,
}; };
function FileTitleSection(props: Props) { function FileTitleSection(props: Props) {
const { title, uri, nsfw, isNsfwBlocked, livestream = false, isLive = false, viewers } = props; const {
title,
uri,
nsfw,
isNsfwBlocked,
livestream = false,
isLive = false,
viewers,
subCount,
channelClaimId,
fetchSubCount,
} = props;
const [hasAcknowledgedSec, setHasAcknowledgedSec] = usePersistedState('sec-nag', false); const [hasAcknowledgedSec, setHasAcknowledgedSec] = usePersistedState('sec-nag', false);
React.useEffect(() => {
if (channelClaimId) {
fetchSubCount(channelClaimId);
}
}, [channelClaimId, fetchSubCount]);
return ( return (
<> <>
{!hasAcknowledgedSec && ( {!hasAcknowledgedSec && (
@ -108,7 +128,7 @@ function FileTitleSection(props: Props) {
</div> </div>
) : ( ) : (
<div className="section"> <div className="section">
<ClaimAuthor uri={uri} /> <ClaimAuthor channelSubCount={subCount} uri={uri} />
<FileDescription uri={uri} /> <FileDescription uri={uri} />
</div> </div>
) )

View file

@ -276,6 +276,11 @@
color: var(--color-text); color: var(--color-text);
} }
.claim-preview__channel-sub-count {
color: var(--color-text-subtitle);
font-size: var(--font-small);
}
.claim-preview__custom-properties { .claim-preview__custom-properties {
text-align: right; text-align: right;
display: flex; display: flex;