From d7edbf55b5418b0bd0554aff0c15e280fae2e9d0 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola <akinwale@gmail.com> Date: Sat, 28 Dec 2019 19:36:17 +0100 Subject: [PATCH 1/2] react-navigation-drawer 2.3.3 --- package-lock.json | 9 +++------ package.json | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 93be683..925284e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10128,12 +10128,9 @@ } }, "react-navigation-drawer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/react-navigation-drawer/-/react-navigation-drawer-1.4.0.tgz", - "integrity": "sha512-ZyWBozcjB2aZ7vwCALv90cYA2NpDjM+WALaiYRshvPvue8l7cqynePbHK8GhlMGyJDwZqp4MxQmu8u1XAKp3Bw==", - "requires": { - "react-native-tab-view": "^1.2.0" - } + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/react-navigation-drawer/-/react-navigation-drawer-2.3.3.tgz", + "integrity": "sha512-d/rA8Slqv7HoMfONKVDBQUrRF7YQH796Gzal/KOhaY4VOwUUqIwfxMRJ3WrsdL2OkDPixtkXJE2Fz6KAj658uA==" }, "react-navigation-redux-helpers": { "version": "3.0.2", diff --git a/package.json b/package.json index f4e561a..553fc77 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "react-native-vector-icons": "^6.6.0", "react-native-video": "lbryio/react-native-video#7992ff945872f9bd00a3736d9ff1318f343abf47", "react-navigation": "^3.11.0", - "react-navigation-drawer": "^1.4.0", + "react-navigation-drawer": "^2.3.3", "react-navigation-redux-helpers": "^3.0.2", "react-navigation-stack": "^1.8.1", "react-redux": "^5.0.3", -- 2.49.1 From b8f2a9e24f18d381ddaef81f059fbce1f9407564 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola <akinwale@gmail.com> Date: Sat, 28 Dec 2019 21:02:29 +0100 Subject: [PATCH 2/2] tweak related content view for perf. fix displayed dates. --- src/component/relatedContent/index.js | 10 +- src/component/relatedContent/view.js | 42 ++- src/page/file/index.js | 8 +- src/page/file/view.js | 377 +++++++++++++------------- 4 files changed, 234 insertions(+), 203 deletions(-) diff --git a/src/component/relatedContent/index.js b/src/component/relatedContent/index.js index 7dd415c..6cb46de 100644 --- a/src/component/relatedContent/index.js +++ b/src/component/relatedContent/index.js @@ -1,25 +1,27 @@ import { connect } from 'react-redux'; import { doResolveUris, + doSearch, makeSelectClaimForUri, makeSelectRecommendedContentForUri, - makeSelectTitleForUri, + selectResolvingUris, selectIsSearching, } from 'lbry-redux'; import RelatedContent from './view'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), - recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), isSearching: selectIsSearching(state), + recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state), + resolvingUris: selectResolvingUris(state), }); const perform = dispatch => ({ resolveUris: uris => dispatch(doResolveUris(uris)), + searchRecommended: query => dispatch(doSearch(query, 20, undefined, true)), }); export default connect( select, - perform + perform, )(RelatedContent); diff --git a/src/component/relatedContent/view.js b/src/component/relatedContent/view.js index 8f626f8..639587c 100644 --- a/src/component/relatedContent/view.js +++ b/src/component/relatedContent/view.js @@ -8,20 +8,54 @@ import fileListStyle from 'styles/fileList'; import relatedContentStyle from 'styles/relatedContent'; export default class RelatedContent extends React.PureComponent { + state = { + resolveStarted: false, + }; + 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; - if (recommendedContent && recommendedContent.length > 0) { - // batch resolve the uris - resolveUris(recommendedContent); + if (!this.state.resolveStarted) { + this.setState({ resolveStarted: true }, () => { + if (recommendedContent && recommendedContent.length > 0) { + // batch resolve the uris + resolveUris(recommendedContent); + } + }); } } render() { - const { recommendedContent, navigation, uri, fullUri } = this.props; + const { isSearching, recommendedContent, navigation, uri, fullUri } = this.props; return ( <View style={relatedContentStyle.container}> <Text style={relatedContentStyle.title}>{__('Related Content')}</Text> + {isSearching && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} {recommendedContent && recommendedContent .filter(recommendedUri => recommendedUri !== normalizeURI(fullUri)) diff --git a/src/page/file/index.js b/src/page/file/index.js index 36dd480..099079a 100644 --- a/src/page/file/index.js +++ b/src/page/file/index.js @@ -9,7 +9,6 @@ import { doDeletePurchasedUri, doResolveUri, doResolveUris, - doSearch, doSendTip, doToast, makeSelectIsUriResolving, @@ -19,7 +18,6 @@ import { makeSelectContentPositionForUri, makeSelectContentTypeForUri, makeSelectMetadataForUri, - makeSelectRecommendedContentForUri, makeSelectStreamingUrlForUri, makeSelectThumbnailForUri, makeSelectTitleForUri, @@ -29,7 +27,6 @@ import { selectPurchasedUris, selectFailedPurchaseUris, selectPurchaseUriErrorMessage, - selectResolvingUris, selectIsSearching, } from 'lbry-redux'; import { @@ -72,8 +69,6 @@ const select = (state, props) => { streamingUrl: makeSelectStreamingUrlForUri(contentUri)(state), thumbnail: makeSelectThumbnailForUri(contentUri)(state), title: makeSelectTitleForUri(contentUri)(state), - recommendedContent: makeSelectRecommendedContentForUri(contentUri)(state), - resolvingUris: selectResolvingUris(state), isSearchingRecommendContent: selectIsSearching(state), viewCount: makeSelectViewCountForUri(contentUri)(state), }; @@ -98,7 +93,6 @@ const perform = dispatch => ({ deletePurchasedUri: uri => dispatch(doDeletePurchasedUri(uri)), resolveUri: uri => dispatch(doResolveUri(uri)), resolveUris: uris => dispatch(doResolveUris(uris)), - searchRecommended: query => dispatch(doSearch(query, 20, undefined, true)), sendTip: (amount, claimId, isSupport, successCallback, errorCallback) => dispatch(doSendTip(amount, claimId, isSupport, successCallback, errorCallback)), setPlayerVisible: () => dispatch(doSetPlayerVisible(true)), @@ -108,5 +102,5 @@ const perform = dispatch => ({ export default connect( select, - perform + perform, )(FilePage); diff --git a/src/page/file/view.js b/src/page/file/view.js index 0cc1156..4f991d7 100644 --- a/src/page/file/view.js +++ b/src/page/file/view.js @@ -87,6 +87,7 @@ class FilePage extends React.PureComponent { playerHeight: 0, uri: null, uriVars: null, + showRecommended: false, stopDownloadConfirmed: false, streamingMode: 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 = () => { - const { searchRecommended, title } = this.props; let timeToStartMillis, timeToStart; if (this.startTime) { timeToStartMillis = Date.now() - this.startTime; @@ -544,9 +544,7 @@ class FilePage extends React.PureComponent { NativeModules.Firebase.track('play', payload); // only fetch recommended content after playback has started - if (title) { - searchRecommended(title); - } + this.setState({ showRecommended: true }); }; onPlaybackFinished = () => { @@ -652,7 +650,7 @@ class FilePage extends React.PureComponent { () => { purchaseUri(claim.permanent_url, costInfo, true); NativeModules.UtilityModule.checkDownloads(); - } + }, ); }; @@ -689,7 +687,7 @@ class FilePage extends React.PureComponent { ], 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, }, - () => 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 ownedClaim = myClaimUris.includes(uri) || myChannelUris.includes(uri); + console.log('calling render...'); + let innerContent = null; if ((isResolvingUri && !claim) || !claim) { return ( @@ -794,7 +794,7 @@ class FilePage extends React.PureComponent { <View style={filePageStyle.dmcaContainer}> <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> <Link style={filePageStyle.dmcaLink} href="https://lbry.com/faq/dmca" text={__('Read More')} /> @@ -882,6 +882,8 @@ class FilePage extends React.PureComponent { return ( <View style={filePageStyle.pageContainer}> {!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />} + {innerContent} + {this.state.showWebView && isWebViewable && ( <WebView allowFileAccess source={{ uri: localFileUri }} style={filePageStyle.viewer} /> )} @@ -892,7 +894,7 @@ class FilePage extends React.PureComponent { renderIndicator={() => null} /> )} - {!this.state.showWebView && ( + {!innerContent && !this.state.showWebView && ( <View style={ 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} /> </TouchableOpacity> </TouchableOpacity> - {(this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( + {!innerContent && (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( <View style={playerBgStyle} ref={ref => { @@ -970,10 +972,10 @@ class FilePage extends React.PureComponent { }} /> )} - {(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)) && + this.state.fullscreenMode && <View style={fsPlayerBgStyle} />} + {!innerContent && (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( <MediaPlayer claim={claim} assignPlayer={ref => { @@ -998,195 +1000,194 @@ class FilePage extends React.PureComponent { /> )} - <ScrollView - style={filePageStyle.scrollContainer} - contentContainerstyle={showActions ? null : filePageStyle.scrollContent} - keyboardShouldPersistTaps={'handled'} - ref={ref => { - this.scrollView = ref; - }} - > - <TouchableWithoutFeedback - style={filePageStyle.titleTouch} - onPress={() => this.setState({ showDescription: !this.state.showDescription })} + {!innerContent && ( + <ScrollView + style={filePageStyle.scrollContainer} + contentContainerstyle={showActions ? null : filePageStyle.scrollContent} + keyboardShouldPersistTaps={'handled'} + ref={ref => { + this.scrollView = ref; + }} > - <View style={filePageStyle.titleArea}> - <View style={filePageStyle.titleRow}> - <Text style={filePageStyle.title} selectable> - {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 })} + <TouchableWithoutFeedback + style={filePageStyle.titleTouch} + onPress={() => this.setState({ showDescription: !this.state.showDescription })} > - <Icon name={'gift'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Tip')}</Text> - </TouchableOpacity> - - {!canEdit && !isPlayable && ( - <View style={filePageStyle.sharedLargeButton}> - {!fileInfo || - (fileInfo.written_bytes <= 0 && !completed && ( - <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onDownloadPressed}> - <Icon name={'download'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Download')}</Text> - </TouchableOpacity> - ))} - - {!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 style={filePageStyle.titleArea}> + <View style={filePageStyle.titleRow}> + <Text style={filePageStyle.title} selectable> + {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> - {!canEdit && ( <TouchableOpacity 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} /> - <Text style={filePageStyle.largeButtonText}>{__('Report')}</Text> + <Icon name={'gift'} size={16} style={filePageStyle.largeButtonIcon} /> + <Text style={filePageStyle.largeButtonText}>{__('Tip')}</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> - )} + {!canEdit && !isPlayable && ( + <View style={filePageStyle.sharedLargeButton}> + {!fileInfo || + (fileInfo.written_bytes <= 0 && !completed && ( + <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onDownloadPressed}> + <Icon name={'download'} size={16} style={filePageStyle.largeButtonIcon} /> + <Text style={filePageStyle.largeButtonText}>{__('Download')}</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> + {!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> + )} - <View style={filePageStyle.channelRow}> - <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={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> + {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> )} + + {!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> - )} - {costInfo && parseFloat(costInfo.cost) > balance && !fileInfo && ( - <FileRewardsDriver navigation={navigation} /> - )} + <View style={filePageStyle.channelRow}> + <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 && ( - <ActivityIndicator size="small" color={Colors.NextLbryGreen} style={filePageStyle.relatedLoading} /> - )} - {!isSearchingRecommendContent && recommendedContent && recommendedContent.length > 0 && ( - <RelatedContent navigation={navigation} uri={uri} fullUri={fullUri} /> - )} - </ScrollView> + {costInfo && parseFloat(costInfo.cost) > balance && !fileInfo && ( + <FileRewardsDriver navigation={navigation} /> + )} + + <View onLayout={this.setRelatedContentPosition} /> + + {this.state.showRecommended && ( + <RelatedContent navigation={navigation} title={title} uri={fullUri} fullUri={fullUri} /> + )} + </ScrollView> + )} </View> )} {this.state.showTipView && ( -- 2.49.1