Add "hide nsfw" option
This commit is contained in:
parent
3d142afd03
commit
b13874d0db
10 changed files with 98 additions and 75 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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>..."#)
|
||||
|
|
|
@ -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();
|
||||
|
|
38
src/user.rs
38
src/user.rs
|
@ -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"),
|
||||
})
|
||||
}
|
||||
|
|
31
src/utils.rs
31
src/utils.rs
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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="→">
|
||||
</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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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="→">
|
||||
</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 != "" %}
|
||||
|
|
|
@ -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="→">
|
||||
</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>
|
||||
|
|
Loading…
Reference in a new issue