tweak related content view for perf. fix displayed dates.

This commit is contained in:
Akinwale Ariwodola 2019-12-28 21:02:29 +01:00
parent d362d9e8dd
commit b8f2a9e24f
4 changed files with 234 additions and 203 deletions

View file

@ -1,25 +1,27 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
doResolveUris, doResolveUris,
doSearch,
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectRecommendedContentForUri, makeSelectRecommendedContentForUri,
makeSelectTitleForUri, selectResolvingUris,
selectIsSearching, selectIsSearching,
} from 'lbry-redux'; } from 'lbry-redux';
import RelatedContent from './view'; import RelatedContent from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state),
isSearching: selectIsSearching(state), isSearching: selectIsSearching(state),
recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state),
resolvingUris: selectResolvingUris(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
resolveUris: uris => dispatch(doResolveUris(uris)), resolveUris: uris => dispatch(doResolveUris(uris)),
searchRecommended: query => dispatch(doSearch(query, 20, undefined, true)),
}); });
export default connect( export default connect(
select, select,
perform perform,
)(RelatedContent); )(RelatedContent);

View file

@ -8,20 +8,54 @@ import fileListStyle from 'styles/fileList';
import relatedContentStyle from 'styles/relatedContent'; import relatedContentStyle from 'styles/relatedContent';
export default class RelatedContent extends React.PureComponent { export default class RelatedContent extends React.PureComponent {
state = {
resolveStarted: false,
};
componentDidMount() { componentDidMount() {
const { title, searchRecommended } = this.props;
if (title) {
searchRecommended(title);
}
}
shouldComponentUpdate(nextProps, nextState) {
const { isSearching, recommendedContent } = nextProps;
return isSearching || (!isSearching && this.allContentResolved());
}
allContentResolved() {
const { recommendedContent, resolvingUris } = this.props;
if (recommendedContent) {
let allResolved = true;
recommendedContent.forEach(uri => {
allResolved = allResolved && !resolvingUris.includes(uri);
});
return allResolved;
}
return false;
}
componentDidUpdate() {
const { resolveUris, recommendedContent } = this.props; const { resolveUris, recommendedContent } = this.props;
if (recommendedContent && recommendedContent.length > 0) { if (!this.state.resolveStarted) {
// batch resolve the uris this.setState({ resolveStarted: true }, () => {
resolveUris(recommendedContent); if (recommendedContent && recommendedContent.length > 0) {
// batch resolve the uris
resolveUris(recommendedContent);
}
});
} }
} }
render() { render() {
const { recommendedContent, navigation, uri, fullUri } = this.props; const { isSearching, recommendedContent, navigation, uri, fullUri } = this.props;
return ( return (
<View style={relatedContentStyle.container}> <View style={relatedContentStyle.container}>
<Text style={relatedContentStyle.title}>{__('Related Content')}</Text> <Text style={relatedContentStyle.title}>{__('Related Content')}</Text>
{isSearching && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />}
{recommendedContent && {recommendedContent &&
recommendedContent recommendedContent
.filter(recommendedUri => recommendedUri !== normalizeURI(fullUri)) .filter(recommendedUri => recommendedUri !== normalizeURI(fullUri))

View file

@ -9,7 +9,6 @@ import {
doDeletePurchasedUri, doDeletePurchasedUri,
doResolveUri, doResolveUri,
doResolveUris, doResolveUris,
doSearch,
doSendTip, doSendTip,
doToast, doToast,
makeSelectIsUriResolving, makeSelectIsUriResolving,
@ -19,7 +18,6 @@ import {
makeSelectContentPositionForUri, makeSelectContentPositionForUri,
makeSelectContentTypeForUri, makeSelectContentTypeForUri,
makeSelectMetadataForUri, makeSelectMetadataForUri,
makeSelectRecommendedContentForUri,
makeSelectStreamingUrlForUri, makeSelectStreamingUrlForUri,
makeSelectThumbnailForUri, makeSelectThumbnailForUri,
makeSelectTitleForUri, makeSelectTitleForUri,
@ -29,7 +27,6 @@ import {
selectPurchasedUris, selectPurchasedUris,
selectFailedPurchaseUris, selectFailedPurchaseUris,
selectPurchaseUriErrorMessage, selectPurchaseUriErrorMessage,
selectResolvingUris,
selectIsSearching, selectIsSearching,
} from 'lbry-redux'; } from 'lbry-redux';
import { import {
@ -72,8 +69,6 @@ const select = (state, props) => {
streamingUrl: makeSelectStreamingUrlForUri(contentUri)(state), streamingUrl: makeSelectStreamingUrlForUri(contentUri)(state),
thumbnail: makeSelectThumbnailForUri(contentUri)(state), thumbnail: makeSelectThumbnailForUri(contentUri)(state),
title: makeSelectTitleForUri(contentUri)(state), title: makeSelectTitleForUri(contentUri)(state),
recommendedContent: makeSelectRecommendedContentForUri(contentUri)(state),
resolvingUris: selectResolvingUris(state),
isSearchingRecommendContent: selectIsSearching(state), isSearchingRecommendContent: selectIsSearching(state),
viewCount: makeSelectViewCountForUri(contentUri)(state), viewCount: makeSelectViewCountForUri(contentUri)(state),
}; };
@ -98,7 +93,6 @@ const perform = dispatch => ({
deletePurchasedUri: uri => dispatch(doDeletePurchasedUri(uri)), deletePurchasedUri: uri => dispatch(doDeletePurchasedUri(uri)),
resolveUri: uri => dispatch(doResolveUri(uri)), resolveUri: uri => dispatch(doResolveUri(uri)),
resolveUris: uris => dispatch(doResolveUris(uris)), resolveUris: uris => dispatch(doResolveUris(uris)),
searchRecommended: query => dispatch(doSearch(query, 20, undefined, true)),
sendTip: (amount, claimId, isSupport, successCallback, errorCallback) => sendTip: (amount, claimId, isSupport, successCallback, errorCallback) =>
dispatch(doSendTip(amount, claimId, isSupport, successCallback, errorCallback)), dispatch(doSendTip(amount, claimId, isSupport, successCallback, errorCallback)),
setPlayerVisible: () => dispatch(doSetPlayerVisible(true)), setPlayerVisible: () => dispatch(doSetPlayerVisible(true)),
@ -108,5 +102,5 @@ const perform = dispatch => ({
export default connect( export default connect(
select, select,
perform perform,
)(FilePage); )(FilePage);

View file

@ -87,6 +87,7 @@ class FilePage extends React.PureComponent {
playerHeight: 0, playerHeight: 0,
uri: null, uri: null,
uriVars: null, uriVars: null,
showRecommended: false,
stopDownloadConfirmed: false, stopDownloadConfirmed: false,
streamingMode: false, streamingMode: false,
viewCountFetched: false, viewCountFetched: false,
@ -339,7 +340,7 @@ class FilePage extends React.PureComponent {
}, },
}, },
], ],
{ cancelable: true } { cancelable: true },
); );
}; };
@ -375,7 +376,7 @@ class FilePage extends React.PureComponent {
}, },
}, },
], ],
{ cancelable: true } { cancelable: true },
); );
}; };
@ -524,7 +525,6 @@ class FilePage extends React.PureComponent {
}; };
onPlaybackStarted = () => { onPlaybackStarted = () => {
const { searchRecommended, title } = this.props;
let timeToStartMillis, timeToStart; let timeToStartMillis, timeToStart;
if (this.startTime) { if (this.startTime) {
timeToStartMillis = Date.now() - this.startTime; timeToStartMillis = Date.now() - this.startTime;
@ -544,9 +544,7 @@ class FilePage extends React.PureComponent {
NativeModules.Firebase.track('play', payload); NativeModules.Firebase.track('play', payload);
// only fetch recommended content after playback has started // only fetch recommended content after playback has started
if (title) { this.setState({ showRecommended: true });
searchRecommended(title);
}
}; };
onPlaybackFinished = () => { onPlaybackFinished = () => {
@ -652,7 +650,7 @@ class FilePage extends React.PureComponent {
() => { () => {
purchaseUri(claim.permanent_url, costInfo, true); purchaseUri(claim.permanent_url, costInfo, true);
NativeModules.UtilityModule.checkDownloads(); NativeModules.UtilityModule.checkDownloads();
} },
); );
}; };
@ -689,7 +687,7 @@ class FilePage extends React.PureComponent {
], ],
showImageViewer: true, showImageViewer: true,
}, },
() => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW) () => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW),
); );
} }
} }
@ -700,7 +698,7 @@ class FilePage extends React.PureComponent {
{ {
showWebView: true, showWebView: true,
}, },
() => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW) () => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW),
); );
} }
} }
@ -737,6 +735,8 @@ class FilePage extends React.PureComponent {
const myChannelUris = channels ? channels.map(channel => channel.permanent_url) : []; const myChannelUris = channels ? channels.map(channel => channel.permanent_url) : [];
const ownedClaim = myClaimUris.includes(uri) || myChannelUris.includes(uri); const ownedClaim = myClaimUris.includes(uri) || myChannelUris.includes(uri);
console.log('calling render...');
let innerContent = null; let innerContent = null;
if ((isResolvingUri && !claim) || !claim) { if ((isResolvingUri && !claim) || !claim) {
return ( return (
@ -794,7 +794,7 @@ class FilePage extends React.PureComponent {
<View style={filePageStyle.dmcaContainer}> <View style={filePageStyle.dmcaContainer}>
<Text style={filePageStyle.dmcaText}> <Text style={filePageStyle.dmcaText}>
{__( {__(
'In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications.' 'In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications.',
)} )}
</Text> </Text>
<Link style={filePageStyle.dmcaLink} href="https://lbry.com/faq/dmca" text={__('Read More')} /> <Link style={filePageStyle.dmcaLink} href="https://lbry.com/faq/dmca" text={__('Read More')} />
@ -882,6 +882,8 @@ class FilePage extends React.PureComponent {
return ( return (
<View style={filePageStyle.pageContainer}> <View style={filePageStyle.pageContainer}>
{!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />} {!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />}
{innerContent}
{this.state.showWebView && isWebViewable && ( {this.state.showWebView && isWebViewable && (
<WebView allowFileAccess source={{ uri: localFileUri }} style={filePageStyle.viewer} /> <WebView allowFileAccess source={{ uri: localFileUri }} style={filePageStyle.viewer} />
)} )}
@ -892,7 +894,7 @@ class FilePage extends React.PureComponent {
renderIndicator={() => null} renderIndicator={() => null}
/> />
)} )}
{!this.state.showWebView && ( {!innerContent && !this.state.showWebView && (
<View <View
style={ style={
this.state.fullscreenMode ? filePageStyle.innerPageContainerFsMode : filePageStyle.innerPageContainer this.state.fullscreenMode ? filePageStyle.innerPageContainerFsMode : filePageStyle.innerPageContainer
@ -957,7 +959,7 @@ class FilePage extends React.PureComponent {
<Icon name={'arrow-left'} size={18} style={filePageStyle.backButtonIcon} /> <Icon name={'arrow-left'} size={18} style={filePageStyle.backButtonIcon} />
</TouchableOpacity> </TouchableOpacity>
</TouchableOpacity> </TouchableOpacity>
{(this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( {!innerContent && (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && (
<View <View
style={playerBgStyle} style={playerBgStyle}
ref={ref => { ref={ref => {
@ -970,10 +972,10 @@ class FilePage extends React.PureComponent {
}} }}
/> />
)} )}
{(this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && this.state.fullscreenMode && ( {!innerContent &&
<View style={fsPlayerBgStyle} /> (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) &&
)} this.state.fullscreenMode && <View style={fsPlayerBgStyle} />}
{(this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( {!innerContent && (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && (
<MediaPlayer <MediaPlayer
claim={claim} claim={claim}
assignPlayer={ref => { assignPlayer={ref => {
@ -998,195 +1000,194 @@ class FilePage extends React.PureComponent {
/> />
)} )}
<ScrollView {!innerContent && (
style={filePageStyle.scrollContainer} <ScrollView
contentContainerstyle={showActions ? null : filePageStyle.scrollContent} style={filePageStyle.scrollContainer}
keyboardShouldPersistTaps={'handled'} contentContainerstyle={showActions ? null : filePageStyle.scrollContent}
ref={ref => { keyboardShouldPersistTaps={'handled'}
this.scrollView = ref; ref={ref => {
}} this.scrollView = ref;
> }}
<TouchableWithoutFeedback
style={filePageStyle.titleTouch}
onPress={() => this.setState({ showDescription: !this.state.showDescription })}
> >
<View style={filePageStyle.titleArea}> <TouchableWithoutFeedback
<View style={filePageStyle.titleRow}> style={filePageStyle.titleTouch}
<Text style={filePageStyle.title} selectable> onPress={() => this.setState({ showDescription: !this.state.showDescription })}
{title}
</Text>
{isRewardContent && <Icon name="award" style={filePageStyle.rewardIcon} size={16} />}
<View style={filePageStyle.descriptionToggle}>
<Icon name={this.state.showDescription ? 'caret-up' : 'caret-down'} size={24} />
</View>
</View>
<Text style={filePageStyle.viewCount}>
{viewCount === 1 && __('%view% view', { view: viewCount })}
{viewCount > 1 && __('%view% views', { view: viewCount })}
</Text>
</View>
</TouchableWithoutFeedback>
<View style={filePageStyle.largeButtonsRow}>
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.handleSharePress}>
<Icon name={'share-alt'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Share')}</Text>
</TouchableOpacity>
<TouchableOpacity
style={filePageStyle.largeButton}
onPress={() => this.setState({ showTipView: true })}
> >
<Icon name={'gift'} size={16} style={filePageStyle.largeButtonIcon} /> <View style={filePageStyle.titleArea}>
<Text style={filePageStyle.largeButtonText}>{__('Tip')}</Text> <View style={filePageStyle.titleRow}>
</TouchableOpacity> <Text style={filePageStyle.title} selectable>
{title}
{!canEdit && !isPlayable && ( </Text>
<View style={filePageStyle.sharedLargeButton}> {isRewardContent && <Icon name="award" style={filePageStyle.rewardIcon} size={16} />}
{!fileInfo || <View style={filePageStyle.descriptionToggle}>
(fileInfo.written_bytes <= 0 && !completed && ( <Icon name={this.state.showDescription ? 'caret-up' : 'caret-down'} size={24} />
<TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onDownloadPressed}> </View>
<Icon name={'download'} size={16} style={filePageStyle.largeButtonIcon} /> </View>
<Text style={filePageStyle.largeButtonText}>{__('Download')}</Text> <Text style={filePageStyle.viewCount}>
</TouchableOpacity> {viewCount === 1 && __('%view% view', { view: viewCount })}
))} {viewCount > 1 && __('%view% views', { view: viewCount })}
</Text>
{!completed &&
fileInfo &&
!fileInfo.stopped &&
fileInfo.written_bytes > 0 &&
fileInfo.written_bytes < fileInfo.total_bytes &&
!this.state.stopDownloadConfirmed && (
<TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onStopDownloadPressed}>
<Icon name={'stop'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Stop')}</Text>
</TouchableOpacity>
)}
{completed && fileInfo && fileInfo.written_bytes >= fileInfo.total_bytes && (
<TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onOpenFilePressed}>
<Icon name={'folder-open'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Open')}</Text>
</TouchableOpacity>
)}
</View> </View>
)} </TouchableWithoutFeedback>
<View style={filePageStyle.largeButtonsRow}>
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.handleSharePress}>
<Icon name={'share-alt'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Share')}</Text>
</TouchableOpacity>
{!canEdit && (
<TouchableOpacity <TouchableOpacity
style={filePageStyle.largeButton} style={filePageStyle.largeButton}
onPress={() => Linking.openURL(`https://lbry.com/dmca/${claim.claim_id}`)} onPress={() => this.setState({ showTipView: true })}
> >
<Icon name={'flag'} size={16} style={filePageStyle.largeButtonIcon} /> <Icon name={'gift'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Report')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Tip')}</Text>
</TouchableOpacity> </TouchableOpacity>
)}
{canEdit && ( {!canEdit && !isPlayable && (
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.onEditPressed}> <View style={filePageStyle.sharedLargeButton}>
<Icon name={'edit'} size={16} style={filePageStyle.largeButtonIcon} /> {!fileInfo ||
<Text style={filePageStyle.largeButtonText}>{__('Edit')}</Text> (fileInfo.written_bytes <= 0 && !completed && (
</TouchableOpacity> <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onDownloadPressed}>
)} <Icon name={'download'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Download')}</Text>
</TouchableOpacity>
))}
{(completed || canEdit) && ( {!completed &&
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.onDeletePressed}> fileInfo &&
<Icon name={'trash-alt'} size={16} style={filePageStyle.largeButtonIcon} /> !fileInfo.stopped &&
<Text style={filePageStyle.largeButtonText}>{__('Delete')}</Text> fileInfo.written_bytes > 0 &&
</TouchableOpacity> fileInfo.written_bytes < fileInfo.total_bytes &&
)} !this.state.stopDownloadConfirmed && (
</View> <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onStopDownloadPressed}>
<Icon name={'stop'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Stop')}</Text>
</TouchableOpacity>
)}
<View style={filePageStyle.channelRow}> {completed && fileInfo && fileInfo.written_bytes >= fileInfo.total_bytes && (
<View style={filePageStyle.publishInfo}> <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onOpenFilePressed}>
{channelName && ( <Icon name={'folder-open'} size={16} style={filePageStyle.largeButtonIcon} />
<Link <Text style={filePageStyle.largeButtonText}>{__('Open')}</Text>
style={filePageStyle.channelName} </TouchableOpacity>
selectable )}
text={channelName}
numberOfLines={1}
ellipsizeMode={'tail'}
onPress={() => {
navigateToUri(
navigation,
normalizeURI(shortChannelUri || fullChannelUri),
null,
false,
fullChannelUri
);
}}
/>
)}
{!channelName && (
<Text style={filePageStyle.anonChannelName} selectable ellipsizeMode={'tail'}>
{__('Anonymous')}
</Text>
)}
<DateTime
style={filePageStyle.publishDate}
textStyle={filePageStyle.publishDateText}
uri={uri}
formatOptions={{ day: 'numeric', month: 'long', year: 'numeric' }}
show={DateTime.SHOW_DATE}
/>
</View>
<View style={filePageStyle.subscriptionRow}>
{false && ((isPlayable && !fileInfo) || (isPlayable && fileInfo && !fileInfo.download_path)) && (
<Button
style={[filePageStyle.actionButton, filePageStyle.saveFileButton]}
theme={'light'}
icon={'download'}
onPress={this.onSaveFilePressed}
/>
)}
{channelName && (
<SubscribeButton
style={filePageStyle.actionButton}
uri={fullChannelUri}
name={channelName}
hideText={false}
/>
)}
{false && channelName && (
<SubscribeNotificationButton
style={[filePageStyle.actionButton, filePageStyle.bellButton]}
uri={fullChannelUri}
name={channelName}
/>
)}
</View>
</View>
{this.state.showDescription && description && description.length > 0 && (
<View style={filePageStyle.divider} />
)}
{this.state.showDescription && description && (
<View>
<Text style={filePageStyle.description} selectable>
{this.linkify(description)}
</Text>
{tags && tags.length > 0 && (
<View style={filePageStyle.tagContainer}>
<Text style={filePageStyle.tagTitle}>{__('Tags')}</Text>
<View style={filePageStyle.tagList}>{this.renderTags(tags)}</View>
</View> </View>
)} )}
{!canEdit && (
<TouchableOpacity
style={filePageStyle.largeButton}
onPress={() => Linking.openURL(`https://lbry.com/dmca/${claim.claim_id}`)}
>
<Icon name={'flag'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Report')}</Text>
</TouchableOpacity>
)}
{canEdit && (
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.onEditPressed}>
<Icon name={'edit'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Edit')}</Text>
</TouchableOpacity>
)}
{(completed || canEdit) && (
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.onDeletePressed}>
<Icon name={'trash-alt'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Delete')}</Text>
</TouchableOpacity>
)}
</View> </View>
)}
{costInfo && parseFloat(costInfo.cost) > balance && !fileInfo && ( <View style={filePageStyle.channelRow}>
<FileRewardsDriver navigation={navigation} /> <View style={filePageStyle.publishInfo}>
)} {channelName && (
<Link
style={filePageStyle.channelName}
selectable
text={channelName}
numberOfLines={1}
ellipsizeMode={'tail'}
onPress={() => {
navigateToUri(
navigation,
normalizeURI(shortChannelUri || fullChannelUri),
null,
false,
fullChannelUri,
);
}}
/>
)}
{!channelName && (
<Text style={filePageStyle.anonChannelName} selectable ellipsizeMode={'tail'}>
{__('Anonymous')}
</Text>
)}
<DateTime
style={filePageStyle.publishDate}
textStyle={filePageStyle.publishDateText}
uri={fullUri}
formatOptions={{ day: 'numeric', month: 'long', year: 'numeric' }}
show={DateTime.SHOW_DATE}
/>
</View>
<View style={filePageStyle.subscriptionRow}>
{false && ((isPlayable && !fileInfo) || (isPlayable && fileInfo && !fileInfo.download_path)) && (
<Button
style={[filePageStyle.actionButton, filePageStyle.saveFileButton]}
theme={'light'}
icon={'download'}
onPress={this.onSaveFilePressed}
/>
)}
{channelName && (
<SubscribeButton
style={filePageStyle.actionButton}
uri={fullChannelUri}
name={channelName}
hideText={false}
/>
)}
{false && channelName && (
<SubscribeNotificationButton
style={[filePageStyle.actionButton, filePageStyle.bellButton]}
uri={fullChannelUri}
name={channelName}
/>
)}
</View>
</View>
<View onLayout={this.setRelatedContentPosition} /> {this.state.showDescription && description && description.length > 0 && (
<View style={filePageStyle.divider} />
)}
{this.state.showDescription && description && (
<View>
<Text style={filePageStyle.description} selectable>
{this.linkify(description)}
</Text>
{tags && tags.length > 0 && (
<View style={filePageStyle.tagContainer}>
<Text style={filePageStyle.tagTitle}>{__('Tags')}</Text>
<View style={filePageStyle.tagList}>{this.renderTags(tags)}</View>
</View>
)}
</View>
)}
{isSearchingRecommendContent && ( {costInfo && parseFloat(costInfo.cost) > balance && !fileInfo && (
<ActivityIndicator size="small" color={Colors.NextLbryGreen} style={filePageStyle.relatedLoading} /> <FileRewardsDriver navigation={navigation} />
)} )}
{!isSearchingRecommendContent && recommendedContent && recommendedContent.length > 0 && (
<RelatedContent navigation={navigation} uri={uri} fullUri={fullUri} /> <View onLayout={this.setRelatedContentPosition} />
)}
</ScrollView> {this.state.showRecommended && (
<RelatedContent navigation={navigation} title={title} uri={fullUri} fullUri={fullUri} />
)}
</ScrollView>
)}
</View> </View>
)} )}
{this.state.showTipView && ( {this.state.showTipView && (