diff --git a/src/duplicates.rs b/src/duplicates.rs index d747d46..b099acf 100644 --- a/src/duplicates.rs +++ b/src/duplicates.rs @@ -3,7 +3,7 @@ use crate::client::json; use crate::server::RequestExt; use crate::subreddit::{can_access_quarantine, quarantine}; -use crate::utils::{error, filter_posts, get_filters, nsfw_landing, parse_post, setting, template, Post, Preferences}; +use crate::utils::{error, filter_posts, get_filters, nsfw_landing, parse_post, template, Post, Preferences}; use askama::Template; use hyper::{Body, Request, Response}; @@ -67,11 +67,12 @@ pub async fn item(req: Request) -> Result, String> { Ok(response) => { let post = parse_post(&response[0]["data"]["children"][0]).await; + let req_url = req.uri().to_string(); // Return landing page if this post if this Reddit deems this post // NSFW, but we have also disabled the display of NSFW content - // or if the instance is SFW-only. - if post.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) { - return Ok(nsfw_landing(req).await.unwrap_or_default()); + // or if the instance is SFW-only + if post.nsfw && crate::utils::should_be_nsfw_gated(&req, &req_url) { + return Ok(nsfw_landing(req, req_url).await.unwrap_or_default()); } let filters = get_filters(&req); @@ -195,14 +196,13 @@ pub async fn item(req: Request) -> Result, String> { after = response[1]["data"]["after"].as_str().unwrap_or_default().to_string(); } } - let url = req.uri().to_string(); template(DuplicatesTemplate { params: DuplicatesParams { before, after, sort }, post, duplicates, prefs: Preferences::new(&req), - url, + url: req_url, num_posts_filtered, all_posts_filtered, }) diff --git a/src/post.rs b/src/post.rs index 91af91e..aa06b09 100644 --- a/src/post.rs +++ b/src/post.rs @@ -63,11 +63,12 @@ pub async fn item(req: Request) -> Result, String> { // Parse the JSON into Post and Comment structs let post = parse_post(&response[0]["data"]["children"][0]).await; + let req_url = req.uri().to_string(); // Return landing page if this post if this Reddit deems this post // NSFW, but we have also disabled the display of NSFW content // or if the instance is SFW-only. - if post.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) { - return Ok(nsfw_landing(req).await.unwrap_or_default()); + if post.nsfw && crate::utils::should_be_nsfw_gated(&req, &req_url) { + return Ok(nsfw_landing(req, req_url).await.unwrap_or_default()); } let query = match COMMENT_SEARCH_CAPTURE.captures(&url) { @@ -88,7 +89,7 @@ pub async fn item(req: Request) -> Result, String> { sort, prefs: Preferences::new(&req), single_thread, - url, + url: req_url, comment_query: query, }) } diff --git a/src/subreddit.rs b/src/subreddit.rs index e253885..ee57ea5 100644 --- a/src/subreddit.rs +++ b/src/subreddit.rs @@ -97,10 +97,11 @@ pub async fn community(req: Request) -> Result, String> { } }; + let req_url = req.uri().to_string(); // Return landing page if this post if this is NSFW community but the user // has disabled the display of NSFW content or if the instance is SFW-only. - if sub.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) { - return Ok(nsfw_landing(req).await.unwrap_or_default()); + if sub.nsfw && crate::utils::should_be_nsfw_gated(&req, &req_url) { + return Ok(nsfw_landing(req, req_url).await.unwrap_or_default()); } let path = format!("/r/{}/{}.json?{}&raw_json=1", sub_name.clone(), sort, req.uri().query().unwrap_or_default()); diff --git a/src/user.rs b/src/user.rs index 53f4090..efa70a9 100644 --- a/src/user.rs +++ b/src/user.rs @@ -50,11 +50,12 @@ pub async fn profile(req: Request) -> Result, String> { // Retrieve info from user about page. let user = user(&username).await.unwrap_or_default(); + let req_url = req.uri().to_string(); // Return landing page if this post if this Reddit deems this user NSFW, // but we have also disabled the display of NSFW content or if the instance // is SFW-only. - if user.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) { - return Ok(nsfw_landing(req).await.unwrap_or_default()); + if user.nsfw && crate::utils::should_be_nsfw_gated(&req, &req_url) { + return Ok(nsfw_landing(req, req_url).await.unwrap_or_default()); } let filters = get_filters(&req); diff --git a/src/utils.rs b/src/utils.rs index e6cb2f7..172bf4d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -893,11 +893,21 @@ pub fn sfw_only() -> bool { } } +// Determines if a request shoud redirect to a nsfw landing gate. +pub fn should_be_nsfw_gated(req: &Request, req_url: &String) -> bool { + let sfw_instance = sfw_only(); + let gate_nsfw = (setting(&req, "show_nsfw") != "on") || sfw_instance; + + // Nsfw landing gate should not be bypassed on a sfw only instance, + let bypass_gate = !sfw_instance && req_url.contains("&bypass_nsfw_landing"); + + gate_nsfw && !bypass_gate +} + /// Renders the landing page for NSFW content when the user has not enabled /// "show NSFW posts" in settings. -pub async fn nsfw_landing(req: Request) -> Result, String> { +pub async fn nsfw_landing(req: Request, req_url: String) -> Result, String> { let res_type: ResourceType; - let url = req.uri().to_string(); // Determine from the request URL if the resource is a subreddit, a user // page, or a post. @@ -916,7 +926,7 @@ pub async fn nsfw_landing(req: Request) -> Result, String> res, res_type, prefs: Preferences::new(&req), - url, + url: req_url, } .render() .unwrap_or_default(); diff --git a/templates/nsfwlanding.html b/templates/nsfwlanding.html index f6287a3..4dc8c86 100644 --- a/templates/nsfwlanding.html +++ b/templates/nsfwlanding.html @@ -19,10 +19,12 @@ {% if crate::utils::sfw_only() %} This instance of Libreddit is SFW-only.

{% else %} - Enable "Show NSFW posts" in settings to view this {% if res_type == crate::utils::ResourceType::Subreddit %}subreddit{% else if res_type == crate::utils::ResourceType::User %}user's posts or comments{% else if res_type == crate::utils::ResourceType::Post %}post{% endif %}. + Enable "Show NSFW posts" in settings to view this {% if res_type == crate::utils::ResourceType::Subreddit %}subreddit{% else if res_type == crate::utils::ResourceType::User %}user's posts or comments{% else if res_type == crate::utils::ResourceType::Post %}post{% endif %}.
+ {% if res_type == crate::utils::ResourceType::Post %} You can also temporarily bypass this gate and view the post by clicking on this link.{% endif %} {% endif %}

{% endblock %} {% block footer %} {% endblock %} +