add reward rate + analytics link on channels page

This commit is contained in:
Sean Yesmunt 2020-10-12 17:12:46 -04:00
parent 65c39cbbc8
commit 4815aa9ff1
7 changed files with 87 additions and 3 deletions

View file

@ -36,6 +36,7 @@ type Props = {
injectedItem: ?Node,
timedOutMessage?: Node,
tileLayout?: boolean,
renderActions?: Claim => ?Node,
};
export default function ClaimList(props: Props) {
@ -59,6 +60,7 @@ export default function ClaimList(props: Props) {
injectedItem,
timedOutMessage,
tileLayout = false,
renderActions,
} = props;
const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW);
@ -147,6 +149,7 @@ export default function ClaimList(props: Props) {
includeSupportAction={includeSupportAction}
showUnresolvedClaim={showUnresolvedClaims}
properties={renderProperties || (type !== 'small' ? undefined : false)}
renderActions={renderActions}
showUserBlocked={showHiddenByUser}
hideBlock={hideBlock}
customShouldHide={(claim: StreamClaim) => {

View file

@ -59,6 +59,8 @@ type Props = {
customShouldHide?: Claim => boolean,
showUnresolvedClaim?: boolean,
includeSupportAction?: boolean,
hideActions?: boolean,
renderActions?: Claim => ?Node,
};
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
@ -91,12 +93,14 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
customShouldHide,
showUnresolvedClaim,
includeSupportAction,
hideActions = false,
renderActions,
} = props;
const shouldFetch =
claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending);
const abandoned = !isResolvingUri && !claim;
const showPublishLink = abandoned && !showUnresolvedClaim && placeholder === 'publish';
const hideActions = type === 'small' || type === 'tooltip';
const shouldHideActions = hideActions || type === 'small' || type === 'tooltip';
const canonicalUrl = claim && claim.canonical_url;
let isValid = false;
if (uri) {
@ -286,7 +290,8 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
<div className="claim-preview__actions">
{!pending && (
<>
{hideActions ? null : actions !== undefined ? (
{renderActions && claim && renderActions(claim)}
{shouldHideActions || renderActions ? null : actions !== undefined ? (
actions
) : (
<div className="claim-preview__primary-actions">

View file

@ -26,7 +26,7 @@ export default function CreatorAnalytics(props: Props) {
const history = useHistory();
const [stats, setStats] = React.useState();
const [error, setError] = React.useState();
const [fetchingStats, setFetchingStats] = React.useState(false);
const [fetchingStats, setFetchingStats] = React.useState(true);
const claimId = claim && claim.claim_id;
const channelHasClaims = claim && claim.meta && claim.meta.claims_in_channel && claim.meta.claims_in_channel > 0;

View file

@ -1,12 +1,14 @@
// @flow
import * as ICONS from 'constants/icons';
import React, { useEffect } from 'react';
import { Lbryio } from 'lbryinc';
import ClaimList from 'component/claimList';
import Page from 'component/page';
import Button from 'component/button';
import YoutubeTransferStatus from 'component/youtubeTransferStatus';
import Spinner from 'component/spinner';
import Yrbl from 'component/yrbl';
import LbcSymbol from 'component/common/lbc-symbol';
import * as PAGES from 'constants/pages';
type Props = {
@ -19,6 +21,7 @@ type Props = {
export default function ChannelsPage(props: Props) {
const { channels, channelUrls, fetchChannelListMine, fetchingChannels, youtubeChannels } = props;
const [rewardData, setRewardData] = React.useState();
const hasYoutubeChannels = youtubeChannels && Boolean(youtubeChannels.length);
const hasPendingChannels = channels && channels.some(channel => channel.confirmations < 0);
@ -26,6 +29,10 @@ export default function ChannelsPage(props: Props) {
fetchChannelListMine();
}, [fetchChannelListMine, hasPendingChannels]);
useEffect(() => {
Lbryio.call('user_rewards', 'view_rate').then(data => setRewardData(data));
}, [setRewardData]);
return (
<Page>
<div className="card-stack">
@ -44,6 +51,44 @@ export default function ChannelsPage(props: Props) {
}
loading={fetchingChannels}
uris={channelUrls}
renderActions={claim => {
const claimsInChannel = claim.meta.claims_in_channel;
return claimsInChannel === 0 ? (
<span />
) : (
<div className="section__actions">
<Button
button="alt"
icon={ICONS.ANALYTICS}
label={__('Analytics')}
navigate={`/$/${PAGES.CREATOR_DASHBOARD}?channel=${encodeURIComponent(claim.canonical_url)}`}
/>
</div>
);
}}
renderProperties={claim => {
const claimsInChannel = claim.meta.claims_in_channel;
if (!claim || claimsInChannel === 0) {
return null;
}
const channelRewardData =
rewardData &&
rewardData.rates.find(data => {
return data.channel_claim_id === claim.claim_id;
});
if (channelRewardData) {
return (
<span className="claim-preview__custom-properties">
<span className="help--inline">{__('Earnings per view')}</span>
<LbcSymbol postfix={channelRewardData.view_rate.toFixed(2)} />
</span>
);
} else {
return null;
}
}}
/>
)}
</div>

View file

@ -8,14 +8,23 @@ import CreatorAnalytics from 'component/creatorAnalytics';
import ChannelSelector from 'component/channelSelector';
import usePersistedState from 'effects/use-persisted-state';
import Yrbl from 'component/yrbl';
import { useHistory } from 'react-router';
type Props = {
channels: Array<ChannelClaim>,
fetchingChannels: boolean,
};
const SELECTED_CHANNEL_QUERY_PARAM = 'channel';
export default function CreatorDashboardPage(props: Props) {
const { channels, fetchingChannels } = props;
const {
push,
location: { search, pathname },
} = useHistory();
const urlParams = new URLSearchParams(search);
const channelFromUrl = urlParams.get(SELECTED_CHANNEL_QUERY_PARAM);
const [selectedChannelUrl, setSelectedChannelUrl] = usePersistedState('analytics-selected-channel');
const hasChannels = channels && channels.length > 0;
const firstChannel = hasChannels && channels[0];
@ -33,6 +42,19 @@ export default function CreatorDashboardPage(props: Props) {
}
}, [setSelectedChannelUrl, selectedChannelUrl, firstChannelUrl, channelFoundForSelectedChannelUrl]);
React.useEffect(() => {
if (channelFromUrl) {
const decodedChannel = decodeURIComponent(channelFromUrl);
setSelectedChannelUrl(decodedChannel);
}
}, [channelFromUrl, setSelectedChannelUrl]);
function updateUrl(channelUrl) {
const newUrlParams = new URLSearchParams();
newUrlParams.append(SELECTED_CHANNEL_QUERY_PARAM, encodeURIComponent(channelUrl));
push(`${pathname}?${newUrlParams.toString()}`);
}
return (
<Page>
{fetchingChannels && (
@ -59,6 +81,7 @@ export default function CreatorDashboardPage(props: Props) {
<ChannelSelector
selectedChannelUrl={selectedChannelUrl}
onChannelSelect={newChannelUrl => {
updateUrl(newChannelUrl);
setSelectedChannelUrl(newChannelUrl);
}}
/>

View file

@ -200,6 +200,10 @@
color: var(--color-text);
}
.claim-preview__custom-properties {
text-align: right;
}
.claim-preview-metadata {
display: flex;
flex-direction: column;

View file

@ -230,6 +230,10 @@ textarea {
@extend .help;
margin-top: 0;
margin-bottom: 0;
&:not(:last-child) {
margin-bottom: 0;
}
}
.help--card-actions {