Blur NSFW posts.

Reimplementation of libreddit/libreddit#482.

Co-authored by: Daniel Valentine <Daniel-Valentine@users.noreply.github.com>
This commit is contained in:
NKIPSC 2022-11-09 08:49:39 -07:00 committed by Daniel Valentine
commit fade305f90
7 changed files with 106 additions and 49 deletions

View File

@ -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
}, },

View File

@ -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",

View File

@ -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"),

View File

@ -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 {
.post_media_video.short {
max-height: 512px;
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 {

View File

@ -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" > <div class="post_media_content">
<svg <a href="{{ post.media.url }}" class="post_media_image" >
width="{{ post.media.width }}px" <svg
height="{{ post.media.height }}px" width="{{ post.media.width }}px"
xmlns="http://www.w3.org/2000/svg"> height="{{ post.media.height }}px"
<image width="100%" height="100%" href="{{ post.media.url }}"/> xmlns="http://www.w3.org/2000/svg">
<desc> <image width="100%" height="100%" href="{{ post.media.url }}"/>
<img loading="lazy" alt="Post image" src="{{ post.media.url }}"/> <desc>
</desc> <img loading="lazy" alt="Post image" src="{{ post.media.url }}"/>
</svg> </desc>
</a> </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> <div class="post_media_content">
<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" /> <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.url }}" type="video/mp4" /> <source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
</video> <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" %}

View File

@ -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>

View File

@ -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 %}" > <div class="post_media_content">
<svg <a href="{{ post.media.url }}" class="post_media_image {% if post.media.height / post.media.width < 2 %}short{% endif %}" >
width="{{ post.media.width }}px" <svg
height="{{ post.media.height }}px" {%if post.flags.nsfw && prefs.blur_nsfw=="on" %}class="post_nsfw_blur"{% endif %}
xmlns="http://www.w3.org/2000/svg"> width="{{ post.media.width }}px"
<image width="100%" height="100%" href="{{ post.media.url }}"/> height="{{ post.media.height }}px"
<desc> xmlns="http://www.w3.org/2000/svg">
<img loading="lazy" alt="Post image" src="{{ post.media.url }}"/> <image width="100%" height="100%" href="{{ post.media.url }}"/>
</desc> <desc>
</svg> <img loading="lazy" alt="Post image" src="{{ post.media.url }}"/>
</a> </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"> <div class="post_media_content">
<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" /> <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.url }}" type="video/mp4" /> <source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
</video> <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"> <div style="max-width:{{ post.thumbnail.width }}px;max-height:{{ post.thumbnail.height }}px;">
<image width="100%" height="100%" href="{{ post.thumbnail.url }}"/> <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">
<desc> <image width="100%" height="100%" href="{{ post.thumbnail.url }}"/>
<img loading="lazy" alt="Thumbnail" src="{{ post.thumbnail.url }}"/> <desc>
</desc> <img loading="lazy" alt="Thumbnail" src="{{ post.thumbnail.url }}"/>
</svg> </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>