Compare commits

...

3 commits

Author SHA1 Message Date
Akinwale Ariwodola
8ae6b88410 fix downloads. file page tweaks. 2019-12-28 10:59:30 +01:00
Akinwale Ariwodola
a32c7f32f8 download button tweaks 2019-12-28 01:12:07 +01:00
Akinwale Ariwodola
c1f73c2766 streamlined first run 2019-12-28 00:46:11 +01:00
10 changed files with 597 additions and 554 deletions

View file

@ -51,6 +51,7 @@ import {
selectHashChanged, selectHashChanged,
selectUser, selectUser,
} from 'lbryinc'; } from 'lbryinc';
import { doStartDownload, doUpdateDownload, doCompleteDownload } from 'redux/actions/file';
import { makeSelectClientSetting, selectFullscreenMode } from 'redux/selectors/settings'; import { makeSelectClientSetting, selectFullscreenMode } from 'redux/selectors/settings';
import { decode as atob } from 'base-64'; import { decode as atob } from 'base-64';
import { dispatchNavigateBack, dispatchNavigateToUri, transformUrl } from 'utils/helper'; import { dispatchNavigateBack, dispatchNavigateToUri, transformUrl } from 'utils/helper';
@ -311,6 +312,10 @@ class AppWithNavigationState extends React.Component {
this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000); this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000);
Linking.addEventListener('url', this._handleUrl); Linking.addEventListener('url', this._handleUrl);
DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted);
DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated);
DeviceEventEmitter.addListener('onDownloadCompleted', this.handleDownloadCompleted);
// call /sync/get with interval // call /sync/get with interval
this.syncGetInterval = setInterval(() => { this.syncGetInterval = setInterval(() => {
this.setState({ syncHashChanged: false }); // reset local state this.setState({ syncHashChanged: false }); // reset local state
@ -345,7 +350,29 @@ class AppWithNavigationState extends React.Component {
); );
}; };
handleDownloadStarted = evt => {
const { dispatch } = this.props;
const { uri, outpoint, fileInfo } = evt;
dispatch(doStartDownload(uri, outpoint, fileInfo));
};
handleDownloadUpdated = evt => {
const { dispatch } = this.props;
const { uri, outpoint, fileInfo, progress } = evt;
dispatch(doUpdateDownload(uri, outpoint, fileInfo, progress));
};
handleDownloadCompleted = evt => {
const { dispatch } = this.props;
const { uri, outpoint, fileInfo } = evt;
dispatch(doCompleteDownload(uri, outpoint, fileInfo));
};
componentWillUnmount() { componentWillUnmount() {
DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted);
DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated);
DeviceEventEmitter.removeListener('onDownloadCompleted', this.handleDownloadCompleted);
AppState.removeEventListener('change', this._handleAppStateChange); AppState.removeEventListener('change', this._handleAppStateChange);
BackHandler.removeEventListener('hardwareBackPress'); BackHandler.removeEventListener('hardwareBackPress');
Linking.removeEventListener('url', this._handleUrl); Linking.removeEventListener('url', this._handleUrl);

View file

@ -11,11 +11,6 @@ class FileDownloadButton extends React.PureComponent {
} }
} }
componentWillReceiveProps(nextProps) {
// this.checkAvailability(nextProps.uri);
// this.restartDownload(nextProps);
}
restartDownload(props) { restartDownload(props) {
const { downloading, fileInfo, uri, restartDownload } = props; const { downloading, fileInfo, uri, restartDownload } = props;
@ -45,6 +40,7 @@ class FileDownloadButton extends React.PureComponent {
doPause, doPause,
style, style,
openFile, openFile,
onFileActionPress,
onButtonLayout, onButtonLayout,
} = this.props; } = this.props;
@ -72,19 +68,7 @@ class FileDownloadButton extends React.PureComponent {
text={isPlayable ? __('Play') : isViewable ? __('View') : __('Download')} text={isPlayable ? __('Play') : isViewable ? __('View') : __('Download')}
onLayout={onButtonLayout} onLayout={onButtonLayout}
style={[style, fileDownloadButtonStyle.container]} style={[style, fileDownloadButtonStyle.container]}
onPress={() => { onPress={onFileActionPress}
NativeModules.Firebase.track('purchase_uri', { uri: uri });
purchaseUri(uri, costInfo, !isPlayable);
if (NativeModules.UtilityModule) {
NativeModules.UtilityModule.checkDownloads();
}
if (isPlayable && onPlay) {
this.props.onPlay();
}
if (isViewable && onView) {
this.props.onView();
}
}}
/> />
); );
} else if (fileInfo && fileInfo.download_path) { } else if (fileInfo && fileInfo.download_path) {

View file

@ -158,7 +158,13 @@ class FileListItem extends React.PureComponent {
</View> </View>
)} )}
{fileInfo && fileInfo.completed && fileInfo.download_path && ( {fileInfo && fileInfo.completed && fileInfo.download_path && (
<Icon style={fileListStyle.downloadedIcon} solid color={Colors.NextLbryGreen} name={'folder'} size={16} /> <Icon
style={featuredResult ? fileListStyle.featuredDownloadedIcon : fileListStyle.downloadedIcon}
solid
color={Colors.NextLbryGreen}
name={'folder'}
size={16}
/>
)} )}
<View style={fileListStyle.detailsContainer}> <View style={fileListStyle.detailsContainer}>
{featuredResult && ( {featuredResult && (

View file

@ -8,18 +8,11 @@ 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 = { componentDidMount() {
urlsResolved: false,
};
componentDidUpdate(prevProps) {
const { resolveUris, recommendedContent } = this.props; const { resolveUris, recommendedContent } = this.props;
if (recommendedContent && recommendedContent.length > 0) {
if (recommendedContent && recommendedContent.length > 0 && !this.state.urisResolved) {
this.setState({ urisResolved: true }, () => {
// batch resolve the uris // batch resolve the uris
resolveUris(recommendedContent); resolveUris(recommendedContent);
});
} }
} }

View file

@ -52,8 +52,9 @@ function checkMessageAndSave(message, messagesFilePath) {
); */ ); */
}) })
.catch(err => { .catch(err => {
if (err) { if (err && !isProduction) {
throw err; // only do this when not in production
console.error(err);
} }
}); });
} }

