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"] }
|
||||
reqwest = { version = "0.10", default_features = false, features = ["rustls-tls"] }
|
||||
askama = "0.10.5"
|
||||
serde = "1.0.118"
|
||||
serde = { version = "1.0.118", default_features = false, features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
async-recursion = "0.3.1"
|
||||
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))
|
||||
})
|
||||
.bind(&address)
|
||||
.map(|x| {
|
||||
x
|
||||
})
|
||||
.unwrap_or_else(|_| panic!("Cannot bind to the address: {}", address))
|
||||
.run()
|
||||
.await
|
||||
|
19
src/post.rs
19
src/post.rs
@ -14,12 +14,18 @@ struct PostTemplate {
|
||||
comments: Vec<Comment>,
|
||||
post: Post,
|
||||
sort: String,
|
||||
layout: String,
|
||||
}
|
||||
|
||||
pub async fn item(req: HttpRequest) -> HttpResponse {
|
||||
// Build Reddit API path
|
||||
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
|
||||
#[cfg(debug_assertions)]
|
||||
@ -34,14 +40,7 @@ pub async fn item(req: HttpRequest) -> HttpResponse {
|
||||
let comments = parse_comments(&res[1]).await;
|
||||
|
||||
// Use the Post and Comment structs to generate a website to show users
|
||||
let s = PostTemplate {
|
||||
comments,
|
||||
post,
|
||||
sort,
|
||||
layout: cookie(req, "layout"),
|
||||
}
|
||||
.render()
|
||||
.unwrap();
|
||||
let s = PostTemplate { comments, post, sort }.render().unwrap();
|
||||
HttpResponse::Ok().content_type("text/html").body(s)
|
||||
}
|
||||
// If the Reddit API returns an error, exit and send error page to user
|
||||
|
@ -6,27 +6,33 @@ use time::{Duration, OffsetDateTime};
|
||||
|
||||
// STRUCTS
|
||||
#[derive(Template)]
|
||||
#[template(path = "settings.html", escape = "none")]
|
||||
#[template(path = "settings.html")]
|
||||
struct SettingsTemplate {
|
||||
layout: String,
|
||||
comment_sort: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct Preferences {
|
||||
pub struct SettingsForm {
|
||||
layout: Option<String>,
|
||||
comment_sort: Option<String>,
|
||||
}
|
||||
|
||||
// FUNCTIONS
|
||||
|
||||
// Retrieve cookies from request "Cookie" header
|
||||
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)
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
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()),
|
||||
};
|
||||
|
||||
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
|
||||
.content_type("text/html")
|
||||
.set_header("Location", "/settings")
|
||||
|
@ -20,17 +20,16 @@ struct WikiTemplate {
|
||||
sub: String,
|
||||
wiki: String,
|
||||
page: String,
|
||||
layout: String,
|
||||
}
|
||||
|
||||
// SERVICES
|
||||
pub async fn page(req: HttpRequest) -> HttpResponse {
|
||||
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 sub_result = if !&sub.contains('+') && sub != "popular" {
|
||||
subreddit(&sub).await.unwrap_or_default()
|
||||
let sub = if !&sub_name.contains('+') && sub_name != "popular" {
|
||||
subreddit(&sub_name).await.unwrap_or_default()
|
||||
} else {
|
||||
Subreddit::default()
|
||||
};
|
||||
@ -38,8 +37,8 @@ pub async fn page(req: HttpRequest) -> HttpResponse {
|
||||
match fetch_posts(&path, String::new()).await {
|
||||
Ok((posts, after)) => {
|
||||
let s = SubredditTemplate {
|
||||
sub: sub_result,
|
||||
posts: posts,
|
||||
sub,
|
||||
posts,
|
||||
sort: (sort, param(&path, "t")),
|
||||
ends: (param(&path, "after"), after),
|
||||
layout: cookie(req, "layout"),
|
||||
@ -63,7 +62,6 @@ pub async fn wiki(req: HttpRequest) -> HttpResponse {
|
||||
sub: sub.to_string(),
|
||||
wiki: rewrite_url(res["data"]["content_html"].as_str().unwrap_or_default()),
|
||||
page: page.to_string(),
|
||||
layout: String::new(),
|
||||
}
|
||||
.render()
|
||||
.unwrap();
|
||||
|
12
src/utils.rs
12
src/utils.rs
@ -94,7 +94,6 @@ pub struct Params {
|
||||
#[template(path = "error.html", escape = "none")]
|
||||
pub struct ErrorTemplate {
|
||||
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
|
||||
match request(&path).await {
|
||||
// If success, receive JSON in response
|
||||
Ok(response) => { res = response; }
|
||||
Ok(response) => {
|
||||
res = response;
|
||||
}
|
||||
// If the Reddit API returns an error, exit this function
|
||||
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 {
|
||||
let body = ErrorTemplate {
|
||||
message: msg,
|
||||
layout: String::new(),
|
||||
}
|
||||
.render()
|
||||
.unwrap_or_default();
|
||||
let body = ErrorTemplate { message: msg }.render().unwrap_or_default();
|
||||
HttpResponse::NotFound().content_type("text/html").body(body)
|
||||
}
|
||||
|
||||
|
@ -622,6 +622,7 @@ input[type="submit"]:hover { color: var(--accent); }
|
||||
|
||||
#prefs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
@ -629,8 +630,20 @@ input[type="submit"]:hover { color: var(--accent); }
|
||||
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;
|
||||
box-shadow: var(--shadow);
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body {% if layout != "" %}id="{{ layout }}"{% endif %}>
|
||||
<body id="{% block layout %}{% endblock %}">
|
||||
<!-- NAVIGATION BAR -->
|
||||
<nav>
|
||||
<p id="logo">
|
||||
|
@ -88,7 +88,7 @@
|
||||
<!-- SORT FORM -->
|
||||
<form id="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="→">
|
||||
</form>
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
{% block title %}Libreddit: search results - {{ params.q }}{% endblock %}
|
||||
|
||||
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="column_one">
|
||||
<form id="search_sort">
|
||||
|
@ -11,11 +11,19 @@
|
||||
<main>
|
||||
<form id="settings" action="/settings" method="POST">
|
||||
<div id="prefs">
|
||||
<div id="layout">
|
||||
<label for="layout">Layout:</label>
|
||||
<select name="layout">
|
||||
{% call utils::options(layout, ["card", "clean", "compact"], "clean") %}
|
||||
</select>
|
||||
</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">
|
||||
</form>
|
||||
</main>
|
||||
|
@ -11,6 +11,8 @@
|
||||
{% call utils::search(["/r/", sub.name.as_str()].concat(), "") %}
|
||||
{% endblock %}
|
||||
|
||||
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<main>
|
||||
<div id="column_one">
|
||||
|
@ -6,6 +6,9 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{{ user.name.replace("u/", "") }} (u/{{ user.name }}) - Libreddit{% endblock %}
|
||||
|
||||
{% block layout %}{% if layout != "" %}{{ layout }}{% endif %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<main style="max-width: 1000px;">
|
||||
<div id="column_one">
|
||||
|
Loading…
Reference in New Issue
Block a user