diff --git a/Cargo.toml b/Cargo.toml index bb5660e..08dba9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/main.rs b/src/main.rs index f539e5b..9d6acc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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 diff --git a/src/post.rs b/src/post.rs index a4c33d5..1244ed0 100644 --- a/src/post.rs +++ b/src/post.rs @@ -14,12 +14,18 @@ struct PostTemplate { comments: Vec, 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 diff --git a/src/settings.rs b/src/settings.rs index d9c55c7..cfc663f 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -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, + comment_sort: Option, } // 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) -> HttpResponse { +pub async fn set(req: HttpRequest, form: Form) -> HttpResponse { let mut response = HttpResponse::Found(); match &form.layout { @@ -40,6 +46,17 @@ pub async fn set(req: HttpRequest, form: Form) -> 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") diff --git a/src/subreddit.rs b/src/subreddit.rs index 9009ba6..03da40c 100644 --- a/src/subreddit.rs +++ b/src/subreddit.rs @@ -20,26 +20,25 @@ 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() }; match fetch_posts(&path, String::new()).await { - Ok((posts,after)) => { + 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(); diff --git a/src/utils.rs b/src/utils.rs index d183562..36b45f8 100644 --- a/src/utils.rs +++ b/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 { 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 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) } diff --git a/static/style.css b/static/style.css index c69f9a0..8acb1bf 100644 --- a/static/style.css +++ b/static/style.css @@ -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; } diff --git a/templates/base.html b/templates/base.html index 4462e19..5a1a493 100644 --- a/templates/base.html +++ b/templates/base.html @@ -11,7 +11,7 @@ {% endblock %} - +