diff --git a/ui/js/component/fileCard/view.jsx b/ui/js/component/fileCard/view.jsx
index 41e1b40a9..42c0e5b68 100644
--- a/ui/js/component/fileCard/view.jsx
+++ b/ui/js/component/fileCard/view.jsx
@@ -1,10 +1,10 @@
import React from "react";
-import lbry from "lbry.js";
import lbryuri from "lbryuri.js";
import Link from "component/link";
-import { Thumbnail, TruncatedText, Icon } from "component/common";
+import { TruncatedText, Icon } from "component/common";
import FilePrice from "component/filePrice";
import UriIndicator from "component/uriIndicator";
+import NsfwOverlay from "component/nsfwOverlay";
class FileCard extends React.PureComponent {
constructor(props) {
@@ -97,22 +97,8 @@ class FileCard extends React.PureComponent {
{description}
- {obscureNsfw &&
- this.state.hovered &&
-
-
- {__(
- "This content is Not Safe For Work. To view adult content, please change your"
- )}
- {" "}
- navigate("settings")}
- label={__("Settings")}
- />.
-
-
}
+ {obscureNsfw && this.state.hovered && }
);
}
diff --git a/ui/js/component/fileTile/view.jsx b/ui/js/component/fileTile/view.jsx
index 09a4363ad..c0c25a202 100644
--- a/ui/js/component/fileTile/view.jsx
+++ b/ui/js/component/fileTile/view.jsx
@@ -2,10 +2,9 @@ import React from "react";
import lbry from "lbry.js";
import lbryuri from "lbryuri.js";
import Link from "component/link";
-import FileActions from "component/fileActions";
-import { Thumbnail, TruncatedText } from "component/common.js";
+import { TruncatedText } from "component/common.js";
import FilePrice from "component/filePrice";
-import UriIndicator from "component/uriIndicator";
+import NsfwOverlay from "component/nsfwOverlay";
class FileTile extends React.PureComponent {
static SHOW_EMPTY_PUBLISH = "publish";
@@ -124,20 +123,7 @@ class FileTile extends React.PureComponent {
- {this.state.showNsfwHelp &&
-
-
- {__(
- "This content is Not Safe For Work. To view adult content, please change your"
- )}
- {" "}
- navigate("/settings")}
- label={__("Settings")}
- />.
-
-
}
+ {this.state.showNsfwHelp && }
);
}
diff --git a/ui/js/component/nsfwOverlay/index.js b/ui/js/component/nsfwOverlay/index.js
new file mode 100644
index 000000000..eb3242410
--- /dev/null
+++ b/ui/js/component/nsfwOverlay/index.js
@@ -0,0 +1,10 @@
+import React from "react";
+import { connect } from "react-redux";
+import { doNavigate } from "actions/app";
+import NsfwOverlay from "./view";
+
+const perform = dispatch => ({
+ navigateSettings: () => dispatch(doNavigate("/settings")),
+});
+
+export default connect(null, perform)(NsfwOverlay);
diff --git a/ui/js/component/nsfwOverlay/view.jsx b/ui/js/component/nsfwOverlay/view.jsx
new file mode 100644
index 000000000..89c3705c7
--- /dev/null
+++ b/ui/js/component/nsfwOverlay/view.jsx
@@ -0,0 +1,22 @@
+import React from "react";
+import Link from "component/link";
+
+const NsfwOverlay = props => {
+ return (
+
+
+ {__(
+ "This content is Not Safe For Work. To view adult content, please change your"
+ )}{" "}
+ {" "}{" "}
+ props.navigateSettings()}
+ label={__("Settings")}
+ />.
+
+
+ );
+};
+
+export default NsfwOverlay;
diff --git a/ui/js/component/video/index.js b/ui/js/component/video/index.js
index 3cf917a75..97345a368 100644
--- a/ui/js/component/video/index.js
+++ b/ui/js/component/video/index.js
@@ -1,6 +1,7 @@
import React from "react";
import { connect } from "react-redux";
import { doCloseModal } from "actions/app";
+import { doNavigate } from "actions/app";
import { selectCurrentModal } from "selectors/app";
import { doPurchaseUri, doLoadVideo } from "actions/content";
import {
@@ -13,6 +14,7 @@ import {
makeSelectDownloadingForUri,
} from "selectors/file_info";
import { makeSelectCostInfoForUri } from "selectors/cost_info";
+import { selectObscureNsfw } from "selectors/app";
import Video from "./view";
const makeSelect = () => {
@@ -27,6 +29,7 @@ const makeSelect = () => {
costInfo: selectCostInfo(state, props),
fileInfo: selectFileInfo(state, props),
metadata: selectMetadata(state, props),
+ obscureNsfw: selectObscureNsfw(state),
modal: selectCurrentModal(state),
isLoading: selectIsLoading(state, props),
isDownloading: selectIsDownloading(state, props),
diff --git a/ui/js/component/video/view.jsx b/ui/js/component/video/view.jsx
index f7f9007ac..c3cb499b9 100644
--- a/ui/js/component/video/view.jsx
+++ b/ui/js/component/video/view.jsx
@@ -3,11 +3,15 @@ import lbry from "lbry";
import VideoPlayer from "./internal/player";
import VideoPlayButton from "./internal/play-button";
import LoadingScreen from "./internal/loading-screen";
+import NsfwOverlay from "component/nsfwOverlay";
class Video extends React.PureComponent {
constructor(props) {
super(props);
- this.state = { isPlaying: false };
+ this.state = {
+ isPlaying: false,
+ showNsfwHelp: false,
+ };
}
startPlaying() {
@@ -16,6 +20,26 @@ class Video extends React.PureComponent {
});
}
+ handleMouseOver() {
+ if (
+ this.props.obscureNsfw &&
+ this.props.metadata &&
+ this.props.metadata.nsfw
+ ) {
+ this.setState({
+ showNsfwHelp: true,
+ });
+ }
+ }
+
+ handleMouseOut() {
+ if (this.state.showNsfwHelp) {
+ this.setState({
+ showNsfwHelp: false,
+ });
+ }
+ }
+
render() {
const {
metadata,
@@ -27,6 +51,7 @@ class Video extends React.PureComponent {
const { isPlaying = false } = this.state;
const isReadyToPlay = fileInfo && fileInfo.written_bytes > 0;
+ const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
const mediaType = lbry.getMediaType(
contentType,
fileInfo && fileInfo.file_name
@@ -47,6 +72,7 @@ class Video extends React.PureComponent {
}
let klasses = [];
+ klasses.push(obscureNsfw ? "video--obscured " : "");
if (isLoading || isDownloading) klasses.push("video-embedded", "video");
if (mediaType === "video") {
klasses.push("video-embedded", "video");
@@ -59,7 +85,11 @@ class Video extends React.PureComponent {
const poster = metadata.thumbnail;
return (
-
+
{isPlaying &&
(!isReadyToPlay
?
@@ -81,6 +111,7 @@ class Video extends React.PureComponent {
mediaType={mediaType}
/>
}
+ {this.state.showNsfwHelp &&
}
);
}
diff --git a/ui/js/lbry.js b/ui/js/lbry.js
index 286218532..6f2891a16 100644
--- a/ui/js/lbry.js
+++ b/ui/js/lbry.js
@@ -321,9 +321,11 @@ lbry.getMediaType = function(contentType, fileName) {
var ext = fileName.substr(dotIndex + 1);
if (/^mp4|m4v|mov|webm|flv|f4v|ogv$/i.test(ext)) {
return "video";
- } else if (/^mp3|m4a|aac|wav|flac|ogg|opus$/i.test(ext)) {
+ } else if (/^mp3|m4a|aac|wav|flac|ogg|opus$/i.test(ext)) {
return "audio";
- } else if (/^html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|org$/i.test(ext)) {
+ } else if (
+ /^html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org$/i.test(ext)
+ ) {
return "document";
} else {
return "unknown";
diff --git a/ui/js/page/filePage/index.js b/ui/js/page/filePage/index.js
index a6781e73a..d7ec5f282 100644
--- a/ui/js/page/filePage/index.js
+++ b/ui/js/page/filePage/index.js
@@ -10,6 +10,7 @@ import {
makeSelectMetadataForUri,
} from "selectors/claims";
import { makeSelectCostInfoForUri } from "selectors/cost_info";
+import { selectObscureNsfw } from "selectors/app";
import FilePage from "./view";
const makeSelect = () => {
@@ -24,6 +25,7 @@ const makeSelect = () => {
contentType: selectContentType(state, props),
costInfo: selectCostInfo(state, props),
metadata: selectMetadata(state, props),
+ obscureNsfw: selectObscureNsfw(state),
fileInfo: selectFileInfo(state, props),
});
diff --git a/ui/js/page/filePage/view.jsx b/ui/js/page/filePage/view.jsx
index 9f3f5fbfe..aef790fc5 100644
--- a/ui/js/page/filePage/view.jsx
+++ b/ui/js/page/filePage/view.jsx
@@ -81,6 +81,7 @@ class FilePage extends React.PureComponent {
const uriIndicator = ;
const mediaType = lbry.getMediaType(contentType);
const player = require("render-media");
+ const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
const isPlayable =
Object.values(player.mime).indexOf(contentType) !== -1 ||
mediaType === "audio";
@@ -94,7 +95,7 @@ class FilePage extends React.PureComponent {
?
: }
-
+
{!fileInfo || fileInfo.written_bytes <= 0
diff --git a/ui/scss/_global.scss b/ui/scss/_global.scss
index 180a9d41c..74dc364c1 100644
--- a/ui/scss/_global.scss
+++ b/ui/scss/_global.scss
@@ -39,7 +39,7 @@ $box-shadow-focus: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2)
$transition-standard: .225s ease;
-$blur-intensity: 8px;
+$blur-intensity-nsfw: 20px;
@mixin clearfix()
{
diff --git a/ui/scss/component/_card.scss b/ui/scss/component/_card.scss
index 4dd88a91e..60b128afd 100644
--- a/ui/scss/component/_card.scss
+++ b/ui/scss/component/_card.scss
@@ -17,11 +17,7 @@ $padding-card-horizontal: $spacing-vertical * 2/3;
position: relative;
}
.card--obscured .card__inner {
- -webkit-filter: blur($blur-intensity);
- -moz-filter: blur($blur-intensity);
- -o-filter: blur($blur-intensity);
- -ms-filter: blur($blur-intensity);
- filter: blur($blur-intensity);
+ filter: blur($blur-intensity-nsfw);
}
.card__title-primary {
padding: 0 $padding-card-horizontal;
diff --git a/ui/scss/component/_video.scss b/ui/scss/component/_video.scss
index e956afe80..745b2d494 100644
--- a/ui/scss/component/_video.scss
+++ b/ui/scss/component/_video.scss
@@ -33,6 +33,11 @@ video {
transform: translateY(-50%);
}
}
+.video--obscured .video__cover
+{
+ position: relative;
+ filter: blur($blur-intensity-nsfw);
+}
.video__loading-screen {