fix downloads. file page tweaks.
This commit is contained in:
parent
a32c7f32f8
commit
8ae6b88410
8 changed files with 498 additions and 498 deletions
|
@ -51,6 +51,7 @@ import {
|
|||
selectHashChanged,
|
||||
selectUser,
|
||||
} from 'lbryinc';
|
||||
import { doStartDownload, doUpdateDownload, doCompleteDownload } from 'redux/actions/file';
|
||||
import { makeSelectClientSetting, selectFullscreenMode } from 'redux/selectors/settings';
|
||||
import { decode as atob } from 'base-64';
|
||||
import { dispatchNavigateBack, dispatchNavigateToUri, transformUrl } from 'utils/helper';
|
||||
|
@ -311,6 +312,10 @@ class AppWithNavigationState extends React.Component {
|
|||
this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000);
|
||||
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
|
||||
this.syncGetInterval = setInterval(() => {
|
||||
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() {
|
||||
DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted);
|
||||
DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated);
|
||||
DeviceEventEmitter.removeListener('onDownloadCompleted', this.handleDownloadCompleted);
|
||||
|
||||
AppState.removeEventListener('change', this._handleAppStateChange);
|
||||
BackHandler.removeEventListener('hardwareBackPress');
|
||||
Linking.removeEventListener('url', this._handleUrl);
|
||||
|
|
|
@ -11,11 +11,6 @@ class FileDownloadButton extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// this.checkAvailability(nextProps.uri);
|
||||
// this.restartDownload(nextProps);
|
||||
}
|
||||
|
||||
restartDownload(props) {
|
||||
const { downloading, fileInfo, uri, restartDownload } = props;
|
||||
|
||||
|
@ -49,9 +44,6 @@ class FileDownloadButton extends React.PureComponent {
|
|||
onButtonLayout,
|
||||
} = this.props;
|
||||
|
||||
console.log('uri=' + uri);
|
||||
console.log(fileInfo);
|
||||
|
||||
if ((fileInfo && !fileInfo.stopped) || loading || downloading) {
|
||||
const progress = fileInfo && fileInfo.written_bytes ? (fileInfo.written_bytes / fileInfo.total_bytes) * 100 : 0,
|
||||
label = fileInfo ? __('%progress%% complete', { progress: progress.toFixed(0) }) : __('Connecting...');
|
||||
|
|
|
@ -158,7 +158,13 @@ class FileListItem extends React.PureComponent {
|
|||
</View>
|
||||
)}
|
||||
{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}>
|
||||
{featuredResult && (
|
||||
|
|
|
@ -8,18 +8,11 @@ import fileListStyle from 'styles/fileList';
|
|||
import relatedContentStyle from 'styles/relatedContent';
|
||||
|
||||
export default class RelatedContent extends React.PureComponent {
|
||||
state = {
|
||||
urlsResolved: false,
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
componentDidMount() {
|
||||
const { resolveUris, recommendedContent } = this.props;
|
||||
|
||||
if (recommendedContent && recommendedContent.length > 0 && !this.state.urisResolved) {
|
||||
this.setState({ urisResolved: true }, () => {
|
||||
if (recommendedContent && recommendedContent.length > 0) {
|
||||
// batch resolve the uris
|
||||
resolveUris(recommendedContent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,8 +57,7 @@ window.__ = __;
|
|||
|
||||
const globalExceptionHandler = (error, isFatal) => {
|
||||
if (error && NativeModules.Firebase) {
|
||||
console.log(error);
|
||||
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);
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
doPurchaseUri,
|
||||
doDeletePurchasedUri,
|
||||
doResolveUri,
|
||||
doResolveUris,
|
||||
doSearch,
|
||||
doSendTip,
|
||||
doToast,
|
||||
|
@ -28,6 +29,7 @@ import {
|
|||
selectPurchasedUris,
|
||||
selectFailedPurchaseUris,
|
||||
selectPurchaseUriErrorMessage,
|
||||
selectResolvingUris,
|
||||
selectIsSearching,
|
||||
} from 'lbry-redux';
|
||||
import {
|
||||
|
@ -39,13 +41,7 @@ import {
|
|||
selectRewardContentClaimIds,
|
||||
selectBlackListedOutpoints,
|
||||
} from 'lbryinc';
|
||||
import {
|
||||
doStartDownload,
|
||||
doUpdateDownload,
|
||||
doCompleteDownload,
|
||||
doDeleteFile,
|
||||
doStopDownloadingFile,
|
||||
} from 'redux/actions/file';
|
||||
import { doDeleteFile, doStopDownloadingFile } from 'redux/actions/file';
|
||||
import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||
import { doToggleFullscreenMode } from 'redux/actions/settings';
|
||||
import { selectDrawerStack } from 'redux/selectors/drawer';
|
||||
|
@ -77,6 +73,7 @@ const select = (state, props) => {
|
|||
thumbnail: makeSelectThumbnailForUri(contentUri)(state),
|
||||
title: makeSelectTitleForUri(contentUri)(state),
|
||||
recommendedContent: makeSelectRecommendedContentForUri(contentUri)(state),
|
||||
resolvingUris: selectResolvingUris(state),
|
||||
isSearchingRecommendContent: selectIsSearching(state),
|
||||
viewCount: makeSelectViewCountForUri(contentUri)(state),
|
||||
};
|
||||
|
@ -100,14 +97,12 @@ const perform = dispatch => ({
|
|||
purchaseUri: (uri, costInfo, saveFile) => dispatch(doPurchaseUri(uri, costInfo, saveFile)),
|
||||
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)),
|
||||
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)),
|
||||
});
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ class FilePage extends React.PureComponent {
|
|||
fileViewLogged: false,
|
||||
fullscreenMode: false,
|
||||
fileGetStarted: false,
|
||||
hasCheckedAllResolved: false,
|
||||
imageUrls: null,
|
||||
isLandscape: false,
|
||||
mediaLoaded: false,
|
||||
|
@ -102,17 +103,14 @@ class FilePage extends React.PureComponent {
|
|||
onComponentFocused = () => {
|
||||
StatusBar.setHidden(false);
|
||||
NativeModules.Firebase.setCurrentScreen('File').then(result => {
|
||||
DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted);
|
||||
DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated);
|
||||
DeviceEventEmitter.addListener('onDownloadCompleted', this.handleDownloadCompleted);
|
||||
DeviceEventEmitter.addListener('onStoragePermissionGranted', this.handleStoragePermissionGranted);
|
||||
DeviceEventEmitter.addListener('onStoragePermissionRefused', this.handleStoragePermissionRefused);
|
||||
|
||||
const { fetchMyClaims, fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
|
||||
const { claim, fetchMyClaims, fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
|
||||
const { uri, uriVars } = navigation.state.params;
|
||||
this.setState({ uri, uriVars });
|
||||
|
||||
if (!isResolvingUri) resolveUri(uri);
|
||||
if (!isResolvingUri && !claim) resolveUri(uri);
|
||||
|
||||
this.fetchFileInfo(this.props);
|
||||
this.fetchCostInfo(this.props);
|
||||
|
@ -149,6 +147,7 @@ class FilePage extends React.PureComponent {
|
|||
navigation,
|
||||
contentType,
|
||||
notify,
|
||||
recommendedContent: prevRecommendedContent,
|
||||
drawerStack: prevDrawerStack,
|
||||
} = this.props;
|
||||
const { uri } = navigation.state.params;
|
||||
|
@ -160,6 +159,8 @@ class FilePage extends React.PureComponent {
|
|||
purchaseUriErrorMessage,
|
||||
streamingUrl,
|
||||
drawerStack,
|
||||
recommendedContent,
|
||||
resolveUris,
|
||||
} = nextProps;
|
||||
|
||||
if (Constants.ROUTE_FILE === currentRoute && currentRoute !== prevRoute) {
|
||||
|
@ -175,10 +176,7 @@ class FilePage extends React.PureComponent {
|
|||
|
||||
const mediaType = Lbry.getMediaType(contentType);
|
||||
const isPlayable = mediaType === 'video' || mediaType === 'audio';
|
||||
if (
|
||||
(this.state.fileGetStarted || prevPurchasedUris.length !== purchasedUris.length) &&
|
||||
NativeModules.UtilityModule
|
||||
) {
|
||||
if (this.state.fileGetStarted || prevPurchasedUris.length !== purchasedUris.length) {
|
||||
const { permanent_url: permanentUrl } = claim;
|
||||
if (purchasedUris.includes(uri) || purchasedUris.includes(permanentUrl)) {
|
||||
const { nout, txid } = claim;
|
||||
|
@ -215,9 +213,23 @@ class FilePage extends React.PureComponent {
|
|||
if (claim && !this.state.viewCountFetched) {
|
||||
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 {
|
||||
claim,
|
||||
contentType,
|
||||
|
@ -227,7 +239,6 @@ class FilePage extends React.PureComponent {
|
|||
resolveUri,
|
||||
navigation,
|
||||
purchaseUri,
|
||||
searchRecommended,
|
||||
title,
|
||||
} = this.props;
|
||||
const { uri } = this.state;
|
||||
|
@ -235,10 +246,6 @@ class FilePage extends React.PureComponent {
|
|||
resolveUri(uri);
|
||||
}
|
||||
|
||||
/* if (title && !this.state.didSearchRecommended) {
|
||||
this.setState({ didSearchRecommended: true }, () => searchRecommended(title));
|
||||
} */
|
||||
|
||||
// Returned to the page. If mediaLoaded, and currentMediaInfo is different, update
|
||||
if (this.state.mediaLoaded && window.currentMediaInfo && window.currentMediaInfo.uri !== this.state.uri) {
|
||||
const { metadata } = this.props;
|
||||
|
@ -390,31 +397,10 @@ class FilePage extends React.PureComponent {
|
|||
}
|
||||
window.player = null;
|
||||
|
||||
DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted);
|
||||
DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated);
|
||||
DeviceEventEmitter.removeListener('onDownloadCompleted', this.handleDownloadCompleted);
|
||||
DeviceEventEmitter.removeListener('onStoragePermissionGranted', this.handleStoragePermissionGranted);
|
||||
DeviceEventEmitter.removeListener('onStoragePermissionRefused', this.handleStoragePermissionRefused);
|
||||
}
|
||||
|
||||
handleDownloadStarted = evt => {
|
||||
const { startDownload } = this.props;
|
||||
const { uri, outpoint, fileInfo } = evt;
|
||||
startDownload(uri, outpoint, fileInfo);
|
||||
};
|
||||
|
||||
handleDownloadUpdated = evt => {
|
||||
const { updateDownload } = this.props;
|
||||
const { uri, outpoint, fileInfo, progress } = evt;
|
||||
updateDownload(uri, outpoint, fileInfo, progress);
|
||||
};
|
||||
|
||||
handleDownloadCompleted = evt => {
|
||||
const { completeDownload } = this.props;
|
||||
const { uri, outpoint, fileInfo } = evt;
|
||||
completeDownload(uri, outpoint, fileInfo);
|
||||
};
|
||||
|
||||
handleStoragePermissionGranted = () => {
|
||||
// permission was allowed. proceed to download
|
||||
const { notify } = this.props;
|
||||
|
@ -538,6 +524,7 @@ class FilePage extends React.PureComponent {
|
|||
};
|
||||
|
||||
onPlaybackStarted = () => {
|
||||
const { searchRecommended, title } = this.props;
|
||||
let timeToStartMillis, timeToStart;
|
||||
if (this.startTime) {
|
||||
timeToStartMillis = Date.now() - this.startTime;
|
||||
|
@ -555,6 +542,11 @@ class FilePage extends React.PureComponent {
|
|||
payload['time_to_start_ms'] = timeToStartMillis;
|
||||
}
|
||||
NativeModules.Firebase.track('play', payload);
|
||||
|
||||
// only fetch recommended content after playback has started
|
||||
if (title) {
|
||||
searchRecommended(title);
|
||||
}
|
||||
};
|
||||
|
||||
onPlaybackFinished = () => {
|
||||
|
@ -748,7 +740,7 @@ class FilePage extends React.PureComponent {
|
|||
let innerContent = null;
|
||||
if ((isResolvingUri && !claim) || !claim) {
|
||||
return (
|
||||
<View style={filePageStyle.container}>
|
||||
<View style={filePageStyle.pageContainer}>
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
{isResolvingUri && (
|
||||
<View style={filePageStyle.busyContainer}>
|
||||
|
@ -786,13 +778,7 @@ class FilePage extends React.PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
if (claim) {
|
||||
if (isChannel) {
|
||||
return <ChannelPage uri={uri} navigation={navigation} />;
|
||||
}
|
||||
|
||||
let isClaimBlackListed = false;
|
||||
|
||||
if (blackListedOutpoints) {
|
||||
for (let i = 0; i < blackListedOutpoints.length; i += 1) {
|
||||
const outpoint = blackListedOutpoints[i];
|
||||
|
@ -804,8 +790,7 @@ class FilePage extends React.PureComponent {
|
|||
}
|
||||
|
||||
if (isClaimBlackListed) {
|
||||
return (
|
||||
<View style={filePageStyle.pageContainer}>
|
||||
innerContent = (
|
||||
<View style={filePageStyle.dmcaContainer}>
|
||||
<Text style={filePageStyle.dmcaText}>
|
||||
{__(
|
||||
|
@ -814,8 +799,6 @@ class FilePage extends React.PureComponent {
|
|||
</Text>
|
||||
<Link style={filePageStyle.dmcaLink} href="https://lbry.com/faq/dmca" text={__('Read More')} />
|
||||
</View>
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -871,12 +854,17 @@ class FilePage extends React.PureComponent {
|
|||
const localFileUri = this.localUriForFileInfo(fileInfo);
|
||||
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 }, () => {
|
||||
if (!isPlayable) {
|
||||
this.checkStoragePermissionForDownload();
|
||||
} else {
|
||||
purchaseUri(uri, costInfo, !isPlayable);
|
||||
purchaseUri(claim.permanent_url, costInfo, !isPlayable);
|
||||
}
|
||||
NativeModules.UtilityModule.checkDownloads();
|
||||
});
|
||||
|
@ -887,13 +875,16 @@ class FilePage extends React.PureComponent {
|
|||
this.setState({ autoOpened: true }, () => this.openFile(localFileUri, mediaType));
|
||||
}
|
||||
|
||||
if (isChannel) {
|
||||
return <ChannelPage uri={uri} navigation={navigation} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={filePageStyle.pageContainer}>
|
||||
{!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />}
|
||||
{this.state.showWebView && isWebViewable && (
|
||||
<WebView allowFileAccess source={{ uri: localFileUri }} style={filePageStyle.viewer} />
|
||||
)}
|
||||
|
||||
{this.state.showImageViewer && (
|
||||
<ImageViewer
|
||||
style={StyleSheet.flatten(filePageStyle.viewer)}
|
||||
|
@ -901,7 +892,6 @@ class FilePage extends React.PureComponent {
|
|||
renderIndicator={() => null}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!this.state.showWebView && (
|
||||
<View
|
||||
style={
|
||||
|
@ -960,11 +950,7 @@ class FilePage extends React.PureComponent {
|
|||
/>
|
||||
)}
|
||||
{!fileInfo && (
|
||||
<FilePrice
|
||||
uri={uri}
|
||||
style={filePageStyle.filePriceContainer}
|
||||
textStyle={filePageStyle.filePriceText}
|
||||
/>
|
||||
<FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />
|
||||
)}
|
||||
|
||||
<TouchableOpacity style={filePageStyle.backButton} onPress={this.onBackButtonPressed}>
|
||||
|
@ -996,7 +982,7 @@ class FilePage extends React.PureComponent {
|
|||
uri={uri}
|
||||
source={this.playerUriForFileInfo(fileInfo)}
|
||||
style={playerStyle}
|
||||
autoPlay={autoplay || this.state.autoPlayMedia}
|
||||
autoPlay
|
||||
onFullscreenToggled={this.handleFullscreenToggle}
|
||||
onLayout={evt => {
|
||||
if (!this.state.playerHeight) {
|
||||
|
@ -1197,7 +1183,7 @@ class FilePage extends React.PureComponent {
|
|||
{isSearchingRecommendContent && (
|
||||
<ActivityIndicator size="small" color={Colors.NextLbryGreen} style={filePageStyle.relatedLoading} />
|
||||
)}
|
||||
{false && !isSearchingRecommendContent && recommendedContent && recommendedContent.length > 0 && (
|
||||
{!isSearchingRecommendContent && recommendedContent && recommendedContent.length > 0 && (
|
||||
<RelatedContent navigation={navigation} uri={uri} fullUri={fullUri} />
|
||||
)}
|
||||
</ScrollView>
|
||||
|
@ -1220,9 +1206,6 @@ class FilePage extends React.PureComponent {
|
|||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default FilePage;
|
||||
|
|
|
@ -94,6 +94,11 @@ const fileListStyle = StyleSheet.create({
|
|||
top: 8,
|
||||
left: 8,
|
||||
},
|
||||
featuredDownloadedIcon: {
|
||||
position: 'absolute',
|
||||
left: 16,
|
||||
top: 16,
|
||||
},
|
||||
fileItem: {
|
||||
marginLeft: 24,
|
||||
marginRight: 24,
|
||||
|
|
Loading…
Reference in a new issue