Wide UI Mode

This commit is contained in:
spikecodes 2021-01-10 13:08:36 -08:00
parent a0866b251e
commit f445c42f55
13 changed files with 102 additions and 64 deletions

View File

@ -1,5 +1,5 @@
// Import Crates // Import Crates
use actix_web::{get, middleware::NormalizePath, web, App, HttpResponse, HttpServer}; use actix_web::{App, HttpResponse, HttpServer, get, middleware, web}; // dev::Service
// Reference local files // Reference local files
mod post; mod post;
@ -28,14 +28,14 @@ async fn favicon() -> HttpResponse {
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
let args: Vec<String> = std::env::args().collect();
let mut address = "0.0.0.0:8080".to_string(); let mut address = "0.0.0.0:8080".to_string();
// let mut https = false;
if args.len() > 1 { for arg in std::env::args().collect::<Vec<String>>() {
for arg in args { match arg.split('=').collect::<Vec<&str>>()[0] {
if arg.starts_with("--address=") || arg.starts_with("-a=") { "--address" | "-a" => address = arg.split('=').collect::<Vec<&str>>()[1].to_string(),
address = arg.split('=').collect::<Vec<&str>>()[1].to_string(); // "--redirect-https" | "-r" => https = true,
} _ => {}
} }
} }
@ -44,8 +44,22 @@ async fn main() -> std::io::Result<()> {
HttpServer::new(|| { HttpServer::new(|| {
App::new() App::new()
// REDIRECT TO HTTPS
// .wrap(middleware::DefaultHeaders::new().header("Strict-Transport-Security", "max-age=31536000"))
// .wrap_fn(|req, srv| {
// let fut = srv.call(req);
// async {
// let mut res = fut.await?;
// if https {
// res.headers_mut().insert(
// actix_web::http::header::STRICT_TRANSPORT_SECURITY, actix_web::http::HeaderValue::from_static("max-age=31536000;"),
// );
// }
// Ok(res)
// }
// })
// TRAILING SLASH MIDDLEWARE // TRAILING SLASH MIDDLEWARE
.wrap(NormalizePath::default()) .wrap( middleware::NormalizePath::default())
// DEFAULT SERVICE // DEFAULT SERVICE
.default_service(web::get().to(|| utils::error("Nothing here".to_string()))) .default_service(web::get().to(|| utils::error("Nothing here".to_string())))
// GENERAL SERVICES // GENERAL SERVICES
@ -80,7 +94,7 @@ 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)
.unwrap_or_else(|_| panic!("Cannot bind to the address: {}", address)) .unwrap_or_else(|e| panic!("Cannot bind to the address {}: {}", address, e))
.run() .run()
.await .await
} }

View File

@ -1,5 +1,5 @@
// CRATES // CRATES
use crate::utils::{cookie, error, format_num, format_url, media, param, request, rewrite_url, val, Comment, Flags, Flair, Post}; use crate::utils::{Comment, Flags, Flair, Post, Preferences, cookie, error, format_num, format_url, media, param, prefs, request, rewrite_url, val};
use actix_web::{HttpRequest, HttpResponse}; use actix_web::{HttpRequest, HttpResponse};
use async_recursion::async_recursion; use async_recursion::async_recursion;
@ -14,6 +14,7 @@ struct PostTemplate {
comments: Vec<Comment>, comments: Vec<Comment>,
post: Post, post: Post,
sort: String, sort: String,
prefs: Preferences
} }
pub async fn item(req: HttpRequest) -> HttpResponse { pub async fn item(req: HttpRequest) -> HttpResponse {
@ -45,7 +46,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 { comments, post, sort }.render().unwrap(); let s = PostTemplate { comments, post, sort, prefs: prefs(req) }.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

View File

@ -15,6 +15,7 @@ struct SettingsTemplate {
pub struct SettingsForm { pub struct SettingsForm {
front_page: Option<String>, front_page: Option<String>,
layout: Option<String>, layout: Option<String>,
wide: Option<String>,
comment_sort: Option<String>, comment_sort: Option<String>,
hide_nsfw: Option<String>, hide_nsfw: Option<String>,
} }
@ -31,8 +32,8 @@ pub async fn get(req: HttpRequest) -> HttpResponse {
pub async fn set(req: HttpRequest, form: Form<SettingsForm>) -> HttpResponse { pub async fn set(req: HttpRequest, form: Form<SettingsForm>) -> HttpResponse {
let mut res = HttpResponse::Found(); let mut res = HttpResponse::Found();
let names = vec!["front_page", "layout", "comment_sort", "hide_nsfw"]; let names = vec!["front_page", "layout", "wide", "comment_sort", "hide_nsfw"];
let values = vec![&form.front_page, &form.layout, &form.comment_sort, &form.hide_nsfw]; let values = vec![&form.front_page, &form.layout, &form.wide, &form.comment_sort, &form.hide_nsfw];
for (i, name) in names.iter().enumerate() { for (i, name) in names.iter().enumerate() {
match values[i] { match values[i] {

View File

@ -20,6 +20,7 @@ struct WikiTemplate {
sub: String, sub: String,
wiki: String, wiki: String,
page: String, page: String,
prefs: Preferences,
} }
// SERVICES // SERVICES
@ -67,6 +68,7 @@ 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(),
prefs: prefs(req),
} }
.render() .render()
.unwrap(); .unwrap();

View File

@ -96,6 +96,7 @@ pub struct ErrorTemplate {
pub struct Preferences { pub struct Preferences {
pub front_page: String, pub front_page: String,
pub layout: String, pub layout: String,
pub wide: String,
pub hide_nsfw: String, pub hide_nsfw: String,
pub comment_sort: String, pub comment_sort: String,
} }
@ -109,6 +110,7 @@ pub fn prefs(req: HttpRequest) -> Preferences {
Preferences { Preferences {
front_page: cookie(&req, "front_page"), front_page: cookie(&req, "front_page"),
layout: cookie(&req, "layout"), layout: cookie(&req, "layout"),
wide: cookie(&req, "wide"),
hide_nsfw: cookie(&req, "hide_nsfw"), hide_nsfw: cookie(&req, "hide_nsfw"),
comment_sort: cookie(&req, "comment_sort"), comment_sort: cookie(&req, "comment_sort"),
} }

View File

@ -2,6 +2,7 @@
:root { :root {
--accent: aqua; --accent: aqua;
--green: #5cff85;
--text: white; --text: white;
--foreground: #222; --foreground: #222;
--background: #0F0F0F; --background: #0F0F0F;
@ -62,6 +63,15 @@ main {
margin: 60px auto 20px auto margin: 60px auto 20px auto
} }
.wide main {
max-width: calc(100% - 40px);
}
.wide #column_one {
width: 100%;
max-width: 100%;
}
#column_one { #column_one {
max-width: 750px; max-width: 750px;
border-radius: 5px; border-radius: 5px;
@ -454,8 +464,8 @@ input[type="submit"]:hover { color: var(--accent); }
} }
.stickied { .stickied {
--accent: #5cff85; --accent: var(--green);
border: 1px solid #5cff85; border: 1px solid var(--green);
} }
/* Comment */ /* Comment */
@ -567,60 +577,60 @@ input[type="submit"]:hover { color: var(--accent); }
/* Layouts */ /* Layouts */
#compact .post:not(.highlighted) { .compact .post:not(.highlighted) {
border-radius: 0; border-radius: 0;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
#compact .post:first-of-type { .compact .post:first-of-type {
border-radius: 5px 5px 0 0; border-radius: 5px 5px 0 0;
overflow: hidden; overflow: hidden;
} }
#compact .post:last-of-type { .compact .post:last-of-type {
border-radius: 0 0 5px 5px; border-radius: 0 0 5px 5px;
overflow: hidden; overflow: hidden;
} }
#compact .post.highlighted { .compact .post.highlighted {
border-radius: 5px; border-radius: 5px;
} }
#compact .post:not(:last-of-type):not(.highlighted):not(.stickied) { .compact .post:not(:last-of-type):not(.highlighted):not(.stickied) {
border-bottom: 0; border-bottom: 0;
} }
#compact .post_left { .compact .post_left {
border-radius: 0; border-radius: 0;
} }
#compact .post_header { .compact .post_header {
font-size: 14px; font-size: 14px;
} }
#compact .post_title { .compact .post_title {
margin-top: 5px; margin-top: 5px;
} }
#compact .post_text { .compact .post_text {
padding: 10px; padding: 10px;
} }
#compact .post_thumbnail { .compact .post_thumbnail {
max-width: 75px; max-width: 75px;
max-height: 75px; max-height: 75px;
} }
#compact footer { .compact footer {
margin-top: 20px; margin-top: 20px;
} }
#card .post_right { .card .post_right {
flex-direction: column; flex-direction: column;
} }
#card .post:not(.highlighted) .post_media { .card .post:not(.highlighted) .post_media {
margin-top: 0; margin-top: 0;
margin-bottom: 15px; margin-bottom: 15px;
} }

