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',