瀏覽代碼

Blur NSFW posts.

Reimplementation of libreddit/libreddit#482.

Co-authored by: Daniel Valentine <Daniel-Valentine@users.noreply.github.com>
NKIPSC 2 年之前
父節點
當前提交
fade305f90
共有 7 個文件被更改,包括 106 次插入49 次删除
  1. 3 0
      app.json
  2. 2 1
      src/settings.rs
  3. 2 0
      src/utils.rs
  4. 37 8
      static/style.css
  5. 22 16
      templates/post.html
  6. 6 1
      templates/settings.html
  7. 34 23
      templates/utils.html

+ 3 - 0
app.json

@@ -32,6 +32,9 @@
     "LIBREDDIT_DEFAULT_SHOW_NSFW": {
     "LIBREDDIT_DEFAULT_SHOW_NSFW": {
       "required": false
       "required": false
     },
     },
+    "LIBREDDIT_DEFAULT_BLUR_NSFW": {
+      "required": false
+    },
     "LIBREDDIT_USE_HLS": {
     "LIBREDDIT_USE_HLS": {
       "required": false
       "required": false
     },
     },

+ 2 - 1
src/settings.rs

@@ -19,7 +19,7 @@ struct SettingsTemplate {
 
 
 // CONSTANTS
 // CONSTANTS
 
 
-const PREFS: [&str; 10] = [
+const PREFS: [&str; 11] = [
 	"theme",
 	"theme",
 	"front_page",
 	"front_page",
 	"layout",
 	"layout",
@@ -27,6 +27,7 @@ const PREFS: [&str; 10] = [
 	"comment_sort",
 	"comment_sort",
 	"post_sort",
 	"post_sort",
 	"show_nsfw",
 	"show_nsfw",
+	"blur_nsfw",
 	"use_hls",
 	"use_hls",
 	"hide_hls_notification",
 	"hide_hls_notification",
 	"autoplay_videos",
 	"autoplay_videos",

+ 2 - 0
src/utils.rs

@@ -462,6 +462,7 @@ pub struct Preferences {
 	pub layout: String,
 	pub layout: String,
 	pub wide: String,
 	pub wide: String,
 	pub show_nsfw: String,
 	pub show_nsfw: String,
+	pub blur_nsfw: String,
 	pub hide_hls_notification: String,
 	pub hide_hls_notification: String,
 	pub use_hls: String,
 	pub use_hls: String,
 	pub autoplay_videos: String,
 	pub autoplay_videos: String,
@@ -493,6 +494,7 @@ impl Preferences {
 			layout: setting(&req, "layout"),
 			layout: setting(&req, "layout"),
 			wide: setting(&req, "wide"),
 			wide: setting(&req, "wide"),
 			show_nsfw: setting(&req, "show_nsfw"),
 			show_nsfw: setting(&req, "show_nsfw"),
+			blur_nsfw: setting(&req, "blur_nsfw"),
 			use_hls: setting(&req, "use_hls"),
 			use_hls: setting(&req, "use_hls"),
 			hide_hls_notification: setting(&req, "hide_hls_notification"),
 			hide_hls_notification: setting(&req, "hide_hls_notification"),
 			autoplay_videos: setting(&req, "autoplay_videos"),
 			autoplay_videos: setting(&req, "autoplay_videos"),

+ 37 - 8
static/style.css

@@ -716,22 +716,39 @@ a.search_subreddit:hover {
 	font-weight: bold;
 	font-weight: bold;
 }
 }
 
 
-.post_media_image, .post .__NoScript_PlaceHolder__, .post_media_video, .gallery {
+.post_media_content, .post .__NoScript_PlaceHolder__, .gallery {
 	max-width: calc(100% - 40px);
 	max-width: calc(100% - 40px);
 	grid-area: post_media;
 	grid-area: post_media;
 	margin: 15px auto 5px auto;
 	margin: 15px auto 5px auto;
+	width: auto;
 	height: auto;
 	height: auto;
+	overflow: hidden;
 }
 }
 
 
-
-.post_media_video.short {
-	max-height: 512px;
+.post_media_video {
 	width: auto;
 	width: auto;
+	height: auto;
+	max-width: 100%;
+	max-height: 512px;
+	display: block;
+	margin: auto;
 }
 }
 
 
 .post_media_image.short svg, .post_media_image.short img{
 .post_media_image.short svg, .post_media_image.short img{
-	max-height: 512px;
 	width: auto;
 	width: auto;
+	height: auto;
+	max-width: 100%;
+	max-height: 512px;
+	display: block;
+	margin: auto;
+}
+
+.post_nsfw_blur {
+	filter: blur(1.5rem);
+}
+
+.post_nsfw_blur:hover {
+	filter: none;
 }
 }
 
 
 .post_media_image svg{
 .post_media_image svg{
@@ -827,13 +844,25 @@ a.search_subreddit:hover {
 	margin: 5px;
 	margin: 5px;
 }
 }
 
 
-.post_thumbnail svg {
+.post_thumbnail div {
 	grid-area: 1 / 1 / 2 / 2;
 	grid-area: 1 / 1 / 2 / 2;
-	width: 100%;
-	height: auto;
 	object-fit: cover;
 	object-fit: cover;
 	align-self: center;
 	align-self: center;
 	justify-self: center;
 	justify-self: center;
+	overflow: hidden;
+}
+
+.post_thumbnail div svg {
+	width: 100%;
+	height: auto;
+}
+
+.post_thumbnail span {
+	z-index: 0;
+}
+
+.thumb_nsfw_blur {
+	filter: blur(0.3rem)
 }
 }
 
 
 .post_thumbnail.no_thumbnail {
 .post_thumbnail.no_thumbnail {

+ 22 - 16
templates/post.html

@@ -68,27 +68,33 @@
 			<!-- POST MEDIA -->
 			<!-- POST MEDIA -->
 			<!-- post_type: {{ post.post_type }} -->
 			<!-- post_type: {{ post.post_type }} -->
 			{% if post.post_type == "image" %}
 			{% if post.post_type == "image" %}
-			<a href="{{ post.media.url }}" class="post_media_image" >
-				<svg
-					width="{{ post.media.width }}px" 
-					height="{{ post.media.height }}px" 
-					xmlns="http://www.w3.org/2000/svg">
-						<image width="100%" height="100%" href="{{ post.media.url }}"/>
-						<desc>
-							<img loading="lazy" alt="Post image" src="{{ post.media.url }}"/>
-						</desc>
-				</svg>
-			</a>
+			<div class="post_media_content">
+				<a href="{{ post.media.url }}" class="post_media_image" >
+					<svg
+						width="{{ post.media.width }}px"
+						height="{{ post.media.height }}px"
+						xmlns="http://www.w3.org/2000/svg">
+							<image width="100%" height="100%" href="{{ post.media.url }}"/>
+							<desc>
+								<img loading="lazy" alt="Post image" src="{{ post.media.url }}"/>
+							</desc>
+					</svg>
+				</a>
+			</div>
 			{% else if post.post_type == "video" || post.post_type == "gif" %}
 			{% else if post.post_type == "video" || post.post_type == "gif" %}
 			{% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %}
 			{% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %}
 			<script src="/hls.min.js"></script>
 			<script src="/hls.min.js"></script>
-			<video class="post_media_video short {% if prefs.autoplay_videos == "on" %}hls_autoplay{% endif %}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls>
-				<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
-				<source src="{{ post.media.url }}" type="video/mp4" />
-			</video>
+			<div class="post_media_content">
+				<video class="post_media_video short {% if prefs.autoplay_videos == "on" %}hls_autoplay{% endif %}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls>
+					<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
+					<source src="{{ post.media.url }}" type="video/mp4" />
+				</video>
+			</div>
 			<script src="/playHLSVideo.js"></script>
 			<script src="/playHLSVideo.js"></script>
 			{% else %}
 			{% else %}
-			<video class="post_media_video" src="{{ post.media.url }}" controls {% if prefs.autoplay_videos == "on" %}autoplay{% endif %} loop><a href={{ post.media.url }}>Video</a></video>
+			<div class="post_media_content">
+				<video class="post_media_video" src="{{ post.media.url }}" controls {% if prefs.autoplay_videos == "on" %}autoplay{% endif %} loop><a href={{ post.media.url }}>Video</a></video>
+			</div>
 			{% call utils::render_hls_notification(post.permalink[1..]) %}
 			{% call utils::render_hls_notification(post.permalink[1..]) %}
 			{% endif %}
 			{% endif %}
 			{% else if post.post_type == "gallery" %}
 			{% else if post.post_type == "gallery" %}

+ 6 - 1
templates/settings.html

@@ -54,6 +54,11 @@
 				<input type="hidden" value="off" name="show_nsfw">
 				<input type="hidden" value="off" name="show_nsfw">
 				<input type="checkbox" name="show_nsfw" {% if prefs.show_nsfw == "on" %}checked{% endif %}>
 				<input type="checkbox" name="show_nsfw" {% if prefs.show_nsfw == "on" %}checked{% endif %}>
 			</div>
 			</div>
+			<div id="blur_nsfw">
+				<label for="blur_nsfw">Blur NSFW previews:</label>
+				<input type="hidden" value="off" name="blur_nsfw">
+				<input type="checkbox" name="blur_nsfw" {% if prefs.blur_nsfw == "on" %}checked{% endif %}>
+			</div>
 			<div id="autoplay_videos">
 			<div id="autoplay_videos">
 				<label for="autoplay_videos">Autoplay videos</label>
 				<label for="autoplay_videos">Autoplay videos</label>
 				<input type="hidden" value="off" name="autoplay_videos">
 				<input type="hidden" value="off" name="autoplay_videos">
@@ -110,7 +115,7 @@
 
 
 	<div id="settings_note">
 	<div id="settings_note">
 		<p><b>Note:</b> settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.</p><br>
 		<p><b>Note:</b> settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.</p><br>
-		<p>You can restore your current settings and subscriptions after clearing your cookies using <a href="/settings/restore/?theme={{ prefs.theme }}&front_page={{ prefs.front_page }}&layout={{ prefs.layout }}&wide={{ prefs.wide }}&post_sort={{ prefs.post_sort }}&comment_sort={{ prefs.comment_sort }}&show_nsfw={{ prefs.show_nsfw }}&use_hls={{ prefs.use_hls }}&hide_hls_notification={{ prefs.hide_hls_notification }}&subscriptions={{ prefs.subscriptions.join("%2B") }}&filters={{ prefs.filters.join("%2B") }}">this link</a>.</p>
+		<p>You can restore your current settings and subscriptions after clearing your cookies using <a href="/settings/restore/?theme={{ prefs.theme }}&front_page={{ prefs.front_page }}&layout={{ prefs.layout }}&wide={{ prefs.wide }}&post_sort={{ prefs.post_sort }}&comment_sort={{ prefs.comment_sort }}&show_nsfw={{ prefs.show_nsfw }}&blur_nsfw={{ prefs.blur_nsfw }}&use_hls={{ prefs.use_hls }}&hide_hls_notification={{ prefs.hide_hls_notification }}&subscriptions={{ prefs.subscriptions.join("%2B") }}&filters={{ prefs.filters.join("%2B") }}">this link</a>.</p>
 	</div>
 	</div>
 </div>
 </div>
 
 

+ 34 - 23
templates/utils.html

@@ -94,27 +94,36 @@
 	</h2>
 	</h2>
 	<!-- POST MEDIA/THUMBNAIL -->
 	<!-- POST MEDIA/THUMBNAIL -->
 	{% if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "image" %}
 	{% if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "image" %}
-	<a href="{{ post.media.url }}" class="post_media_image {% if post.media.height / post.media.width < 2 %}short{% endif %}" >
-		<svg
-			width="{{ post.media.width }}px" 
-			height="{{ post.media.height }}px" 
-			xmlns="http://www.w3.org/2000/svg">
-				<image width="100%" height="100%" href="{{ post.media.url }}"/>
-				<desc>
-					<img loading="lazy" alt="Post image" src="{{ post.media.url }}"/>
-				</desc>
-		</svg>
-	</a>
+	<div class="post_media_content">
+		<a href="{{ post.media.url }}" class="post_media_image {% if post.media.height / post.media.width < 2 %}short{% endif %}" >
+			<svg
+				{%if post.flags.nsfw && prefs.blur_nsfw=="on" %}class="post_nsfw_blur"{% endif %}
+				width="{{ post.media.width }}px"
+				height="{{ post.media.height }}px"
+				xmlns="http://www.w3.org/2000/svg">
+					<image width="100%" height="100%" href="{{ post.media.url }}"/>
+					<desc>
+						<img loading="lazy" alt="Post image" src="{{ post.media.url }}"/>
+					</desc>
+			</svg>
+		</a>
+	</div>
 	{% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "gif" %}
 	{% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "gif" %}
-	<video class="post_media_video short" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls loop {% if prefs.autoplay_videos == "on" %}autoplay{% endif %}><a href={{ post.media.url }}>Video</a></video>
+	<div class="post_media_content">
+		<video class="post_media_video short {%if post.flags.nsfw && prefs.blur_nsfw=="on" %}post_nsfw_blur{% endif %}" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls loop {% if prefs.autoplay_videos == "on" %}autoplay{% endif %}><a href={{ post.media.url }}>Video</a></video>
+	</div>
 	{% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "video" %}
 	{% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "video" %}
 	{% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %}
 	{% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %}
-	<video class="post_media_video short {% if prefs.autoplay_videos == "on" %}hls_autoplay{% endif %}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" controls preload="none">
-		<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
-		<source src="{{ post.media.url }}" type="video/mp4" />
-	</video>
+	<div class="post_media_content">
+		<video class="post_media_video short {%if post.flags.nsfw && prefs.blur_nsfw=="on" %}post_nsfw_blur{% endif %} {% if prefs.autoplay_videos == "on" %}hls_autoplay{% endif %}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" controls preload="none">
+			<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
+			<source src="{{ post.media.url }}" type="video/mp4" />
+		</video>
+	</div>
 	{% else %}
 	{% else %}
-	<video class="post_media_video short" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls {% if prefs.autoplay_videos == "on" %}autoplay{% endif %}><a href={{ post.media.url }}>Video</a></video>
+	<div class="post_media_content">
+		<video class="post_media_video short {%if post.flags.nsfw && prefs.blur_nsfw=="on" %}post_nsfw_blur{% endif %}" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls {% if prefs.autoplay_videos == "on" %}autoplay{% endif %}><a href={{ post.media.url }}>Video</a></video>
+	</div>
 	{% call render_hls_notification(format!("{}%23{}", &self.url[1..].replace("&", "%26").replace("+", "%2B"), post.id)) %}
 	{% call render_hls_notification(format!("{}%23{}", &self.url[1..].replace("&", "%26").replace("+", "%2B"), post.id)) %}
 	{% endif %}
 	{% endif %}
 	{% else if post.post_type != "self" %}
 	{% else if post.post_type != "self" %}
@@ -125,12 +134,14 @@
 			<path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/>
 			<path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/>
 		</svg>
 		</svg>
 		{% else %}
 		{% else %}
-		<svg width="{{ post.thumbnail.width }}px" height="{{ post.thumbnail.height }}px" xmlns="http://www.w3.org/2000/svg">
-			<image width="100%" height="100%" href="{{ post.thumbnail.url }}"/>
-			<desc>
-				<img loading="lazy" alt="Thumbnail" src="{{ post.thumbnail.url }}"/>
-			</desc>
-		</svg>
+		<div style="max-width:{{ post.thumbnail.width }}px;max-height:{{ post.thumbnail.height }}px;">
+			<svg {% if post.flags.nsfw && prefs.blur_nsfw=="on" %} class="thumb_nsfw_blur" {% endif %} width="{{ post.thumbnail.width }}px" height="{{ post.thumbnail.height }}px" xmlns="http://www.w3.org/2000/svg">
+				<image width="100%" height="100%" href="{{ post.thumbnail.url }}"/>
+				<desc>
+					<img loading="lazy" alt="Thumbnail" src="{{ post.thumbnail.url }}"/>
+				</desc>
+			</svg>
+		</div>
 		{% endif %}
 		{% endif %}
 		<span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span>
 		<span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span>
 	</a>
 	</a>