View file

@ -57,7 +57,7 @@ window.__ = __;
const globalExceptionHandler = (error, isFatal) => { const globalExceptionHandler = (error, isFatal) => {
if (error && NativeModules.Firebase) { if (error && NativeModules.Firebase) {
NativeModules.Firebase.logException(isFatal, error.message ? error.message : 'No message', JSON.stringify(error)); NativeModules.Firebase.logException(!!isFatal, error.message ? error.message : 'No message', JSON.stringify(error));
} }
}; };
setJSExceptionHandler(globalExceptionHandler, true); setJSExceptionHandler(globalExceptionHandler, true);

View file

@ -8,6 +8,7 @@ import {
doPurchaseUri, doPurchaseUri,
doDeletePurchasedUri, doDeletePurchasedUri,
doResolveUri, doResolveUri,
doResolveUris,
doSearch, doSearch,
doSendTip, doSendTip,
doToast, doToast,
@ -28,6 +29,7 @@ import {
selectPurchasedUris, selectPurchasedUris,
selectFailedPurchaseUris, selectFailedPurchaseUris,
selectPurchaseUriErrorMessage, selectPurchaseUriErrorMessage,
selectResolvingUris,
selectIsSearching, selectIsSearching,
} from 'lbry-redux'; } from 'lbry-redux';
import { import {
@ -39,13 +41,7 @@ import {
selectRewardContentClaimIds, selectRewardContentClaimIds,
selectBlackListedOutpoints, selectBlackListedOutpoints,
} from 'lbryinc'; } from 'lbryinc';
import { import { doDeleteFile, doStopDownloadingFile } from 'redux/actions/file';
doStartDownload,
doUpdateDownload,
doCompleteDownload,
doDeleteFile,
doStopDownloadingFile,
} from 'redux/actions/file';
import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
import { doToggleFullscreenMode } from 'redux/actions/settings'; import { doToggleFullscreenMode } from 'redux/actions/settings';
import { selectDrawerStack } from 'redux/selectors/drawer'; import { selectDrawerStack } from 'redux/selectors/drawer';
@ -77,6 +73,7 @@ const select = (state, props) => {
thumbnail: makeSelectThumbnailForUri(contentUri)(state), thumbnail: makeSelectThumbnailForUri(contentUri)(state),
title: makeSelectTitleForUri(contentUri)(state), title: makeSelectTitleForUri(contentUri)(state),
recommendedContent: makeSelectRecommendedContentForUri(contentUri)(state), recommendedContent: makeSelectRecommendedContentForUri(contentUri)(state),
resolvingUris: selectResolvingUris(state),
isSearchingRecommendContent: selectIsSearching(state), isSearchingRecommendContent: selectIsSearching(state),
viewCount: makeSelectViewCountForUri(contentUri)(state), viewCount: makeSelectViewCountForUri(contentUri)(state),
}; };
@ -100,14 +97,12 @@ const perform = dispatch => ({
purchaseUri: (uri, costInfo, saveFile) => dispatch(doPurchaseUri(uri, costInfo, saveFile)), purchaseUri: (uri, costInfo, saveFile) => dispatch(doPurchaseUri(uri, costInfo, saveFile)),
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)),
searchRecommended: query => dispatch(doSearch(query, 20, undefined, true)), 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)),
stopDownload: (uri, fileInfo) => dispatch(doStopDownloadingFile(uri, fileInfo)), stopDownload: (uri, fileInfo) => dispatch(doStopDownloadingFile(uri, fileInfo)),
startDownload: (uri, outpoint, fileInfo) => dispatch(doStartDownload(uri, outpoint, fileInfo)),
updateDownload: (uri, outpoint, fileInfo, progress) => dispatch(doUpdateDownload(uri, outpoint, fileInfo, progress)),
completeDownload: (uri, outpoint, fileInfo) => dispatch(doCompleteDownload(uri, outpoint, fileInfo)),
toggleFullscreenMode: mode => dispatch(doToggleFullscreenMode(mode)), toggleFullscreenMode: mode => dispatch(doToggleFullscreenMode(mode)),
}); });

