2020-03-18 22:14:11 +01:00
// @flow
import * as ICONS from 'constants/icons' ;
import * as PAGES from 'constants/pages' ;
import React from 'react' ;
import { Lbryio } from 'lbryinc' ;
import ClaimPreview from 'component/claimPreview' ;
import Card from 'component/common/card' ;
import Spinner from 'component/spinner' ;
import Icon from 'component/common/icon' ;
import Button from 'component/button' ;
import Yrbl from 'component/yrbl' ;
import { useHistory } from 'react-router-dom' ;
2020-03-19 17:00:15 +01:00
import analytics from 'analytics' ;
2020-03-18 22:14:11 +01:00
type Props = {
2020-04-22 21:07:38 +02:00
claim : ? ChannelClaim ,
2020-03-18 22:14:11 +01:00
fetchingChannels : boolean ,
prepareEdit : string => void ,
} ;
2020-04-22 21:07:38 +02:00
const UNAUTHENTICATED _ERROR = 'unauthenticated' ;
const GENERIC _ERROR = 'error' ;
2020-03-19 15:38:20 +01:00
export default function CreatorAnalytics ( props : Props ) {
2020-04-22 21:07:38 +02:00
const { prepareEdit , claim } = props ;
2020-03-18 22:14:11 +01:00
const history = useHistory ( ) ;
const [ stats , setStats ] = React . useState ( ) ;
2020-04-22 21:07:38 +02:00
const [ error , setError ] = React . useState ( ) ;
2020-03-18 22:14:11 +01:00
const [ fetchingStats , setFetchingStats ] = React . useState ( false ) ;
2020-04-22 21:07:38 +02:00
const claimId = claim && claim . claim _id ;
const channelHasClaims = claim && claim . meta && claim . meta . claims _in _channel && claim . meta . claims _in _channel > 0 ;
2020-03-18 22:14:11 +01:00
React . useEffect ( ( ) => {
2020-04-22 21:07:38 +02:00
setStats ( null ) ;
} , [ claimId ] ) ;
2020-03-18 22:14:11 +01:00
2020-04-22 21:07:38 +02:00
const channelForEffect = JSON . stringify ( claim ) ;
2020-03-18 22:14:11 +01:00
React . useEffect ( ( ) => {
2020-04-23 22:38:09 +02:00
if ( claimId && channelForEffect && channelHasClaims ) {
2020-03-18 22:14:11 +01:00
setFetchingStats ( true ) ;
2020-04-22 21:07:38 +02:00
Lbryio . call ( 'reports' , 'content' , { claim _id : claimId } )
2020-03-18 22:14:11 +01:00
. then ( res => {
setFetchingStats ( false ) ;
setStats ( res ) ;
} )
2020-04-22 21:07:38 +02:00
. catch ( error => {
if ( error . response . status === 401 ) {
setError ( UNAUTHENTICATED _ERROR ) ;
const channelToSend = JSON . parse ( channelForEffect ) ;
analytics . apiLogPublish ( channelToSend ) ;
} else {
setError ( GENERIC _ERROR ) ;
}
2020-03-18 22:14:11 +01:00
setFetchingStats ( false ) ;
} ) ;
}
2020-04-23 22:38:09 +02:00
} , [ claimId , channelForEffect , channelHasClaims , setFetchingStats , setStats ] ) ;
2020-03-18 22:14:11 +01:00
return (
< React.Fragment >
2020-04-22 21:07:38 +02:00
{ ! stats && (
2020-03-18 22:14:11 +01:00
< div className = "main--empty" >
2020-04-22 21:07:38 +02:00
{ fetchingStats ? (
< Spinner delayed / >
) : (
< div >
{ error && (
< Yrbl
type = "sad"
2020-08-26 22:28:33 +02:00
title = { error === GENERIC _ERROR ? _ _ ( 'No stats found' ) : _ _ ( 'Error fetching stats' ) }
2020-04-22 21:07:38 +02:00
subtitle = {
error === GENERIC _ERROR
? _ _ (
2020-05-22 03:19:01 +02:00
'There are no stats for this channel yet, it will take a few views. Make sure you are signed in with the correct email and have data sharing turned on.'
2020-04-22 21:07:38 +02:00
)
: _ _ (
"You are not able to see this channel's stats. Make sure you are signed in with the correct email and have data sharing turned on."
)
2020-03-18 22:14:11 +01:00
}
2020-04-22 21:07:38 +02:00
/ >
) }
{ ! error && (
< Yrbl
title = {
channelHasClaims
2020-07-23 19:02:07 +02:00
? _ _ ( 'No recent uploads' )
: _ _ ( "You haven't uploaded anything with this channel yet!" )
2020-04-22 21:07:38 +02:00
}
2020-09-02 22:08:37 +02:00
actions = {
< div className = "section__actions" >
< Button
button = "primary"
label = { _ _ ( 'Upload Something' ) }
onClick = { ( ) => {
if ( claim ) {
prepareEdit ( claim . name ) ;
history . push ( ` / $ / ${ PAGES . UPLOAD } ` ) ;
}
} }
/ >
< / div >
2020-04-22 21:07:38 +02:00
}
/ >
) }
< / div >
) }
< / div >
2020-03-18 22:14:11 +01:00
) }
2020-04-22 21:07:38 +02:00
2020-03-18 22:14:11 +01:00
{ stats && (
< div className = "section" >
< div className = "columns" >
< Card
iconColor
2020-04-22 21:07:38 +02:00
title = { < span > { _ _ ( '%follower_count% followers' , { follower _count : stats . ChannelSubs } ) } < / span > }
2020-03-18 22:14:11 +01:00
icon = { ICONS . SUBSCRIBE }
subtitle = {
< div className = "card__data-subtitle" >
< span >
2020-03-19 17:42:43 +01:00
{ 0 > - 1 && '+' } { ' ' }
2020-03-19 15:38:20 +01:00
{ _ _ ( '%follower_count_weekly_change% this week' , {
follower _count _weekly _change : stats . ChannelSubChange || 0 ,
} ) }
2020-03-18 22:14:11 +01:00
< / span >
2020-06-08 20:42:29 +02:00
{ stats . ChannelSubChange > 0 && < Icon icon = { ICONS . TRENDING } iconColor = "green" size = { 18 } / > }
2020-03-18 22:14:11 +01:00
< / div >
}
/ >
< Card
icon = { ICONS . EYE }
2020-03-19 15:38:20 +01:00
title = { < span > { _ _ ( '%all_content_views% views' , { all _content _views : stats . AllContentViews } ) } < / span > }
subtitle = {
2020-03-19 17:42:43 +01:00
< div className = "card__data-subtitle" >
< span >
{ _ _ ( '+ %all_content_views_weekly_change% this week' , {
all _content _views _weekly _change : stats . AllContentViewChange || 0 ,
} ) }
< / span >
2020-06-08 20:42:29 +02:00
{ stats . AllContentViewChange > 0 && < Icon icon = { ICONS . TRENDING } iconColor = "green" size = { 18 } / > }
2020-03-19 17:42:43 +01:00
< / div >
2020-03-19 15:38:20 +01:00
}
2020-03-18 22:14:11 +01:00
/ >
< / div >
2020-04-23 23:40:58 +02:00
{ / * < C a r d
2020-04-22 21:07:38 +02:00
iconColor
className = "section"
2020-09-02 22:08:37 +02:00
title = { < span > { _ _ ( '%lbc_received% LBRY Credits Earned' , { lbc _received : stats . AllLBCReceived } ) } < / span > }
2020-04-23 18:15:51 +02:00
icon = { ICONS . REWARDS }
2020-04-22 21:07:38 +02:00
subtitle = {
< React.Fragment >
< div className = "card__data-subtitle" >
< span >
{ '+' } { ' ' }
{ _ _ ( '%lbc_received_changed% this week' , {
lbc _received _changed : stats . LBCReceivedChange || 0 ,
} ) }
< / span >
2020-06-08 20:42:29 +02:00
{ stats . LBCReceivedChange > 0 && < Icon icon = { ICONS . TRENDING } iconColor = "green" size = { 18 } / > }
2020-04-22 21:07:38 +02:00
< / div >
< p className = "help" >
{ _ _ (
"Earnings may also include any LBC you've sent yourself or added as support. We are working on making this more accurate. Check your wallet page for the correct total balance."
) }
< / p >
< / React.Fragment >
2020-03-18 22:14:11 +01:00
}
2020-04-23 23:40:58 +02:00
/> */ }
2020-04-22 21:07:38 +02:00
{ stats . VideoURITopNew ? (
< Card
className = "section"
2020-08-26 22:28:33 +02:00
title = { _ _ ( 'Most viewed recent content' ) }
2020-04-22 21:07:38 +02:00
body = {
< React.Fragment >
< div className = "card--inline" >
2020-04-23 22:38:09 +02:00
< ClaimPreview uri = { stats . VideoURITopNew } / >
2020-04-22 21:07:38 +02:00
< / div >
< div className = "section__subtitle card__data-subtitle" >
< span >
2020-05-26 14:49:21 +02:00
{ stats . VideoViewsTopNew === 1
2020-08-27 22:31:22 +02:00
? _ _ ( '1 view' )
: _ _ ( '%view_count% views - %view_count_change% this week' , {
view _count : stats . VideoViewsTopNew ,
view _count _change : stats . VideoViewChangeTopNew ,
} ) }
2020-04-22 21:07:38 +02:00
< / span >
2020-08-27 22:31:22 +02:00
{ stats . VideoViewChangeTopNew > 0 && < Icon icon = { ICONS . TRENDING } iconColor = "green" size = { 18 } / > }
2020-04-22 21:07:38 +02:00
< / div >
< / React.Fragment >
}
/ >
) : (
< Card
className = "section"
2020-08-26 22:28:33 +02:00
title = { _ _ ( 'Your recent content' ) }
2020-04-22 21:07:38 +02:00
subtitle = {
! stats . VideoURITopNew &&
2020-07-23 19:02:07 +02:00
_ _ ( "No recent uploads found for this channel. Upload something new and track how it's performing here." )
2020-04-22 21:07:38 +02:00
}
actions = {
< div className = "section__actions" >
< Button
button = "primary"
2020-05-31 15:56:33 +02:00
icon = { ICONS . PUBLISH }
2020-07-23 19:02:07 +02:00
label = { _ _ ( 'Upload' ) }
2020-04-22 21:07:38 +02:00
onClick = { ( ) => {
if ( claim ) {
prepareEdit ( claim . name ) ;
2020-07-23 19:02:07 +02:00
history . push ( ` / $ / ${ PAGES . UPLOAD } ` ) ;
2020-04-22 21:07:38 +02:00
}
} }
/ >
< / div >
}
/ >
) }
2020-08-27 22:31:22 +02:00
{ stats . VideoURITopCommentNew && stats . VideoCommentTopCommentNew > 0 && (
< Card
className = "section"
title = { _ _ ( 'Most Commented Recent Content' ) }
body = {
< React.Fragment >
< div className = "card--inline" >
< ClaimPreview uri = { stats . VideoURITopCommentNew } / >
< / div >
< div className = "section__subtitle card__data-subtitle" >
< span >
{ stats . VideoCommentTopCommentNew === 1
? _ _ ( '1 comment' )
: _ _ ( '%comment_count% comments - %comment_count_change% this week' , {
comment _count : stats . VideoCommentTopCommentNew ,
comment _count _change : stats . VideoCommentChangeTopCommentNew ,
} ) }
< / span >
{ stats . VideoCommentChangeTopCommentNew > 0 && (
< Icon icon = { ICONS . TRENDING } iconColor = "green" size = { 18 } / >
) }
< / div >
< / React.Fragment >
}
/ >
) }
2020-04-22 21:07:38 +02:00
< Card
className = "section"
2020-08-26 22:28:33 +02:00
title = { _ _ ( 'Most viewed content all time' ) }
2020-03-18 22:14:11 +01:00
body = {
< React.Fragment >
< div className = "card--inline" >
2020-03-19 15:38:20 +01:00
< ClaimPreview uri = { stats . VideoURITopAllTime } / >
< / div >
< div className = "section__subtitle card__data-subtitle" >
< span >
{ _ _ ( '%all_time_top_views% views - %all_time_views_weekly_change% this week' , {
all _time _top _views : stats . VideoViewsTopAllTime ,
all _time _views _weekly _change : stats . VideoViewChangeTopAllTime ,
} ) }
< / span >
2020-06-08 20:42:29 +02:00
{ stats . VideoViewChangeTopAllTime > 0 && < Icon icon = { ICONS . TRENDING } iconColor = "green" size = { 18 } / > }
2020-03-18 22:14:11 +01:00
< / div >
< / React.Fragment >
}
/ >
< / div >
) }
< / React.Fragment >
) ;
}