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.