diff --git a/app/package-lock.json b/app/package-lock.json index aa8db71..dac133e 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -3990,8 +3990,8 @@ } }, "lbryinc": { - "version": "github:lbryio/lbryinc#7910b565d7edda16be1c9d291f296982261ba60a", - "from": "github:lbryio/lbryinc#phone-verification", + "version": "github:lbryio/lbryinc#f2fff2a331578aef84eb77c108f976967afc50e0", + "from": "github:lbryio/lbryinc", "requires": { "lbry-redux": "github:lbryio/lbry-redux#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc", "reselect": "^3.0.0" @@ -5315,9 +5315,8 @@ } }, "react-native-phone-input": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/react-native-phone-input/-/react-native-phone-input-0.2.1.tgz", - "integrity": "sha1-rGhSoeo32NWP+D3tUtGNe2MD5mc=", + "version": "github:lbryio/react-native-phone-input#60fdef484e8bf27328c7fb6a203baab9eb9cd4a1", + "from": "github:lbryio/react-native-phone-input", "requires": { "google-libphonenumber": "^2.0.9", "lodash": "^4.17.4", diff --git a/app/package.json b/app/package.json index a4071f1..3c61ce6 100644 --- a/app/package.json +++ b/app/package.json @@ -16,7 +16,7 @@ "react-native-fast-image": "^5.0.3", "react-native-fetch-blob": "^0.10.8", "react-native-image-zoom-viewer": "^2.2.5", - "react-native-phone-input": "^0.2.1", + "react-native-phone-input": "lbryio/react-native-phone-input", "react-native-vector-icons": "^5.0.0", "react-native-video": "lbryio/react-native-video#exoplayer-lbry-android", "react-navigation": "^2.12.1", diff --git a/app/src/component/fileItem/index.js b/app/src/component/fileItem/index.js index 13209f0..f53ef77 100644 --- a/app/src/component/fileItem/index.js +++ b/app/src/component/fileItem/index.js @@ -5,8 +5,8 @@ import { makeSelectMetadataForUri, makeSelectFileInfoForUri, makeSelectIsUriResolving, - selectRewardContentClaimIds } from 'lbry-redux'; +import { selectRewardContentClaimIds } from 'lbryinc'; import { selectShowNsfw } from '../../redux/selectors/settings'; import FileItem from './view'; diff --git a/app/src/component/fileItem/view.js b/app/src/component/fileItem/view.js index 9539a25..5654763 100644 --- a/app/src/component/fileItem/view.js +++ b/app/src/component/fileItem/view.js @@ -3,8 +3,10 @@ import { normalizeURI } from 'lbry-redux'; import { NavigationActions } from 'react-navigation'; import { NativeModules, Text, View, TouchableOpacity } from 'react-native'; import { navigateToUri } from '../../utils/helper'; +import Colors from '../../styles/colors'; import FileItemMedia from '../fileItemMedia'; import FilePrice from '../filePrice'; +import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from '../link'; import NsfwOverlay from '../nsfwOverlay'; import discoverStyle from '../../styles/discover'; @@ -65,7 +67,10 @@ class FileItem extends React.PureComponent { isResolvingUri={isResolvingUri} style={mediaStyle} /> - {title} + + {title} + {isRewardContent && } + {channelName && { const channelUri = normalizeURI(channelName); diff --git a/app/src/component/fileListItem/view.js b/app/src/component/fileListItem/view.js index aea9558..20d4fa1 100644 --- a/app/src/component/fileListItem/view.js +++ b/app/src/component/fileListItem/view.js @@ -8,7 +8,7 @@ import { TouchableOpacity, View } from 'react-native'; -import { navigateToUri } from '../../utils/helper'; +import { navigateToUri, formatBytes } from '../../utils/helper'; import Colors from '../../styles/colors'; import FileItemMedia from '../fileItemMedia'; import Link from '../../component/link'; @@ -18,27 +18,12 @@ import fileListStyle from '../../styles/fileList'; class FileListItem extends React.PureComponent { getStorageForFileInfo = (fileInfo) => { if (!fileInfo.completed) { - const written = this.formatBytes(fileInfo.written_bytes); - const total = this.formatBytes(fileInfo.total_bytes); + const written = formatBytes(fileInfo.written_bytes); + const total = formatBytes(fileInfo.total_bytes); return `(${written} / ${total})`; } - return this.formatBytes(fileInfo.written_bytes); - } - - formatBytes = (bytes) => { - if (bytes < 1048576) { // < 1MB - const value = (bytes / 1024.0).toFixed(0); - return `${value} KB`; - } - - if (bytes < 1073741824) { // < 1GB - const value = (bytes / (1024.0 * 1024.0)).toFixed(0); - return `${value} MB`; - } - - const value = (bytes / (1024.0 * 1024.0 * 1024.0)).toFixed(0); - return `${value} GB`; + return formatBytes(fileInfo.written_bytes); } formatTitle = (title) => { @@ -90,19 +75,19 @@ class FileListItem extends React.PureComponent { - {isResolving && ( + {!title && !name && !channel && isResolving && ( - {uri} - + {(!title && !name) && {uri}} + {(!title && !name) && - + } )} - {!isResolving && {this.formatTitle(title) || this.formatTitle(name)}} - {!isResolving && channel && + {(title || name) && {this.formatTitle(title) || this.formatTitle(name)}} + {channel && { const channelUri = normalizeURI(channel); navigateToUri(navigation, channelUri); diff --git a/app/src/component/mediaPlayer/view.js b/app/src/component/mediaPlayer/view.js index 38de91b..2b2b045 100644 --- a/app/src/component/mediaPlayer/view.js +++ b/app/src/component/mediaPlayer/view.js @@ -115,6 +115,11 @@ class MediaPlayer extends React.PureComponent { this.hidePlayerControls(); } + manualHidePlayerControls = () => { + this.clearControlsTimeout(); + this.setState({ areControlsVisible: false }); + } + hidePlayerControls() { const player = this; let timeout = setTimeout(() => { @@ -123,6 +128,14 @@ class MediaPlayer extends React.PureComponent { player.setState({ controlsTimeout: timeout }); } + togglePlayerControls = () => { + if (this.state.areControlsVisible) { + this.manualHidePlayerControls(); + } else { + this.showPlayerControls(); + } + } + togglePlay = () => { this.showPlayerControls(); this.setState({ paused: !this.state.paused }); @@ -342,7 +355,7 @@ class MediaPlayer extends React.PureComponent { onEnd={this.onEnd} /> - + {this.renderPlayerControls()} diff --git a/app/src/component/relatedContent/index.js b/app/src/component/relatedContent/index.js new file mode 100644 index 0000000..0bafb6e --- /dev/null +++ b/app/src/component/relatedContent/index.js @@ -0,0 +1,23 @@ +import { connect } from 'react-redux'; +import { + makeSelectClaimForUri, + doSearch, + makeSelectRecommendedContentForUri, + selectIsSearching, +} from 'lbry-redux'; +import RelatedContent from './view'; + +const select = (state, props) => ({ + claim: makeSelectClaimForUri(props.uri)(state), + recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state), + isSearching: selectIsSearching(state), +}); + +const perform = dispatch => ({ + search: query => dispatch(doSearch(query, 10, undefined, true)), +}); + +export default connect( + select, + perform +)(RelatedContent); \ No newline at end of file diff --git a/app/src/component/relatedContent/view.js b/app/src/component/relatedContent/view.js new file mode 100644 index 0000000..1583bae --- /dev/null +++ b/app/src/component/relatedContent/view.js @@ -0,0 +1,66 @@ +import React from 'react'; +import { ActivityIndicator, FlatList, Text, View } from 'react-native'; +import { navigateToUri } from '../../utils/helper'; +import Colors from '../../styles/colors'; +import FileListItem from '../fileListItem'; +import fileListStyle from '../../styles/fileList'; +import relatedContentStyle from '../../styles/relatedContent'; + +export default class RelatedContent extends React.PureComponent { + constructor() { + super(); + + this.didSearch = undefined; + } + + componentDidMount() { + this.getRecommendedContent(); + } + + componentDidUpdate(prevProps: Props) { + const { claim, uri } = this.props; + + if (uri !== prevProps.uri) { + this.didSearch = false; + } + + if (claim && !this.didSearch) { + this.getRecommendedContent(); + } + } + + getRecommendedContent() { + const { claim, search } = this.props; + + if (claim && claim.value && claim.value.stream && claim.value.stream.metadata) { + const { title } = claim.value.stream.metadata; + search(title); + this.didSearch = true; + } + } + + didSearch: ?boolean; + + render() { + const { recommendedContent, isSearching, navigation } = this.props; + + if (!isSearching && (!recommendedContent || recommendedContent.length === 0)) { + return null; + } + + return ( + + Related Content + {recommendedContent && recommendedContent.map(recommendedUri => ( + navigateToUri(navigation, recommendedUri, { autoplay: true })} /> + ))} + {isSearching && } + + ); + } +} \ No newline at end of file diff --git a/app/src/page/discover/index.js b/app/src/page/discover/index.js index 0930f68..0d3da51 100644 --- a/app/src/page/discover/index.js +++ b/app/src/page/discover/index.js @@ -5,6 +5,7 @@ import { selectFeaturedUris, selectFetchingFeaturedUris } from 'lbry-redux'; +import { doFetchRewardedContent } from 'lbryinc'; import DiscoverPage from './view'; const select = state => ({ @@ -15,6 +16,7 @@ const select = state => ({ const perform = dispatch => ({ fetchFeaturedUris: () => dispatch(doFetchFeaturedUris()), + fetchRewardedContent: () => dispatch(doFetchRewardedContent()), }); export default connect(select, perform)(DiscoverPage); \ No newline at end of file diff --git a/app/src/page/discover/view.js b/app/src/page/discover/view.js index 93c5571..b2a8153 100644 --- a/app/src/page/discover/view.js +++ b/app/src/page/discover/view.js @@ -41,7 +41,9 @@ class DiscoverPage extends React.PureComponent { } }); - this.props.fetchFeaturedUris(); + const { fetchFeaturedUris, fetchRewardedContent } = this.props; + fetchFeaturedUris(); + fetchRewardedContent(); } render() { diff --git a/app/src/page/file/index.js b/app/src/page/file/index.js index 19e5d49..e653fff 100644 --- a/app/src/page/file/index.js +++ b/app/src/page/file/index.js @@ -9,9 +9,9 @@ import { makeSelectClaimForUri, makeSelectContentTypeForUri, makeSelectMetadataForUri, - selectRewardContentClaimIds, - selectBlackListedOutpoints, + selectBlackListedOutpoints, } from 'lbry-redux'; +import { selectRewardContentClaimIds } from 'lbryinc'; import { doDeleteFile, doStopDownloadingFile } from '../../redux/actions/file'; import FilePage from './view'; diff --git a/app/src/page/file/view.js b/app/src/page/file/view.js index 8cd3ff7..9871982 100644 --- a/app/src/page/file/view.js +++ b/app/src/page/file/view.js @@ -15,6 +15,7 @@ import { View, WebView } from 'react-native'; +import { navigateToUri } from '../../utils/helper'; import ImageViewer from 'react-native-image-zoom-viewer'; import Button from '../../component/button'; import Colors from '../../styles/colors'; @@ -25,6 +26,7 @@ import FilePrice from '../../component/filePrice'; import FloatingWalletBalance from '../../component/floatingWalletBalance'; import Link from '../../component/link'; import MediaPlayer from '../../component/mediaPlayer'; +import RelatedContent from '../../component/relatedContent'; import UriBar from '../../component/uriBar'; import Video from 'react-native-video'; import filePageStyle from '../../styles/filePage'; @@ -435,19 +437,23 @@ class FilePage extends React.PureComponent { onPress={this.onStopDownloadPressed} /> } } - + {title} {channelName && { const channelUri = normalizeURI(channelName); - navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri: channelUri }}); + navigateToUri(navigation, channelUri); }} />} {description && description.length > 0 && } {description && {this.linkify(description)}} + + )} diff --git a/app/src/page/search/index.js b/app/src/page/search/index.js index c9f856d..7897391 100644 --- a/app/src/page/search/index.js +++ b/app/src/page/search/index.js @@ -14,7 +14,7 @@ const select = (state) => ({ }); const perform = dispatch => ({ - search: (query) => dispatch(doSearch(query)) + search: (query) => dispatch(doSearch(query, 25)) }); export default connect(select, perform)(SearchPage); diff --git a/app/src/page/splash/index.js b/app/src/page/splash/index.js index d9ac7ed..f85f128 100644 --- a/app/src/page/splash/index.js +++ b/app/src/page/splash/index.js @@ -2,6 +2,7 @@ import { connect } from 'react-redux'; import { doBalanceSubscribe, doNotify } from 'lbry-redux'; import { doAuthenticate, + doFetchRewardedContent, doUserEmailToVerify, doUserEmailVerify, doUserEmailVerifyFailure, @@ -18,8 +19,9 @@ const select = state => ({ const perform = dispatch => ({ authenticate: (appVersion, os) => dispatch(doAuthenticate(appVersion, os)), - deleteCompleteBlobs: () => dispatch(doDeleteCompleteBlobs()), balanceSubscribe: () => dispatch(doBalanceSubscribe()), + deleteCompleteBlobs: () => dispatch(doDeleteCompleteBlobs()), + fetchRewardedContent: () => dispatch(doFetchRewardedContent()), notify: data => dispatch(doNotify(data)), setEmailToVerify: email => dispatch(doUserEmailToVerify(email)), verifyUserEmail: (token, recaptcha) => dispatch(doUserEmailVerify(token, recaptcha)), diff --git a/app/src/page/splash/view.js b/app/src/page/splash/view.js index debde4b..c84d370 100644 --- a/app/src/page/splash/view.js +++ b/app/src/page/splash/view.js @@ -50,6 +50,8 @@ class SplashScreen extends React.PureComponent { AsyncStorage.setItem('firstLaunchTime', String(moment().unix())); } }); + + this.props.fetchRewardedContent(); } updateStatus() { @@ -109,7 +111,7 @@ class SplashScreen extends React.PureComponent { }); } } else { - navigation.navigate({ routeName: 'File', key: 'filePage', params: { uri: launchUrl } }); + navigateToUri(navigation, launchUrl); } } }); diff --git a/app/src/page/wallet/view.js b/app/src/page/wallet/view.js index 5956cb5..5fcb160 100644 --- a/app/src/page/wallet/view.js +++ b/app/src/page/wallet/view.js @@ -17,7 +17,7 @@ class WalletPage extends React.PureComponent { - This is beta software. You may lose any LBC that you send to your wallet due to uninstallation, software bugs, deleted files, or malicious third-party software. You should not use this wallet as your primary wallet. If you understand the risks and you wish to continue, please click the button below. + This is beta software. You may lose any LBC that you send to your wallet due to uninstallation, software bugs, deleted files, or malicious third-party software. You should not use this wallet as your primary wallet. If you understand the risks and you wish to continue, please tap the button below.