View file

@ -72,6 +72,7 @@ class FilePage extends React.PureComponent {
fileViewLogged: false, fileViewLogged: false,
fullscreenMode: false, fullscreenMode: false,
fileGetStarted: false, fileGetStarted: false,
hasCheckedAllResolved: false,
imageUrls: null, imageUrls: null,
isLandscape: false, isLandscape: false,
mediaLoaded: false, mediaLoaded: false,
@ -101,29 +102,24 @@ class FilePage extends React.PureComponent {
onComponentFocused = () => { onComponentFocused = () => {
StatusBar.setHidden(false); StatusBar.setHidden(false);
NativeModules.Firebase.setCurrentScreen('File'); NativeModules.Firebase.setCurrentScreen('File').then(result => {
DeviceEventEmitter.addListener('onStoragePermissionGranted', this.handleStoragePermissionGranted);
DeviceEventEmitter.addListener('onStoragePermissionRefused', this.handleStoragePermissionRefused);
DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted); const { claim, fetchMyClaims, fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated);
DeviceEventEmitter.addListener('onDownloadCompleted', this.handleDownloadCompleted);
const { fetchMyClaims, fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
const { uri, uriVars } = navigation.state.params; const { uri, uriVars } = navigation.state.params;
this.setState({ uri, uriVars }); this.setState({ uri, uriVars });
if (!isResolvingUri) resolveUri(uri); if (!isResolvingUri && !claim) resolveUri(uri);
this.fetchFileInfo(this.props); this.fetchFileInfo(this.props);
this.fetchCostInfo(this.props); this.fetchCostInfo(this.props);
fetchMyClaims(); fetchMyClaims();
if (NativeModules.Firebase) {
NativeModules.Firebase.track('open_file_page', { uri: uri }); NativeModules.Firebase.track('open_file_page', { uri: uri });
}
if (NativeModules.UtilityModule) {
NativeModules.UtilityModule.keepAwakeOn(); NativeModules.UtilityModule.keepAwakeOn();
} });
}; };
componentDidMount() { componentDidMount() {
@ -151,6 +147,7 @@ class FilePage extends React.PureComponent {
navigation, navigation,
contentType, contentType,
notify, notify,
recommendedContent: prevRecommendedContent,
drawerStack: prevDrawerStack, drawerStack: prevDrawerStack,
} = this.props; } = this.props;
const { uri } = navigation.state.params; const { uri } = navigation.state.params;
@ -162,6 +159,8 @@ class FilePage extends React.PureComponent {
purchaseUriErrorMessage, purchaseUriErrorMessage,
streamingUrl, streamingUrl,
drawerStack, drawerStack,
recommendedContent,
resolveUris,
} = nextProps; } = nextProps;
if (Constants.ROUTE_FILE === currentRoute && currentRoute !== prevRoute) { if (Constants.ROUTE_FILE === currentRoute && currentRoute !== prevRoute) {
@ -177,11 +176,9 @@ class FilePage extends React.PureComponent {
const mediaType = Lbry.getMediaType(contentType); const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio'; const isPlayable = mediaType === 'video' || mediaType === 'audio';
if ( if (this.state.fileGetStarted || prevPurchasedUris.length !== purchasedUris.length) {
(this.state.fileGetStarted || prevPurchasedUris.length !== purchasedUris.length) && const { permanent_url: permanentUrl } = claim;
NativeModules.UtilityModule if (purchasedUris.includes(uri) || purchasedUris.includes(permanentUrl)) {
) {
if (purchasedUris.includes(uri)) {
const { nout, txid } = claim; const { nout, txid } = claim;
const outpoint = `${txid}:${nout}`; const outpoint = `${txid}:${nout}`;
NativeModules.UtilityModule.queueDownload(outpoint); NativeModules.UtilityModule.queueDownload(outpoint);
@ -216,9 +213,23 @@ class FilePage extends React.PureComponent {
if (claim && !this.state.viewCountFetched) { if (claim && !this.state.viewCountFetched) {
this.setState({ viewCountFetched: true }, () => fetchViewCount(claim.claim_id)); this.setState({ viewCountFetched: true }, () => fetchViewCount(claim.claim_id));
} }
if (
(!prevRecommendedContent && recommendedContent) ||
(recommendedContent && prevRecommendedContent && recommendedContent.length !== prevRecommendedContent.length)
) {
resolveUris(recommendedContent);
}
} }
componentDidUpdate(prevProps) { shouldComponentUpdate(nextProps, nextState) {
return (
Object.keys(this.difference(nextProps, this.props)).length > 0 ||
Object.keys(this.difference(nextState, this.state)).length > 0
);
}
componentDidUpdate(prevProps, prevState) {
const { const {
claim, claim,
contentType, contentType,
@ -228,7 +239,6 @@ class FilePage extends React.PureComponent {
resolveUri, resolveUri,
navigation, navigation,
purchaseUri, purchaseUri,
searchRecommended,
title, title,
} = this.props; } = this.props;
const { uri } = this.state; const { uri } = this.state;
@ -236,10 +246,6 @@ class FilePage extends React.PureComponent {
resolveUri(uri); resolveUri(uri);
} }
if (title && !this.state.didSearchRecommended) {
this.setState({ didSearchRecommended: true }, () => searchRecommended(title));
}
// Returned to the page. If mediaLoaded, and currentMediaInfo is different, update // Returned to the page. If mediaLoaded, and currentMediaInfo is different, update
if (this.state.mediaLoaded && window.currentMediaInfo && window.currentMediaInfo.uri !== this.state.uri) { if (this.state.mediaLoaded && window.currentMediaInfo && window.currentMediaInfo.uri !== this.state.uri) {
const { metadata } = this.props; const { metadata } = this.props;
@ -254,15 +260,7 @@ class FilePage extends React.PureComponent {
const mediaType = Lbry.getMediaType(contentType); const mediaType = Lbry.getMediaType(contentType);
const isViewable = mediaType === 'image' || mediaType === 'text'; const isViewable = mediaType === 'image' || mediaType === 'text';
if (claim && costInfo && costInfo.cost === 0 && !this.state.autoGetAttempted && isViewable) { if (claim && costInfo && costInfo.cost === 0 && !this.state.autoGetAttempted && isViewable) {
this.setState( this.setState({ autoGetAttempted: true }, () => this.checkStoragePermissionForDownload());
{
autoGetAttempted: true,
downloadPressed: true,
autoPlayMedia: true,
stopDownloadConfirmed: false,
},
() => purchaseUri(claim.permanent_url, costInfo, true)
);
} }
} }
@ -399,27 +397,34 @@ class FilePage extends React.PureComponent {
} }
window.player = null; window.player = null;
DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted); DeviceEventEmitter.removeListener('onStoragePermissionGranted', this.handleStoragePermissionGranted);
DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated); DeviceEventEmitter.removeListener('onStoragePermissionRefused', this.handleStoragePermissionRefused);
DeviceEventEmitter.removeListener('onDownloadCompleted', this.handleDownloadCompleted);
} }
handleDownloadStarted = evt => { handleStoragePermissionGranted = () => {
const { startDownload } = this.props; // permission was allowed. proceed to download
const { uri, outpoint, fileInfo } = evt; const { notify } = this.props;
startDownload(uri, outpoint, fileInfo);
// update the configured download folder and then download
NativeModules.UtilityModule.getDownloadDirectory().then(downloadDirectory => {
Lbry.settings_set({
key: 'download_dir',
value: downloadDirectory,
})
.then(() => this.performDownload())
.catch(() => {
notify({ message: 'The file could not be downloaded to the default download directory.', isError: true });
});
});
}; };
handleDownloadUpdated = evt => { handleStoragePermissionRefused = () => {
const { updateDownload } = this.props; const { notify } = this.props;
const { uri, outpoint, fileInfo, progress } = evt; this.setState({ downloadPressed: false });
updateDownload(uri, outpoint, fileInfo, progress); notify({
}; message: __('The file could not be downloaded because the permission to write to storage was not granted.'),
isError: true,
handleDownloadCompleted = evt => { });
const { completeDownload } = this.props;
const { uri, outpoint, fileInfo } = evt;
completeDownload(uri, outpoint, fileInfo);
}; };
localUriForFileInfo = fileInfo => { localUriForFileInfo = fileInfo => {
@ -519,6 +524,7 @@ 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;
@ -536,6 +542,11 @@ class FilePage extends React.PureComponent {
payload['time_to_start_ms'] = timeToStartMillis; payload['time_to_start_ms'] = timeToStartMillis;
} }
NativeModules.Firebase.track('play', payload); NativeModules.Firebase.track('play', payload);
// only fetch recommended content after playback has started
if (title) {
searchRecommended(title);
}
}; };
onPlaybackFinished = () => { onPlaybackFinished = () => {
@ -589,14 +600,48 @@ class FilePage extends React.PureComponent {
)); ));
}; };
onFileDownloadButtonPlayed = () => { onFileDownloadButtonPressed = () => {
const { setPlayerVisible } = this.props; const { claim, costInfo, contentType, purchaseUri, setPlayerVisible } = this.props;
const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio';
const isViewable = mediaType === 'image' || mediaType === 'text';
const { permanent_url: uri } = claim;
NativeModules.Firebase.track('purchase_uri', { uri: uri });
if (!isPlayable) {
this.checkStoragePermissionForDownload();
} else {
purchaseUri(uri, costInfo, !isPlayable);
}
if (isPlayable) {
this.startTime = Date.now(); this.startTime = Date.now();
this.setState({ downloadPressed: true, autoPlayMedia: true, stopDownloadConfirmed: false }); this.setState({ downloadPressed: true, autoPlayMedia: true, stopDownloadConfirmed: false });
setPlayerVisible(); setPlayerVisible();
}
if (isViewable) {
this.setState({ downloadPressed: true });
}
}; };
onDownloadPressed = () => { onDownloadPressed = () => {
this.checkStoragePermissionForDownload();
};
checkStoragePermissionForDownload = () => {
// check if we the permission to write to external storage has been granted
NativeModules.UtilityModule.canReadWriteStorage().then(canReadWrite => {
if (!canReadWrite) {
// request permission
NativeModules.UtilityModule.requestStoragePermission();
} else {
this.performDownload();
}
});
};
performDownload = () => {
const { claim, costInfo, purchaseUri } = this.props; const { claim, costInfo, purchaseUri } = this.props;
this.setState( this.setState(
{ {
@ -604,7 +649,10 @@ class FilePage extends React.PureComponent {
autoPlayMedia: false, autoPlayMedia: false,
stopDownloadConfirmed: false, stopDownloadConfirmed: false,
}, },
() => purchaseUri(claim.permanent_url, costInfo, true) () => {
purchaseUri(claim.permanent_url, costInfo, true);
NativeModules.UtilityModule.checkDownloads();
}
); );
}; };
@ -621,14 +669,7 @@ class FilePage extends React.PureComponent {
// file already in library or URI already purchased, use fileGet directly // file already in library or URI already purchased, use fileGet directly
this.setState({ fileGetStarted: true }, () => fileGet(uri, true)); this.setState({ fileGetStarted: true }, () => fileGet(uri, true));
} else { } else {
this.setState( this.checkStoragePermissionForDownload();
{
downloadPressed: true,
autoPlayMedia: false,
stopDownloadConfirmed: false,
},
() => purchaseUri(uri, costInfo, true)
);
} }
}; };
@ -665,17 +706,6 @@ class FilePage extends React.PureComponent {
} }
}; };
onMediaContainerPressed = () => {
const { costInfo, contentType, purchaseUri } = this.props;
const { uri } = this.state;
const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio';
purchaseUri(uri, costInfo, isPlayable);
if (isPlayable) {
this.onFileDownloadButtonPlayed();
}
};
render() { render() {
const { const {
balance, balance,
@ -710,7 +740,7 @@ class FilePage extends React.PureComponent {
let innerContent = null; let innerContent = null;
if ((isResolvingUri && !claim) || !claim) { if ((isResolvingUri && !claim) || !claim) {
return ( return (
<View style={filePageStyle.container}> <View style={filePageStyle.pageContainer}>
<UriBar value={uri} navigation={navigation} /> <UriBar value={uri} navigation={navigation} />
{isResolvingUri && ( {isResolvingUri && (
<View style={filePageStyle.busyContainer}> <View style={filePageStyle.busyContainer}>
@ -748,13 +778,7 @@ class FilePage extends React.PureComponent {
); );
} }
if (claim) {
if (isChannel) {
return <ChannelPage uri={uri} navigation={navigation} />;
}
let isClaimBlackListed = false; let isClaimBlackListed = false;
if (blackListedOutpoints) { if (blackListedOutpoints) {
for (let i = 0; i < blackListedOutpoints.length; i += 1) { for (let i = 0; i < blackListedOutpoints.length; i += 1) {
const outpoint = blackListedOutpoints[i]; const outpoint = blackListedOutpoints[i];
@ -766,8 +790,7 @@ class FilePage extends React.PureComponent {
} }
if (isClaimBlackListed) { if (isClaimBlackListed) {
return ( innerContent = (
<View style={filePageStyle.pageContainer}>
<View style={filePageStyle.dmcaContainer}> <View style={filePageStyle.dmcaContainer}>
<Text style={filePageStyle.dmcaText}> <Text style={filePageStyle.dmcaText}>
{__( {__(
@ -776,8 +799,6 @@ class FilePage extends React.PureComponent {
</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')} />
</View> </View>
<UriBar value={uri} navigation={navigation} />
</View>
); );
} }
@ -833,12 +854,19 @@ class FilePage extends React.PureComponent {
const localFileUri = this.localUriForFileInfo(fileInfo); const localFileUri = this.localUriForFileInfo(fileInfo);
const unsupported = !isPlayable && !canOpen; const unsupported = !isPlayable && !canOpen;
if (fileInfo && !this.state.autoDownloadStarted && this.state.uriVars && this.state.uriVars.download === 'true') { if (
!this.state.autoDownloadStarted &&
claim &&
costInfo &&
((isPlayable && costInfo.cost === 0) || (this.state.uriVars && this.state.uriVars.download === 'true'))
) {
this.setState({ autoDownloadStarted: true }, () => { this.setState({ autoDownloadStarted: true }, () => {
purchaseUri(uri, costInfo, !isPlayable); if (!isPlayable) {
if (NativeModules.UtilityModule) { this.checkStoragePermissionForDownload();
NativeModules.UtilityModule.checkDownloads(); } else {
purchaseUri(claim.permanent_url, costInfo, !isPlayable);
} }
NativeModules.UtilityModule.checkDownloads();
}); });
} }
@ -847,13 +875,16 @@ class FilePage extends React.PureComponent {
this.setState({ autoOpened: true }, () => this.openFile(localFileUri, mediaType)); this.setState({ autoOpened: true }, () => this.openFile(localFileUri, mediaType));
} }
if (isChannel) {
return <ChannelPage uri={uri} navigation={navigation} />;
}
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} />}
{this.state.showWebView && isWebViewable && ( {this.state.showWebView && isWebViewable && (
<WebView allowFileAccess source={{ uri: localFileUri }} style={filePageStyle.viewer} /> <WebView allowFileAccess source={{ uri: localFileUri }} style={filePageStyle.viewer} />
)} )}
{this.state.showImageViewer && ( {this.state.showImageViewer && (
<ImageViewer <ImageViewer
style={StyleSheet.flatten(filePageStyle.viewer)} style={StyleSheet.flatten(filePageStyle.viewer)}
@ -861,7 +892,6 @@ class FilePage extends React.PureComponent {
renderIndicator={() => null} renderIndicator={() => null}
/> />
)} )}
{!this.state.showWebView && ( {!this.state.showWebView && (
<View <View
style={ style={
@ -872,7 +902,7 @@ class FilePage extends React.PureComponent {
<TouchableOpacity <TouchableOpacity
activeOpacity={0.5} activeOpacity={0.5}
style={filePageStyle.mediaContainer} style={filePageStyle.mediaContainer}
onPress={this.onMediaContainerPressed} onPress={this.onFileDownloadButtonPressed}
> >
{(canOpen || (!fileInfo || (isPlayable && !canLoadMedia)) || (!canOpen && fileInfo)) && ( {(canOpen || (!fileInfo || (isPlayable && !canLoadMedia)) || (!canOpen && fileInfo)) && (
<FileItemMedia <FileItemMedia
@ -908,25 +938,19 @@ class FilePage extends React.PureComponent {
{((isPlayable && !completed && !canLoadMedia) || {((isPlayable && !completed && !canLoadMedia) ||
canOpen || canOpen ||
(!completed && !this.state.streamingMode)) && (!completed && !this.state.streamingMode)) && (
!this.state.downloadPressed && (
<FileDownloadButton <FileDownloadButton
uri={claim && claim.permanent_url ? claim.permanent_url : uri} uri={claim && claim.permanent_url ? claim.permanent_url : uri}
style={filePageStyle.downloadButton} style={filePageStyle.downloadButton}
openFile={() => this.openFile(localFileUri, mediaType)} openFile={() => this.openFile(localFileUri, mediaType)}
isPlayable={isPlayable} isPlayable={isPlayable}
isViewable={isViewable} isViewable={isViewable}
onPlay={this.onFileDownloadButtonPlayed} onFileActionPress={this.onFileDownloadButtonPressed}
onView={() => this.setState({ downloadPressed: true })}
onButtonLayout={() => this.setState({ downloadButtonShown: true })} onButtonLayout={() => this.setState({ downloadButtonShown: true })}
/> />
)} )}
{!fileInfo && ( {!fileInfo && (
<FilePrice <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />
uri={uri}
style={filePageStyle.filePriceContainer}
textStyle={filePageStyle.filePriceText}
/>
)} )}
<TouchableOpacity style={filePageStyle.backButton} onPress={this.onBackButtonPressed}> <TouchableOpacity style={filePageStyle.backButton} onPress={this.onBackButtonPressed}>
@ -958,7 +982,7 @@ class FilePage extends React.PureComponent {
uri={uri} uri={uri}
source={this.playerUriForFileInfo(fileInfo)} source={this.playerUriForFileInfo(fileInfo)}
style={playerStyle} style={playerStyle}
autoPlay={autoplay || this.state.autoPlayMedia} autoPlay
onFullscreenToggled={this.handleFullscreenToggle} onFullscreenToggled={this.handleFullscreenToggle}
onLayout={evt => { onLayout={evt => {
if (!this.state.playerHeight) { if (!this.state.playerHeight) {
@ -1182,9 +1206,6 @@ class FilePage extends React.PureComponent {
</View> </View>
); );
} }
return null;
}
} }
export default FilePage; export default FilePage;

View file

@ -228,7 +228,13 @@ class FirstRunScreen extends React.PureComponent {
handleContinuePressed = () => { handleContinuePressed = () => {
const { notify, user, hasSyncedWallet } = this.props; const { notify, user, hasSyncedWallet } = this.props;
const pageIndex = FirstRunScreen.pages.indexOf(this.state.currentPage); const pageIndex = FirstRunScreen.pages.indexOf(this.state.currentPage);
if (Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage) {
if (Constants.FIRST_RUN_PAGE_WELCOME === this.state.currentPage) {
// only show the welcome screen on first run
this.closeFinalPage();
}
/* if (Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage) {
// do apply sync to check if the password is valid // do apply sync to check if the password is valid
if (hasSyncedWallet) { if (hasSyncedWallet) {
this.checkWalletPassword(); this.checkWalletPassword();
@ -256,7 +262,7 @@ class FirstRunScreen extends React.PureComponent {
} else { } else {
this.showNextPage(); this.showNextPage();
} }
} } */
}; };
handleEmailCollectPageContinue() { handleEmailCollectPageContinue() {
@ -500,7 +506,12 @@ class FirstRunScreen extends React.PureComponent {
{Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT !== this.state.currentPage && {Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT !== this.state.currentPage &&
Constants.FIRST_RUN_PAGE_EMAIL_VERIFY !== this.state.currentPage && ( Constants.FIRST_RUN_PAGE_EMAIL_VERIFY !== this.state.currentPage && (
<Text style={firstRunStyle.buttonText}> <Text style={firstRunStyle.buttonText}>
{Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage ? __('Use LBRY') : __('Continue')} » {[Constants.FIRST_RUN_PAGE_WALLET, Constants.FIRST_RUN_PAGE_WELCOME].includes(
this.state.currentPage
)
? __('Use LBRY')
: __('Continue')}{' '}
»
</Text> </Text>
)} )}
</TouchableOpacity> </TouchableOpacity>

View file

@ -94,6 +94,11 @@ const fileListStyle = StyleSheet.create({
top: 8, top: 8,
left: 8, left: 8,
}, },
featuredDownloadedIcon: {
position: 'absolute',
left: 16,
top: 16,
},
fileItem: { fileItem: {
marginLeft: 24, marginLeft: 24,
marginRight: 24, marginRight: 24,