show blocked message for blacklisted content

This commit is contained in:
Akinwale Ariwodola 2018-09-24 14:19:34 +01:00
parent d921347d73
commit 51fcf04b0b
5 changed files with 184 additions and 134 deletions

View file

@ -10,6 +10,7 @@ import {
} from 'react-native'; } from 'react-native';
import { import {
Lbry, Lbry,
blacklistReducer,
claimsReducer, claimsReducer,
costInfoReducer, costInfoReducer,
fileInfoReducer, fileInfoReducer,
@ -68,6 +69,7 @@ const navigatorReducer = (state = initialNavState, action) => {
const reducers = combineReducers({ const reducers = combineReducers({
auth: authReducer, auth: authReducer,
blacklist: blacklistReducer,
claims: claimsReducer, claims: claimsReducer,
costInfo: costInfoReducer, costInfo: costInfoReducer,
fileInfo: fileInfoReducer, fileInfo: fileInfoReducer,

View file

@ -329,144 +329,170 @@ class FilePage extends React.PureComponent {
<ChannelPage uri={uri} navigation={navigation} /> <ChannelPage uri={uri} navigation={navigation} />
); );
} else if (claim) { } else if (claim) {
const completed = fileInfo && fileInfo.completed; let isClaimBlackListed = false;
const title = metadata.title;
const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id);
const description = metadata.description ? metadata.description : null;
const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio';
const { height, channel_name: channelName, value } = claim;
const showActions = !this.state.fullscreenMode && !this.state.showImageViewer && !this.state.showWebView &&
(completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
const channelClaimId =
value && value.publisherSignature && value.publisherSignature.certificateId;
const playerStyle = [filePageStyle.player, if (blackListedOutpoints) {
this.state.isLandscape ? filePageStyle.containedPlayerLandscape : for (let i = 0; i < blackListedOutpoints.length; i += 1) {
(this.state.fullscreenMode ? filePageStyle.fullscreenPlayer : filePageStyle.containedPlayer)]; const outpoint = blackListedOutpoints[i];
const playerBgStyle = [filePageStyle.playerBackground, this.state.fullscreenMode ? if (outpoint.txid === claim.txid && outpoint.nout === claim.nout) {
filePageStyle.fullscreenPlayerBackground : filePageStyle.containedPlayerBackground]; isClaimBlackListed = true;
// at least 2MB (or the full download) before media can be loaded break;
const canLoadMedia = fileInfo && }
(fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes == fileInfo.total_bytes); // 2MB = 1024*1024*2
const canOpen = (mediaType === 'image' || mediaType === 'text') && completed;
const isWebViewable = mediaType === 'text';
const localFileUri = this.localUriForFileInfo(fileInfo);
const openFile = () => {
if (mediaType === 'image') {
// use image viewer
this.setState({
imageUrls: [{
url: localFileUri
}],
showImageViewer: true
});
}
if (isWebViewable) {
// show webview
this.setState({
showWebView: true
});
} }
} }
innerContent = ( if (isClaimBlackListed) {
<View style={filePageStyle.pageContainer}> innerContent = (
{this.state.showWebView && isWebViewable && <WebView source={{ uri: localFileUri }} <View style={filePageStyle.pageContainer}>
style={filePageStyle.viewer} />} <View style={filePageStyle.dmcaContainer}>
<Text style={filePageStyle.dmcaText}>
{this.state.showImageViewer && <ImageViewer style={StyleSheet.flatten(filePageStyle.viewer)} In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications.
imageUrls={this.state.imageUrls} </Text>
renderIndicator={() => null} />} <Link style={filePageStyle.dmcaLink} href="https://lbry.io/faq/dmca" text="Read More" />
{!this.state.showWebView && (
<View style={this.state.fullscreenMode ? filePageStyle.innerPageContainerFsMode : filePageStyle.innerPageContainer}
onLayout={this.checkOrientation}>
<View style={filePageStyle.mediaContainer}>
{((canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) || (!canOpen && fileInfo)) &&
<FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={metadata.thumbnail} />}
{((!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded) &&
<ActivityIndicator size="large" color={Colors.LbryGreen} style={filePageStyle.loading} />}
{((isPlayable && !completed && !canLoadMedia) || !completed || canOpen) && (!this.state.downloadPressed) &&
<FileDownloadButton uri={uri}
style={filePageStyle.downloadButton}
openFile={openFile}
isPlayable={isPlayable}
onPlay={() => {
this.startTime = Date.now();
this.setState({ downloadPressed: true, autoPlayMedia: true });
}}
onButtonLayout={() => this.setState({ downloadButtonShown: true })}
onStartDownloadFailed={() => {
this.startTime = null;
setTimeout(() => {
this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false });
}, 500);
}} />}
{!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />}
</View>
{canLoadMedia && fileInfo && <View style={playerBgStyle}
ref={(ref) => { this.playerBackground = ref; }}
onLayout={(evt) => {
if (!this.state.playerBgHeight) {
this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
}
}} />}
{canLoadMedia && fileInfo && <MediaPlayer
fileInfo={fileInfo}
assignPlayer={(ref) => { this.player = ref; }}
uri={uri}
style={playerStyle}
autoPlay={autoplay || this.state.autoPlayMedia}
onFullscreenToggled={this.handleFullscreenToggle}
onLayout={(evt) => {
if (!this.state.playerHeight) {
this.setState({ playerHeight: evt.nativeEvent.layout.height });
}
}}
onMediaLoaded={() => this.onMediaLoaded(channelName, title, uri)}
onPlaybackStarted={this.onPlaybackStarted}
/>}
{ showActions &&
<View style={filePageStyle.actions}>
{completed && <Button style={filePageStyle.actionButton}
theme={"light"}
icon={"trash"}
text={"Delete"}
onPress={this.onDeletePressed} />}
{!completed && fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes &&
<Button style={filePageStyle.actionButton}
theme={"light"}
text={"Stop Download"}
onPress={this.onStopDownloadPressed} />
}
</View>}
<ScrollView
style={showActions ? filePageStyle.scrollContainerActions : filePageStyle.scrollContainer}
contentContainerstyle={showActions ? null : filePageStyle.scrollContent}>
<Text style={filePageStyle.title} selectable={true}>{title}</Text>
{channelName && <Link style={filePageStyle.channelName}
selectable={true}
text={channelName}
onPress={() => {
const channelUri = normalizeURI(channelName);
navigateToUri(navigation, channelUri);
}} />}
{description && description.length > 0 && <View style={filePageStyle.divider} />}
{description && <Text style={filePageStyle.description} selectable={true}>{this.linkify(description)}</Text>}
<RelatedContent navigation={navigation} uri={uri} />
</ScrollView>
</View> </View>
)} <UriBar value={uri} navigation={navigation} />
{!this.state.fullscreenMode && <FloatingWalletBalance navigation={navigation} />} </View>
{!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />} );
</View> } else {
); const completed = fileInfo && fileInfo.completed;
const title = metadata.title;
const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id);
const description = metadata.description ? metadata.description : null;
const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio';
const { height, channel_name: channelName, value } = claim;
const showActions = !this.state.fullscreenMode && !this.state.showImageViewer && !this.state.showWebView &&
(completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
const channelClaimId =
value && value.publisherSignature && value.publisherSignature.certificateId;
const playerStyle = [filePageStyle.player,
this.state.isLandscape ? filePageStyle.containedPlayerLandscape :
(this.state.fullscreenMode ? filePageStyle.fullscreenPlayer : filePageStyle.containedPlayer)];
const playerBgStyle = [filePageStyle.playerBackground, this.state.fullscreenMode ?
filePageStyle.fullscreenPlayerBackground : filePageStyle.containedPlayerBackground];
// at least 2MB (or the full download) before media can be loaded
const canLoadMedia = fileInfo &&
(fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes == fileInfo.total_bytes); // 2MB = 1024*1024*2
const canOpen = (mediaType === 'image' || mediaType === 'text') && completed;
const isWebViewable = mediaType === 'text';
const localFileUri = this.localUriForFileInfo(fileInfo);
const openFile = () => {
if (mediaType === 'image') {
// use image viewer
this.setState({
imageUrls: [{
url: localFileUri
}],
showImageViewer: true
});
}
if (isWebViewable) {
// show webview
this.setState({
showWebView: true
});
}
}
innerContent = (
<View style={filePageStyle.pageContainer}>
{this.state.showWebView && isWebViewable && <WebView source={{ uri: localFileUri }}
style={filePageStyle.viewer} />}
{this.state.showImageViewer && <ImageViewer style={StyleSheet.flatten(filePageStyle.viewer)}
imageUrls={this.state.imageUrls}
renderIndicator={() => null} />}
{!this.state.showWebView && (
<View style={this.state.fullscreenMode ? filePageStyle.innerPageContainerFsMode : filePageStyle.innerPageContainer}
onLayout={this.checkOrientation}>
<View style={filePageStyle.mediaContainer}>
{((canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) || (!canOpen && fileInfo)) &&
<FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={metadata.thumbnail} />}
{((!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded) &&
<ActivityIndicator size="large" color={Colors.LbryGreen} style={filePageStyle.loading} />}
{((isPlayable && !completed && !canLoadMedia) || !completed || canOpen) && (!this.state.downloadPressed) &&
<FileDownloadButton uri={uri}
style={filePageStyle.downloadButton}
openFile={openFile}
isPlayable={isPlayable}
onPlay={() => {
this.startTime = Date.now();
this.setState({ downloadPressed: true, autoPlayMedia: true });
}}
onButtonLayout={() => this.setState({ downloadButtonShown: true })}
onStartDownloadFailed={() => {
this.startTime = null;
setTimeout(() => {
this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false });
}, 500);
}} />}
{!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />}
</View>
{canLoadMedia && fileInfo && <View style={playerBgStyle}
ref={(ref) => { this.playerBackground = ref; }}
onLayout={(evt) => {
if (!this.state.playerBgHeight) {
this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
}
}} />}
{canLoadMedia && fileInfo && <MediaPlayer
fileInfo={fileInfo}
assignPlayer={(ref) => { this.player = ref; }}
uri={uri}
style={playerStyle}
autoPlay={autoplay || this.state.autoPlayMedia}
onFullscreenToggled={this.handleFullscreenToggle}
onLayout={(evt) => {
if (!this.state.playerHeight) {
this.setState({ playerHeight: evt.nativeEvent.layout.height });
}
}}
onMediaLoaded={() => this.onMediaLoaded(channelName, title, uri)}
onPlaybackStarted={this.onPlaybackStarted}
/>}
{ showActions &&
<View style={filePageStyle.actions}>
{completed && <Button style={filePageStyle.actionButton}
theme={"light"}
icon={"trash"}
text={"Delete"}
onPress={this.onDeletePressed} />}
{!completed && fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes &&
<Button style={filePageStyle.actionButton}
theme={"light"}
text={"Stop Download"}
onPress={this.onStopDownloadPressed} />
}
</View>}
<ScrollView
style={showActions ? filePageStyle.scrollContainerActions : filePageStyle.scrollContainer}
contentContainerstyle={showActions ? null : filePageStyle.scrollContent}>
<Text style={filePageStyle.title} selectable={true}>{title}</Text>
{channelName && <Link style={filePageStyle.channelName}
selectable={true}
text={channelName}
onPress={() => {
const channelUri = normalizeURI(channelName);
navigateToUri(navigation, channelUri);
}} />}
{description && description.length > 0 && <View style={filePageStyle.divider} />}
{description && <Text style={filePageStyle.description} selectable={true}>{this.linkify(description)}</Text>}
<RelatedContent navigation={navigation} uri={uri} />
</ScrollView>
</View>
)}
{!this.state.fullscreenMode && <FloatingWalletBalance navigation={navigation} />}
{!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />}
</View>
);
}
} }
return innerContent; return innerContent;

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doBalanceSubscribe, doNotify } from 'lbry-redux'; import { doBalanceSubscribe, doBlackListedOutpointsSubscribe, doNotify } from 'lbry-redux';
import { import {
doAuthenticate, doAuthenticate,
doFetchRewardedContent, doFetchRewardedContent,
@ -20,6 +20,7 @@ const select = state => ({
const perform = dispatch => ({ const perform = dispatch => ({
authenticate: (appVersion, os) => dispatch(doAuthenticate(appVersion, os)), authenticate: (appVersion, os) => dispatch(doAuthenticate(appVersion, os)),
balanceSubscribe: () => dispatch(doBalanceSubscribe()), balanceSubscribe: () => dispatch(doBalanceSubscribe()),
blacklistedOutpointsSubscribe: () => dispatch(doBlackListedOutpointsSubscribe()),
deleteCompleteBlobs: () => dispatch(doDeleteCompleteBlobs()), deleteCompleteBlobs: () => dispatch(doDeleteCompleteBlobs()),
fetchRewardedContent: () => dispatch(doFetchRewardedContent()), fetchRewardedContent: () => dispatch(doFetchRewardedContent()),
notify: data => dispatch(doNotify(data)), notify: data => dispatch(doNotify(data)),

View file

@ -144,11 +144,13 @@ class SplashScreen extends React.PureComponent {
const { const {
authenticate, authenticate,
balanceSubscribe, balanceSubscribe,
blacklistedOutpointsSubscribe,
navigation, navigation,
notify notify
} = this.props; } = this.props;
balanceSubscribe(); balanceSubscribe();
blacklistedOutpointsSubscribe();
NativeModules.VersionInfo.getAppVersion().then(appVersion => { NativeModules.VersionInfo.getAppVersion().then(appVersion => {
this.setState({ shouldAuthenticate: true }); this.setState({ shouldAuthenticate: true });
authenticate(appVersion, Platform.OS); authenticate(appVersion, Platform.OS);

View file

@ -165,6 +165,25 @@ const filePageStyle = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
flexDirection: 'row' flexDirection: 'row'
}, },
dmcaContainer: {
flex: 1,
alignItems: 'flex-start',
justifyContent: 'center',
paddingLeft: 24,
paddingRight: 24
},
dmcaText: {
fontFamily: 'Metropolis-Regular',
fontSize: 18,
lineHeight: 24
},
dmcaLink: {
color: Colors.LbryGreen,
fontFamily: 'Metropolis-Regular',
fontSize: 18,
lineHeight: 24,
marginTop: 24
},
infoText: { infoText: {
fontFamily: 'Metropolis-Regular', fontFamily: 'Metropolis-Regular',
fontSize: 20, fontSize: 20,