diff --git a/src/index.js b/src/index.js index 01db9eb..74b01f0 100644 --- a/src/index.js +++ b/src/index.js @@ -27,6 +27,7 @@ import { homepageReducer, rewardsReducer, selectUserVerifiedEmail, + statsReducer, subscriptionsReducer, syncReducer, userReducer, @@ -141,6 +142,7 @@ const reducers = persistCombineReducers(persistOptions, { rewards: rewardsReducer, settings: settingsReducer, search: searchReducer, + stats: statsReducer, subscriptions: subscriptionsReducer, sync: syncReducer, tags: tagsReducer, diff --git a/src/page/channel/index.js b/src/page/channel/index.js index 42c42cf..59d6fc2 100644 --- a/src/page/channel/index.js +++ b/src/page/channel/index.js @@ -1,5 +1,6 @@ import { connect } from 'react-redux'; import { doAbandonClaim, doFetchChannelListMine, makeSelectClaimForUri, selectMyChannelClaims } from 'lbry-redux'; +import { doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc'; import { doPopDrawerStack } from 'redux/actions/drawer'; import { doSetSortByItem, doSetTimeItem } from 'redux/actions/settings'; import { selectDrawerStack } from 'redux/selectors/drawer'; @@ -11,12 +12,14 @@ const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), drawerStack: selectDrawerStack(state), sortByItem: selectSortByItem(state), + subCount: makeSelectSubCountForUri(props.uri)(state), timeItem: selectTimeItem(state), }); const perform = dispatch => ({ abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)), fetchChannelListMine: () => dispatch(doFetchChannelListMine()), + fetchSubCount: claimId => dispatch(doFetchSubCount(claimId)), popDrawerStack: () => dispatch(doPopDrawerStack()), setSortByItem: item => dispatch(doSetSortByItem(item)), setTimeItem: item => dispatch(doSetTimeItem(item)), diff --git a/src/page/channel/view.js b/src/page/channel/view.js index 3f15e5f..40c13ec 100644 --- a/src/page/channel/view.js +++ b/src/page/channel/view.js @@ -49,9 +49,12 @@ class ChannelPage extends React.PureComponent { } componentDidMount() { - const { fetchChannelListMine } = this.props; + const { claim, fetchChannelListMine, fetchSubCount } = this.props; NativeModules.Firebase.setCurrentScreen('Channel'); fetchChannelListMine(); + if (claim) { + fetchSubCount(claim.claim_id); + } } handleSortByItemSelected = item => { @@ -207,7 +210,7 @@ class ChannelPage extends React.PureComponent { }; render() { - const { channels, claim, navigation, uri, drawerStack, popDrawerStack, timeItem } = this.props; + const { channels, claim, navigation, uri, drawerStack, popDrawerStack, subCount, timeItem } = this.props; const { name, permanent_url: permanentUrl } = claim; const { autoStyle, currentSortByItem, showSortPicker, showTimePicker } = this.state; const ownedChannel = channels ? channels.map(channel => channel.permanent_url).includes(permanentUrl) : false; @@ -252,6 +255,10 @@ class ChannelPage extends React.PureComponent { {title && title.trim().length > 0 ? title : name} + + {subCount === 1 && __('%follower% follower', { follower: subCount })} + {subCount > 1 && __('%follower% followers', { follower: subCount })} + diff --git a/src/page/file/index.js b/src/page/file/index.js index 71a9ddc..263b305 100644 --- a/src/page/file/index.js +++ b/src/page/file/index.js @@ -33,7 +33,9 @@ import { import { doClaimEligiblePurchaseRewards, doFetchCostInfoForUri, + doFetchViewCount, makeSelectCostInfoForUri, + makeSelectViewCountForUri, selectRewardContentClaimIds, selectBlackListedOutpoints, } from 'lbryinc'; @@ -76,6 +78,7 @@ const select = (state, props) => { title: makeSelectTitleForUri(contentUri)(state), recommendedContent: makeSelectRecommendedContentForUri(contentUri)(state), isSearchingRecommendContent: selectIsSearching(state), + viewCount: makeSelectViewCountForUri(contentUri)(state), }; }; @@ -89,6 +92,7 @@ const perform = dispatch => ({ fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)), fetchMyClaims: () => dispatch(doFetchClaimListMine()), fetchChannelListMine: () => dispatch(doFetchChannelListMine()), + fetchViewCount: claimId => dispatch(doFetchViewCount(claimId)), fileGet: (uri, saveFile) => dispatch(doFileGet(uri, saveFile)), notify: data => dispatch(doToast(data)), popDrawerStack: () => dispatch(doPopDrawerStack()), diff --git a/src/page/file/view.js b/src/page/file/view.js index ac6b747..a151fbd 100644 --- a/src/page/file/view.js +++ b/src/page/file/view.js @@ -69,6 +69,7 @@ class FilePage extends React.PureComponent { creditsInputFocused: false, downloadButtonShown: false, downloadPressed: false, + didSearchRecommended: false, fileViewLogged: false, fullscreenMode: false, fileGetStarted: false, @@ -89,7 +90,7 @@ class FilePage extends React.PureComponent { uriVars: null, stopDownloadConfirmed: false, streamingMode: false, - didSearchRecommended: false, + viewCountFetched: false, }; } @@ -116,6 +117,7 @@ class FilePage extends React.PureComponent { this.fetchFileInfo(this.props); this.fetchCostInfo(this.props); + fetchMyClaims(); if (NativeModules.Firebase) { @@ -146,6 +148,7 @@ class FilePage extends React.PureComponent { claim, currentRoute, failedPurchaseUris: prevFailedPurchaseUris, + fetchViewCount, purchasedUris: prevPurchasedUris, navigation, contentType, @@ -211,6 +214,10 @@ class FilePage extends React.PureComponent { showWebView: false, }); } + + if (claim && !this.state.viewCountFetched) { + this.setState({ viewCountFetched: true }, () => fetchViewCount(claim.claim_id)); + } } componentDidUpdate(prevProps) { @@ -727,6 +734,7 @@ class FilePage extends React.PureComponent { recommendedContent, thumbnail, title, + viewCount, } = this.props; const { uri, autoplay } = navigation.state.params; @@ -1014,14 +1022,20 @@ class FilePage extends React.PureComponent { style={filePageStyle.titleTouch} onPress={() => this.setState({ showDescription: !this.state.showDescription })} > - - - {title} - - {isRewardContent && } - - + + + + {title} + + {isRewardContent && } + + + + + {viewCount === 1 && __('%view% view', { view: viewCount })} + {viewCount > 1 && __('%view% views', { view: viewCount })} + diff --git a/src/styles/channelPage.js b/src/styles/channelPage.js index ba27579..9de0bda 100644 --- a/src/styles/channelPage.js +++ b/src/styles/channelPage.js @@ -145,7 +145,7 @@ const channelPageStyle = StyleSheet.create({ position: 'absolute', overflow: 'hidden', left: 24, - bottom: -40, + bottom: -24, zIndex: 100, alignItems: 'center', justifyContent: 'center', @@ -176,6 +176,12 @@ const channelPageStyle = StyleSheet.create({ marginLeft: 8, marginRight: 8, }, + followerCount: { + fontFamily: 'Inter-UI-Regular', + fontSize: 12, + color: Colors.White, + marginTop: 2, + }, }); export default channelPageStyle; diff --git a/src/styles/filePage.js b/src/styles/filePage.js index ec39ac7..9c29db6 100644 --- a/src/styles/filePage.js +++ b/src/styles/filePage.js @@ -446,6 +446,13 @@ const filePageStyle = StyleSheet.create({ relatedLoading: { marginTop: 16, }, + viewCount: { + fontFamily: 'Inter-UI-Regular', + fontSize: 12, + color: Colors.DescriptionGrey, + marginLeft: 12, + marginRight: 12, + }, balance: { alignItems: 'center', flexDirection: 'row',