View File

@ -11,7 +11,7 @@
<link rel="stylesheet" href="/style.css"> <link rel="stylesheet" href="/style.css">
{% endblock %} {% endblock %}
</head> </head>
<body id="{% block layout %}{% endblock %}"> <body class="{% block ui %}{% endblock %}">
<!-- NAVIGATION BAR --> <!-- NAVIGATION BAR -->
<nav> <nav>
<p id="logo"> <p id="logo">

View File

@ -7,6 +7,8 @@
{% call utils::search(["/r/", post.community.as_str()].concat(), "") %} {% call utils::search(["/r/", post.community.as_str()].concat(), "") %}
{% endblock %} {% endblock %}
{% block ui %}{% if prefs.wide == "on" %} wide{% endif %}{% endblock %}
{% block root %}/r/{{ post.community }}{% endblock %}{% block location %}r/{{ post.community }}{% endblock %} {% block root %}/r/{{ post.community }}{% endblock %}{% block location %}r/{{ post.community }}{% endblock %}
{% block head %} {% block head %}
{% call super() %} {% call super() %}

View File

@ -3,7 +3,7 @@
{% block title %}Libreddit: search results - {{ params.q }}{% endblock %} {% block title %}Libreddit: search results - {{ params.q }}{% endblock %}
{% block layout %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% endblock %} {% block ui %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% if prefs.wide == "on" %} wide{% endif %}{% endblock %}
{% block content %} {% block content %}
<div id="column_one"> <div id="column_one">

