Add "hide nsfw" option

This commit is contained in:
spikecodes 2021-01-08 17:35:04 -08:00
parent 3d142afd03
commit b13874d0db
10 changed files with 98 additions and 75 deletions

8
Cargo.lock generated
View file

@ -1026,9 +1026,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.81"
version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
[[package]]
name = "libreddit"
@ -1756,9 +1756,9 @@ dependencies = [
[[package]]
name = "thread_local"
version = "1.0.1"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
dependencies = [
"lazy_static",
]

View file

@ -1,5 +1,5 @@
// CRATES
use crate::utils::{cookie, error, fetch_posts, param, Post};
use crate::utils::{error, fetch_posts, param, prefs, Post, Preferences};
use actix_web::{HttpRequest, HttpResponse};
use askama::Template;
@ -19,7 +19,7 @@ struct SearchTemplate {
posts: Vec<Post>,
sub: String,
params: SearchParams,
layout: String,
prefs: Preferences,
}
// SERVICES
@ -45,7 +45,7 @@ pub async fn find(req: HttpRequest) -> HttpResponse {
after,
restrict_sr: param(&path, "restrict_sr"),
},
layout: cookie(req, "layout"),
prefs: prefs(req),
}
.render()
.unwrap(),

View file

@ -1,6 +1,6 @@
// CRATES
use crate::utils::cookie;
use actix_web::{cookie::Cookie, web::Form, HttpRequest, HttpResponse}; // http::Method,
use actix_web::{cookie::Cookie, web::Form, HttpMessage, HttpRequest, HttpResponse};
use askama::Template;
use time::{Duration, OffsetDateTime};
@ -10,12 +10,14 @@ use time::{Duration, OffsetDateTime};
struct SettingsTemplate {
layout: String,
comment_sort: String,
hide_nsfw: String,
}
#[derive(serde::Deserialize)]
pub struct SettingsForm {
layout: Option<String>,
comment_sort: Option<String>,
hide_nsfw: Option<String>,
}
// FUNCTIONS
@ -24,7 +26,8 @@ pub struct SettingsForm {
pub async fn get(req: HttpRequest) -> HttpResponse {
let s = SettingsTemplate {
layout: cookie(req.to_owned(), "layout"),
comment_sort: cookie(req, "comment_sort"),
comment_sort: cookie(req.to_owned(), "comment_sort"),
hide_nsfw: cookie(req, "hide_nsfw"),
}
.render()
.unwrap();
@ -33,31 +36,28 @@ pub async fn get(req: HttpRequest) -> HttpResponse {
// Set cookies using response "Set-Cookie" header
pub async fn set(req: HttpRequest, form: Form<SettingsForm>) -> HttpResponse {
let mut response = HttpResponse::Found();
let mut res = HttpResponse::Found();
match &form.layout {
Some(value) => response.cookie(
Cookie::build("layout", value)
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),
),
None => response.del_cookie(&actix_web::HttpMessage::cookie(&req, "layout").unwrap()),
};
let names = vec!["layout", "comment_sort", "hide_nsfw"];
let values = vec![&form.layout, &form.comment_sort, &form.hide_nsfw];
match &form.comment_sort {
Some(value) => response.cookie(
Cookie::build("comment_sort", value)
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),
),
None => response.del_cookie(&actix_web::HttpMessage::cookie(&req, "comment_sort").unwrap()),
};
for (i, name) in names.iter().enumerate() {
match values[i] {
Some(value) => res.cookie(
Cookie::build(name.to_owned(), value)
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),
),
None => match HttpMessage::cookie(&req, name.to_owned()) {
Some(cookie) => res.del_cookie(&cookie),
None => &mut res,
},
};
}
response
res
.content_type("text/html")
.set_header("Location", "/settings")
.body(r#"Redirecting to <a href="/settings">settings</a>..."#)

View file

@ -1,5 +1,5 @@
// CRATES
use crate::utils::{cookie, error, fetch_posts, format_num, format_url, param, request, rewrite_url, val, Post, Subreddit};
use crate::utils::{error, fetch_posts, format_num, format_url, param, prefs, request, rewrite_url, val, Post, Preferences, Subreddit};
use actix_web::{HttpRequest, HttpResponse, Result};
use askama::Template;
@ -11,7 +11,7 @@ struct SubredditTemplate {
posts: Vec<Post>,
sort: (String, String),
ends: (String, String),
layout: String,
prefs: Preferences,
}
#[derive(Template)]
@ -41,7 +41,7 @@ pub async fn page(req: HttpRequest) -> HttpResponse {
posts,
sort: (sort, param(&path, "t")),
ends: (param(&path, "after"), after),
layout: cookie(req, "layout"),
prefs: prefs(req),
}
.render()
.unwrap();

View file

@ -1,5 +1,5 @@
// CRATES
use crate::utils::{cookie, error, fetch_posts, format_url, nested_val, param, request, Post, User};
use crate::utils::{error, fetch_posts, format_url, nested_val, param, prefs, request, Post, Preferences, User};
use actix_web::{HttpRequest, HttpResponse, Result};
use askama::Template;
use time::OffsetDateTime;
@ -12,7 +12,7 @@ struct UserTemplate {
posts: Vec<Post>,
sort: (String, String),
ends: (String, String),
layout: String,
prefs: Preferences,
}
// FUNCTIONS
@ -35,7 +35,7 @@ pub async fn profile(req: HttpRequest) -> HttpResponse {
posts,
sort: (sort, param(&path, "t")),
ends: (param(&path, "after"), after),
layout: cookie(req, "layout"),
prefs: prefs(req),
}
.render()
.unwrap();
@ -51,29 +51,25 @@ async fn user(name: &str) -> Result<User, &'static str> {
// Build the Reddit JSON API path
let path: String = format!("user/{}/about.json", name);
let res;
// Send a request to the url
match request(&path).await {
// If success, receive JSON in response
Ok(response) => {
res = response;
Ok(res) => {
// Grab creation date as unix timestamp
let created: i64 = res["data"]["created"].as_f64().unwrap_or(0.0).round() as i64;
// Parse the JSON output into a User struct
Ok(User {
name: name.to_string(),
title: nested_val(&res, "subreddit", "title"),
icon: format_url(nested_val(&res, "subreddit", "icon_img")),
karma: res["data"]["total_karma"].as_i64().unwrap_or(0),
created: OffsetDateTime::from_unix_timestamp(created).format("%b %d '%y"),
banner: nested_val(&res, "subreddit", "banner_img"),
description: nested_val(&res, "subreddit", "public_description"),
})
}
// If the Reddit API returns an error, exit this function
Err(msg) => return Err(msg),
}
// Grab creation date as unix timestamp
let created: i64 = res["data"]["created"].as_f64().unwrap_or(0.0).round() as i64;
// Parse the JSON output into a User struct
Ok(User {
name: name.to_string(),
title: nested_val(&res, "subreddit", "title"),
icon: format_url(nested_val(&res, "subreddit", "icon_img")),
karma: res["data"]["total_karma"].as_i64().unwrap_or(0),
created: OffsetDateTime::from_unix_timestamp(created).format("%b %d '%y"),
banner: nested_val(&res, "subreddit", "banner_img"),
description: nested_val(&res, "subreddit", "public_description"),
})
}

View file

@ -1,7 +1,3 @@
// use std::collections::HashMap;
use std::collections::HashMap;
//
// CRATES
//
@ -10,9 +6,9 @@ use askama::Template;
use base64::encode;
use regex::Regex;
use serde_json::from_str;
use std::collections::HashMap;
use time::OffsetDateTime;
use url::Url;
// use surf::{client, get, middleware::Redirect};
//
// STRUCTS
@ -96,10 +92,23 @@ pub struct ErrorTemplate {
pub message: String,
}
pub struct Preferences {
pub layout: String,
pub hide_nsfw: String,
}
//
// FORMATTING
//
// Build preferences from cookies
pub fn prefs(req: actix_web::HttpRequest) -> Preferences {
Preferences {
layout: cookie(req.to_owned(), "layout"),
hide_nsfw: cookie(req, "hide_nsfw"),
}
}
// Grab a query param from a url
pub fn param(path: &str, value: &str) -> String {
let url = Url::parse(format!("https://libredd.it/{}", path).as_str()).unwrap();
@ -114,7 +123,7 @@ pub fn cookie(req: actix_web::HttpRequest, name: &str) -> String {
// Direct urls to proxy if proxy is enabled
pub fn format_url(url: String) -> String {
if url.is_empty() || url == "self" || url == "default" || url == "nsfw" {
if url.is_empty() || url == "self" || url == "default" || url == "nsfw" || url == "spoiler" {
String::new()
} else {
format!("/proxy/{}", encode(url).as_str())
@ -129,10 +138,10 @@ pub fn rewrite_url(text: &str) -> String {
// Append `m` and `k` for millions and thousands respectively
pub fn format_num(num: i64) -> String {
if num > 1000000 {
format!("{}m", num / 1000000)
if num > 1_000_000 {
format!("{}m", num / 1_000_000)
} else if num > 1000 {
format!("{}k", num / 1000)
format!("{}k", num / 1_000)
} else {
num.to_string()
}
@ -279,9 +288,9 @@ pub async fn request(path: &str) -> Result<serde_json::Value, &'static str> {
}
}
// If can't send request to Reddit, return this to user
Err(e) => {
Err(_e) => {
#[cfg(debug_assertions)]
dbg!(format!("{} - {}", url, e));
dbg!(format!("{} - {}", url, _e));
Err("Couldn't send request to Reddit")
}
}

View file

@ -3,7 +3,7 @@
{% block title %}Libreddit: search results - {{ params.q }}{% endblock %}
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
{% block layout %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% endblock %}
{% block content %}
<div id="column_one">
@ -22,7 +22,9 @@
</select>{% endif %}<input id="sort_submit" type="submit" value="&rarr;">
</form>
{% for post in posts %}
{% if post.title != "Comment" %}
{% if post.flags.nsfw && prefs.hide_nsfw == "on" %}
{% else if post.title != "Comment" %}
<div class="post">
<div class="post_left">
<p class="post_score">{{ post.score }}</p>

View file

@ -23,6 +23,10 @@
{% call utils::options(comment_sort, ["confidence", "top", "new", "controversial", "old"], "confidence") %}
</select>
</div>
<div id="hide_nsfw">
<label for="hide_nsfw">Hide NSFW posts:</label>
<input type="checkbox" name="hide_nsfw" {% if hide_nsfw == "on" %}checked{% endif %}>
</div>
</div>
<input id="save" type="submit" value="Save">
</form>

View file

@ -11,7 +11,7 @@
{% call utils::search(["/r/", sub.name.as_str()].concat(), "") %}
{% endblock %}
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
{% block layout %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% endblock %}
{% block body %}
<main>
@ -29,7 +29,10 @@
<input id="sort_submit" type="submit" value="&rarr;">
</select>{% endif %}
</form>
<div id="posts">
{% for post in posts %}
{% if !(post.flags.nsfw && prefs.hide_nsfw == "on") %}
<div class="post {% if post.flags.stickied %}stickied{% endif %}">
<div class="post_left">
<p class="post_score">{{ post.score }}</p>
@ -53,14 +56,16 @@
</div>
<!-- POST MEDIA/THUMBNAIL -->
{% if layout == "card" && post.post_type == "image" %}
{% if prefs.layout == "card" && post.post_type == "image" %}
<img class="post_media" src="{{ post.media }}"/>
{% else if layout != "card" %}
{% else if prefs.layout != "card" %}
<img class="post_thumbnail" src="{{ post.thumbnail }}">
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</div>
<footer>
{% if ends.0 != "" %}

View file

@ -7,7 +7,7 @@
{% block title %}{{ user.name.replace("u/", "") }} (u/{{ user.name }}) - Libreddit{% endblock %}
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
{% block layout %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% endblock %}
{% block body %}
<main style="max-width: 1000px;">
@ -19,8 +19,12 @@
{% call utils::options(sort.1, ["hour", "day", "week", "month", "year", "all"], "all") %}
</select>{% endif %}<input id="sort_submit" type="submit" value="&rarr;">
</form>
<div id="posts">
{% for post in posts %}
{% if post.title != "Comment" %}
{% if post.flags.nsfw && prefs.hide_nsfw == "on" %}
{% else if post.title != "Comment" %}
<div class="post">
<div class="post_left">
<p class="post_score">{{ post.score }}</p>
@ -47,9 +51,9 @@
</div>
<!-- POST MEDIA/THUMBNAIL -->
{% if layout == "card" && post.post_type == "image" %}
{% if prefs.layout == "card" && post.post_type == "image" %}
<img class="post_media" src="{{ post.media }}"/>
{% else if layout != "card" %}
{% else if prefs.layout != "card" %}
<img class="post_thumbnail" src="{{ post.thumbnail }}">
{% endif %}
</div>
@ -69,7 +73,10 @@
</details>
</div>
{% endif %}
{% endfor %}
</div>
<footer>
{% if ends.0 != "" %}
<a href="?sort={{ sort.0 }}&before={{ ends.0 }}">PREV</a>