Default Comment Sort Setting
This commit is contained in:
parent
7e96bb3d80
commit
3444989f9a
@ -12,7 +12,7 @@ base64 = "0.13.0"
|
|||||||
actix-web = { version = "3.3.2", features = ["rustls"] }
|
actix-web = { version = "3.3.2", features = ["rustls"] }
|
||||||
reqwest = { version = "0.10", default_features = false, features = ["rustls-tls"] }
|
reqwest = { version = "0.10", default_features = false, features = ["rustls-tls"] }
|
||||||
askama = "0.10.5"
|
askama = "0.10.5"
|
||||||
serde = "1.0.118"
|
serde = { version = "1.0.118", default_features = false, features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
async-recursion = "0.3.1"
|
async-recursion = "0.3.1"
|
||||||
url = "2.2.0"
|
url = "2.2.0"
|
||||||
|
@ -80,9 +80,6 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.route("/r/{sub}/comments/{id}/{title}/{comment_id}/", web::get().to(post::item))
|
.route("/r/{sub}/comments/{id}/{title}/{comment_id}/", web::get().to(post::item))
|
||||||
})
|
})
|
||||||
.bind(&address)
|
.bind(&address)
|
||||||
.map(|x| {
|
|
||||||
x
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|_| panic!("Cannot bind to the address: {}", address))
|
.unwrap_or_else(|_| panic!("Cannot bind to the address: {}", address))
|
||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
|
19
src/post.rs
19
src/post.rs
@ -14,12 +14,18 @@ struct PostTemplate {
|
|||||||
comments: Vec<Comment>,
|
comments: Vec<Comment>,
|
||||||
post: Post,
|
post: Post,
|
||||||
sort: String,
|
sort: String,
|
||||||
layout: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn item(req: HttpRequest) -> HttpResponse {
|
pub async fn item(req: HttpRequest) -> HttpResponse {
|
||||||
|
// Build Reddit API path
|
||||||
let path = format!("{}.json?{}&raw_json=1", req.path(), req.query_string());
|
let path = format!("{}.json?{}&raw_json=1", req.path(), req.query_string());
|
||||||
let sort = param(&path, "sort");
|
|
||||||
|
// Set sort to sort query parameter or otherwise default sort
|
||||||
|
let sort = if param(&path, "sort").is_empty() {
|
||||||
|
cookie(req.to_owned(), "comment_sort")
|
||||||
|
} else {
|
||||||
|
param(&path, "sort")
|
||||||
|
};
|
||||||
|
|
||||||
// Log the post ID being fetched in debug mode
|
// Log the post ID being fetched in debug mode
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@ -34,14 +40,7 @@ pub async fn item(req: HttpRequest) -> HttpResponse {
|
|||||||
let comments = parse_comments(&res[1]).await;
|
let comments = parse_comments(&res[1]).await;
|
||||||
|
|
||||||
// Use the Post and Comment structs to generate a website to show users
|
// Use the Post and Comment structs to generate a website to show users
|
||||||
let s = PostTemplate {
|
let s = PostTemplate { comments, post, sort }.render().unwrap();
|
||||||
comments,
|
|
||||||
post,
|
|
||||||
sort,
|
|
||||||
layout: cookie(req, "layout"),
|
|
||||||
}
|
|
||||||
.render()
|
|
||||||
.unwrap();
|
|
||||||
HttpResponse::Ok().content_type("text/html").body(s)
|
HttpResponse::Ok().content_type("text/html").body(s)
|
||||||
}
|
}
|
||||||
// If the Reddit API returns an error, exit and send error page to user
|
// If the Reddit API returns an error, exit and send error page to user
|
||||||
|
@ -6,27 +6,33 @@ use time::{Duration, OffsetDateTime};
|
|||||||
|
|
||||||
// STRUCTS
|
// STRUCTS
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "settings.html", escape = "none")]
|
#[template(path = "settings.html")]
|
||||||
struct SettingsTemplate {
|
struct SettingsTemplate {
|
||||||
layout: String,
|
layout: String,
|
||||||
|
comment_sort: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct Preferences {
|
pub struct SettingsForm {
|
||||||
layout: Option<String>,
|
layout: Option<String>,
|
||||||
|
comment_sort: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTIONS
|
// FUNCTIONS
|
||||||
|
|
||||||
// Retrieve cookies from request "Cookie" header
|
// Retrieve cookies from request "Cookie" header
|
||||||
pub async fn get(req: HttpRequest) -> HttpResponse {
|
pub async fn get(req: HttpRequest) -> HttpResponse {
|
||||||
let s = SettingsTemplate { layout: cookie(req, "layout") }.render().unwrap();
|
let s = SettingsTemplate {
|
||||||
|
layout: cookie(req.to_owned(), "layout"),
|
||||||
|
comment_sort: cookie(req, "comment_sort"),
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
.unwrap();
|
||||||
HttpResponse::Ok().content_type("text/html").body(s)
|
HttpResponse::Ok().content_type("text/html").body(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set cookies using response "Set-Cookie" header
|
// Set cookies using response "Set-Cookie" header
|
||||||
pub async fn set(req: HttpRequest, form: Form<Preferences>) -> HttpResponse {
|
pub async fn set(req: HttpRequest, form: Form<SettingsForm>) -> HttpResponse {
|
||||||
let mut response = HttpResponse::Found();
|
let mut response = HttpResponse::Found();
|
||||||
|
|
||||||
match &form.layout {
|
match &form.layout {
|
||||||
@ -40,6 +46,17 @@ pub async fn set(req: HttpRequest, form: Form<Preferences>) -> HttpResponse {
|
|||||||
None => response.del_cookie(&actix_web::HttpMessage::cookie(&req, "layout").unwrap()),
|
None => response.del_cookie(&actix_web::HttpMessage::cookie(&req, "layout").unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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()),
|
||||||
|
};
|
||||||
|
|
||||||
response
|
response
|
||||||
.content_type("text/html")
|
.content_type("text/html")
|
||||||
.set_header("Location", "/settings")
|
.set_header("Location", "/settings")
|
||||||
|
@ -20,17 +20,16 @@ struct WikiTemplate {
|
|||||||
sub: String,
|
sub: String,
|
||||||
wiki: String,
|
wiki: String,
|
||||||
page: String,
|
page: String,
|
||||||
layout: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SERVICES
|
// SERVICES
|
||||||
pub async fn page(req: HttpRequest) -> HttpResponse {
|
pub async fn page(req: HttpRequest) -> HttpResponse {
|
||||||
let path = format!("{}.json?{}", req.path(), req.query_string());
|
let path = format!("{}.json?{}", req.path(), req.query_string());
|
||||||
let sub = req.match_info().get("sub").unwrap_or("popular").to_string();
|
let sub_name = req.match_info().get("sub").unwrap_or("popular").to_string();
|
||||||
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
|
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
|
||||||
|
|
||||||
let sub_result = if !&sub.contains('+') && sub != "popular" {
|
let sub = if !&sub_name.contains('+') && sub_name != "popular" {
|
||||||
subreddit(&sub).await.unwrap_or_default()
|
subreddit(&sub_name).await.unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
Subreddit::default()
|
Subreddit::default()
|
||||||
};
|
};
|
||||||
@ -38,8 +37,8 @@ pub async fn page(req: HttpRequest) -> HttpResponse {
|
|||||||
match fetch_posts(&path, String::new()).await {
|
match fetch_posts(&path, String::new()).await {
|
||||||
Ok((posts, after)) => {
|
Ok((posts, after)) => {
|
||||||
let s = SubredditTemplate {
|
let s = SubredditTemplate {
|
||||||
sub: sub_result,
|
sub,
|
||||||
posts: posts,
|
posts,
|
||||||
sort: (sort, param(&path, "t")),
|
sort: (sort, param(&path, "t")),
|
||||||
ends: (param(&path, "after"), after),
|
ends: (param(&path, "after"), after),
|
||||||
layout: cookie(req, "layout"),
|
layout: cookie(req, "layout"),
|
||||||
@ -63,7 +62,6 @@ pub async fn wiki(req: HttpRequest) -> HttpResponse {
|
|||||||
sub: sub.to_string(),
|
sub: sub.to_string(),
|
||||||
wiki: rewrite_url(res["data"]["content_html"].as_str().unwrap_or_default()),
|
wiki: rewrite_url(res["data"]["content_html"].as_str().unwrap_or_default()),
|
||||||
page: page.to_string(),
|
page: page.to_string(),
|
||||||
layout: String::new(),
|
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
12
src/utils.rs
12
src/utils.rs
@ -94,7 +94,6 @@ pub struct Params {
|
|||||||
#[template(path = "error.html", escape = "none")]
|
#[template(path = "error.html", escape = "none")]
|
||||||
pub struct ErrorTemplate {
|
pub struct ErrorTemplate {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
pub layout: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -180,7 +179,9 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec<Post
|
|||||||
// Send a request to the url
|
// Send a request to the url
|
||||||
match request(&path).await {
|
match request(&path).await {
|
||||||
// If success, receive JSON in response
|
// If success, receive JSON in response
|
||||||
Ok(response) => { res = response; }
|
Ok(response) => {
|
||||||
|
res = response;
|
||||||
|
}
|
||||||
// If the Reddit API returns an error, exit this function
|
// If the Reddit API returns an error, exit this function
|
||||||
Err(msg) => return Err(msg),
|
Err(msg) => return Err(msg),
|
||||||
}
|
}
|
||||||
@ -245,12 +246,7 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec<Post
|
|||||||
//
|
//
|
||||||
|
|
||||||
pub async fn error(msg: String) -> HttpResponse {
|
pub async fn error(msg: String) -> HttpResponse {
|
||||||
let body = ErrorTemplate {
|
let body = ErrorTemplate { message: msg }.render().unwrap_or_default();
|
||||||
message: msg,
|
|
||||||
layout: String::new(),
|
|
||||||
}
|
|
||||||
.render()
|
|
||||||
.unwrap_or_default();
|
|
||||||
HttpResponse::NotFound().content_type("text/html").body(body)
|
HttpResponse::NotFound().content_type("text/html").body(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,6 +622,7 @@ input[type="submit"]:hover { color: var(--accent); }
|
|||||||
|
|
||||||
#prefs {
|
#prefs {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@ -629,8 +630,20 @@ input[type="submit"]:hover { color: var(--accent); }
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#prefs > select {
|
#prefs > div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#prefs > div:not(:last-of-type) {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#prefs select {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<link rel="stylesheet" href="/style.css">
|
<link rel="stylesheet" href="/style.css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body {% if layout != "" %}id="{{ layout }}"{% endif %}>
|
<body id="{% block layout %}{% endblock %}">
|
||||||
<!-- NAVIGATION BAR -->
|
<!-- NAVIGATION BAR -->
|
||||||
<nav>
|
<nav>
|
||||||
<p id="logo">
|
<p id="logo">
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
<!-- SORT FORM -->
|
<!-- SORT FORM -->
|
||||||
<form id="sort">
|
<form id="sort">
|
||||||
<select name="sort">
|
<select name="sort">
|
||||||
{% call utils::options(sort, ["confidence", "top", "new", "controversial", "old"], "") %}
|
{% call utils::options(sort, ["confidence", "top", "new", "controversial", "old"], "confidence") %}
|
||||||
</select><input id="sort_submit" type="submit" value="→">
|
</select><input id="sort_submit" type="submit" value="→">
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
{% block title %}Libreddit: search results - {{ params.q }}{% endblock %}
|
{% block title %}Libreddit: search results - {{ params.q }}{% endblock %}
|
||||||
|
|
||||||
|
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="column_one">
|
<div id="column_one">
|
||||||
<form id="search_sort">
|
<form id="search_sort">
|
||||||
|
@ -11,11 +11,19 @@
|
|||||||
<main>
|
<main>
|
||||||
<form id="settings" action="/settings" method="POST">
|
<form id="settings" action="/settings" method="POST">
|
||||||
<div id="prefs">
|
<div id="prefs">
|
||||||
|
<div id="layout">
|
||||||
<label for="layout">Layout:</label>
|
<label for="layout">Layout:</label>
|
||||||
<select name="layout">
|
<select name="layout">
|
||||||
{% call utils::options(layout, ["card", "clean", "compact"], "clean") %}
|
{% call utils::options(layout, ["card", "clean", "compact"], "clean") %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="comment_sort">
|
||||||
|
<label for="comment_sort">Default comment sort:</label>
|
||||||
|
<select name="comment_sort">
|
||||||
|
{% call utils::options(comment_sort, ["confidence", "top", "new", "controversial", "old"], "confidence") %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<input id="save" type="submit" value="Save">
|
<input id="save" type="submit" value="Save">
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
{% call utils::search(["/r/", sub.name.as_str()].concat(), "") %}
|
{% call utils::search(["/r/", sub.name.as_str()].concat(), "") %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<main>
|
<main>
|
||||||
<div id="column_one">
|
<div id="column_one">
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block title %}{{ user.name.replace("u/", "") }} (u/{{ user.name }}) - Libreddit{% endblock %}
|
{% block title %}{{ user.name.replace("u/", "") }} (u/{{ user.name }}) - Libreddit{% endblock %}
|
||||||
|
|
||||||
|
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<main style="max-width: 1000px;">
|
<main style="max-width: 1000px;">
|
||||||
<div id="column_one">
|
<div id="column_one">
|
||||||
|
Loading…
Reference in New Issue
Block a user