View File

@ -7,35 +7,39 @@
{% call utils::search("".to_owned(), "", "") %} {% call utils::search("".to_owned(), "", "") %}
{% endblock %} {% endblock %}
{% block body %} {% block content %}
<main> <form id="settings" action="/settings" method="POST">
<form id="settings" action="/settings" method="POST"> <div id="prefs">
<div id="prefs"> <p>Interface</p>
<div id="front_page"> <div id="front_page">
<label for="front_page">Front page:</label> <label for="front_page">Front page:</label>
<select name="front_page"> <select name="front_page">
{% call utils::options(prefs.front_page, ["popular", "all"], "popular") %} {% call utils::options(prefs.front_page, ["popular", "all"], "popular") %}
</select> </select>
</div> </div>
<div id="layout"> <div id="layout">
<label for="layout">Layout:</label> <label for="layout">Layout:</label>
<select name="layout"> <select name="layout">
{% call utils::options(prefs.layout, ["card", "clean", "compact"], "clean") %} {% call utils::options(prefs.layout, ["card", "clean", "compact"], "clean") %}
</select> </select>
</div> </div>
<div id="comment_sort"> <div id="wide">
<label for="comment_sort">Default comment sort:</label> <label for="wide">Wide UI:</label>
<select name="comment_sort"> <input type="checkbox" name="wide" {% if prefs.wide == "on" %}checked{% endif %}>
{% call utils::options(prefs.comment_sort, ["confidence", "top", "new", "controversial", "old"], "confidence") %} </div>
</select> <p>Sorting / Filtering</p>
</div> <div id="comment_sort">
<div id="hide_nsfw"> <label for="comment_sort">Default comment sort:</label>
<label for="hide_nsfw">Hide NSFW posts:</label> <select name="comment_sort">
<input type="checkbox" name="hide_nsfw" {% if prefs.hide_nsfw == "on" %}checked{% endif %}> {% call utils::options(prefs.comment_sort, ["confidence", "top", "new", "controversial", "old"], "confidence") %}
</div> </select>
</div> </div>
<p id="settings_note"><b>Note:</b> settings are saved in browser cookies. Clearing your cookie data will reset them.</p> <div id="hide_nsfw">
<input id="save" type="submit" value="Save"> <label for="hide_nsfw">Hide NSFW posts:</label>
</form> <input type="checkbox" name="hide_nsfw" {% if prefs.hide_nsfw == "on" %}checked{% endif %}>
</main> </div>
</div>
<p id="settings_note"><b>Note:</b> settings are saved in browser cookies. Clearing your cookie data will reset them.</p>
<input id="save" type="submit" value="Save">
</form>
{% endblock %} {% endblock %}

View File

@ -11,7 +11,7 @@
{% call utils::search(["/r/", sub.name.as_str()].concat(), "") %} {% call utils::search(["/r/", sub.name.as_str()].concat(), "") %}
{% endblock %} {% endblock %}
{% block layout %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% endblock %} {% block ui %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% if prefs.wide == "on" %} wide{% endif %}{% endblock %}
{% block body %} {% block body %}
<main> <main>

View File

@ -7,10 +7,10 @@
{% 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 prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% endblock %} {% block ui %}{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}{% if prefs.wide == "on" %} wide{% endif %}{% endblock %}
{% block body %} {% block body %}
<main style="max-width: 1000px;"> <main>
<div id="column_one"> <div id="column_one">
<form id="sort"> <form id="sort">
<select name="sort"> <select name="sort">

View File

@ -6,6 +6,8 @@
{% else %}Libreddit{% endif %} {% else %}Libreddit{% endif %}
{% endblock %} {% endblock %}
{% block ui %}{% if prefs.wide == "on" %} wide{% endif %}{% endblock %}
{% block search %} {% block search %}
{% call utils::search(["/r/", sub.as_str()].concat(), "") %} {% call utils::search(["/r/", sub.as_str()].concat(), "") %}
{% endblock %} {% endblock %}