diff --git a/app/src/index.js b/app/src/index.js
index 15e7276..9401201 100644
--- a/app/src/index.js
+++ b/app/src/index.js
@@ -10,6 +10,7 @@ import {
} from 'react-native';
import {
Lbry,
+ blacklistReducer,
claimsReducer,
costInfoReducer,
fileInfoReducer,
@@ -68,6 +69,7 @@ const navigatorReducer = (state = initialNavState, action) => {
const reducers = combineReducers({
auth: authReducer,
+ blacklist: blacklistReducer,
claims: claimsReducer,
costInfo: costInfoReducer,
fileInfo: fileInfoReducer,
diff --git a/app/src/page/file/view.js b/app/src/page/file/view.js
index 2cd0d9d..5e399d6 100644
--- a/app/src/page/file/view.js
+++ b/app/src/page/file/view.js
@@ -329,144 +329,170 @@ class FilePage extends React.PureComponent {
);
} else if (claim) {
- 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;
+ let isClaimBlackListed = false;
- 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
- });
+ if (blackListedOutpoints) {
+ for (let i = 0; i < blackListedOutpoints.length; i += 1) {
+ const outpoint = blackListedOutpoints[i];
+ if (outpoint.txid === claim.txid && outpoint.nout === claim.nout) {
+ isClaimBlackListed = true;
+ break;
+ }
}
}
- innerContent = (
-
- {this.state.showWebView && isWebViewable && }
-
- {this.state.showImageViewer && null} />}
-
- {!this.state.showWebView && (
-
-
- {((canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) || (!canOpen && fileInfo)) &&
- }
- {((!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded) &&
- }
- {((isPlayable && !completed && !canLoadMedia) || !completed || canOpen) && (!this.state.downloadPressed) &&
- {
- 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 && }
-
- {canLoadMedia && fileInfo && { this.playerBackground = ref; }}
- onLayout={(evt) => {
- if (!this.state.playerBgHeight) {
- this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
- }
- }} />}
- {canLoadMedia && fileInfo && { 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 &&
-
- {completed && }
- {!completed && fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes &&
-
- }
- }
-
- {title}
- {channelName && {
- const channelUri = normalizeURI(channelName);
- navigateToUri(navigation, channelUri);
- }} />}
-
- {description && description.length > 0 && }
-
- {description && {this.linkify(description)}}
-
-
-
+ if (isClaimBlackListed) {
+ innerContent = (
+
+
+
+ In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications.
+
+
- )}
- {!this.state.fullscreenMode && }
- {!this.state.fullscreenMode && }
-
- );
+
+
+ );
+ } 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 = (
+
+ {this.state.showWebView && isWebViewable && }
+
+ {this.state.showImageViewer && null} />}
+
+ {!this.state.showWebView && (
+
+
+ {((canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) || (!canOpen && fileInfo)) &&
+ }
+ {((!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded) &&
+ }
+ {((isPlayable && !completed && !canLoadMedia) || !completed || canOpen) && (!this.state.downloadPressed) &&
+ {
+ 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 && }
+
+ {canLoadMedia && fileInfo && { this.playerBackground = ref; }}
+ onLayout={(evt) => {
+ if (!this.state.playerBgHeight) {
+ this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
+ }
+ }} />}
+ {canLoadMedia && fileInfo && { 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 &&
+
+ {completed && }
+ {!completed && fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes &&
+
+ }
+ }
+
+ {title}
+ {channelName && {
+ const channelUri = normalizeURI(channelName);
+ navigateToUri(navigation, channelUri);
+ }} />}
+
+ {description && description.length > 0 && }
+
+ {description && {this.linkify(description)}}
+
+
+
+
+ )}
+ {!this.state.fullscreenMode && }
+ {!this.state.fullscreenMode && }
+
+ );
+ }
}
return innerContent;
diff --git a/app/src/page/splash/index.js b/app/src/page/splash/index.js
index f85f128..2116937 100644
--- a/app/src/page/splash/index.js
+++ b/app/src/page/splash/index.js
@@ -1,5 +1,5 @@
import { connect } from 'react-redux';
-import { doBalanceSubscribe, doNotify } from 'lbry-redux';
+import { doBalanceSubscribe, doBlackListedOutpointsSubscribe, doNotify } from 'lbry-redux';
import {
doAuthenticate,
doFetchRewardedContent,
@@ -20,6 +20,7 @@ const select = state => ({
const perform = dispatch => ({
authenticate: (appVersion, os) => dispatch(doAuthenticate(appVersion, os)),
balanceSubscribe: () => dispatch(doBalanceSubscribe()),
+ blacklistedOutpointsSubscribe: () => dispatch(doBlackListedOutpointsSubscribe()),
deleteCompleteBlobs: () => dispatch(doDeleteCompleteBlobs()),
fetchRewardedContent: () => dispatch(doFetchRewardedContent()),
notify: data => dispatch(doNotify(data)),
diff --git a/app/src/page/splash/view.js b/app/src/page/splash/view.js
index c84d370..e1acafb 100644
--- a/app/src/page/splash/view.js
+++ b/app/src/page/splash/view.js
@@ -144,11 +144,13 @@ class SplashScreen extends React.PureComponent {
const {
authenticate,
balanceSubscribe,
+ blacklistedOutpointsSubscribe,
navigation,
notify
} = this.props;
balanceSubscribe();
+ blacklistedOutpointsSubscribe();
NativeModules.VersionInfo.getAppVersion().then(appVersion => {
this.setState({ shouldAuthenticate: true });
authenticate(appVersion, Platform.OS);
diff --git a/app/src/styles/filePage.js b/app/src/styles/filePage.js
index df9a9cd..76a6955 100644
--- a/app/src/styles/filePage.js
+++ b/app/src/styles/filePage.js
@@ -165,6 +165,25 @@ const filePageStyle = StyleSheet.create({
alignItems: 'center',
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: {
fontFamily: 'Metropolis-Regular',
fontSize: 20,