Set subscriptions as default front page

This commit is contained in:
spikecodes 2021-01-30 20:18:57 -08:00
parent 9c58d23b41
commit 21d96e261f
No known key found for this signature in database
GPG Key ID: 004CECFF9B463BCB
7 changed files with 86 additions and 48 deletions

View File

@ -54,7 +54,7 @@ async fn main() -> std::io::Result<()> {
.wrap_fn(move |req, srv| {
let secure = req.connection_info().scheme() == "https";
let https_url = format!("https://{}{}", req.connection_info().host(), req.uri().to_string());
srv.call(req).map(move |res: Result<ServiceResponse, _>|
srv.call(req).map(move |res: Result<ServiceResponse, _>| {
if force_https && !secure {
Ok(ServiceResponse::new(
res.unwrap().request().to_owned(),
@ -63,16 +63,21 @@ async fn main() -> std::io::Result<()> {
} else {
res
}
)
})
})
// Append trailing slash and remove double slashes
.wrap(middleware::NormalizePath::default())
// Apply default headers for security
.wrap(middleware::DefaultHeaders::new()
.header("Referrer-Policy", "no-referrer")
.header("X-Content-Type-Options", "nosniff")
.header("X-Frame-Options", "DENY")
.header("Content-Security-Policy", "default-src 'none'; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none';"))
.wrap(
middleware::DefaultHeaders::new()
.header("Referrer-Policy", "no-referrer")
.header("X-Content-Type-Options", "nosniff")
.header("X-Frame-Options", "DENY")
.header(
"Content-Security-Policy",
"default-src 'none'; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none';",
),
)
// Default service in case no routes match
.default_service(web::get().to(|| utils::error("Nothing here".to_string())))
// Read static files

View File

@ -24,26 +24,24 @@ pub async fn handler(web::Path(b64): web::Path<String>) -> Result<HttpResponse>
let decoded = decode(b64).map(|bytes| String::from_utf8(bytes).unwrap_or_default());
match decoded {
Ok(media) => {
match Url::parse(media.as_str()) {
Ok(url) => {
let domain = url.domain().unwrap_or_default();
Ok(media) => match Url::parse(media.as_str()) {
Ok(url) => {
let domain = url.domain().unwrap_or_default();
if domains.contains(&domain) {
Client::default().get(media.replace("&amp;", "&")).send().await.map_err(Error::from).map(|res| {
HttpResponse::build(res.status())
.header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
.header("Content-Length", res.headers().get("Content-Length").unwrap().to_owned())
.header("Content-Type", res.headers().get("Content-Type").unwrap().to_owned())
.streaming(res)
})
} else {
Err(error::ErrorForbidden("Resource must be from Reddit"))
}
if domains.contains(&domain) {
Client::default().get(media.replace("&amp;", "&")).send().await.map_err(Error::from).map(|res| {
HttpResponse::build(res.status())
.header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
.header("Content-Length", res.headers().get("Content-Length").unwrap().to_owned())
.header("Content-Type", res.headers().get("Content-Type").unwrap().to_owned())
.streaming(res)
})
} else {
Err(error::ErrorForbidden("Resource must be from Reddit"))
}
_ => Err(error::ErrorBadRequest("Can't parse base64 into URL")),
}
}
_ => Err(error::ErrorBadRequest("Can't parse base64 into URL")),
},
_ => Err(error::ErrorBadRequest("Can't decode base64")),
}
}

View File

@ -26,25 +26,44 @@ struct WikiTemplate {
// SERVICES
pub async fn page(req: HttpRequest) -> HttpResponse {
let path = format!("{}.json?{}", req.path(), req.query_string());
let default = cookie(&req, "front_page");
let subscribed = cookie(&req, "subscriptions");
let front_page = cookie(&req, "front_page");
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
let sub = req
.match_info()
.get("sub")
.unwrap_or(if default.is_empty() { "popular" } else { default.as_str() })
.to_string();
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
.map(String::from)
.unwrap_or(if front_page == "default" || front_page.is_empty() {
if subscribed.is_empty() {
"popular".to_string()
} else {
subscribed.to_owned()
}
} else {
front_page.to_owned()
});
let path = format!("/r/{}.json?{}", sub, req.query_string());
match fetch_posts(&path, String::new()).await {
Ok((posts, after)) => {
// If you can get subreddit posts, also request subreddit metadata
let sub = if !sub.contains('+') && sub != "popular" && sub != "all" {
let sub = if !sub.contains('+') && sub != subscribed && sub != "popular" && sub != "all" {
// Regular subreddit
subreddit(&sub).await.unwrap_or_default()
} else if sub.contains('+') {
// Multireddit
Subreddit {
name: sub,
..Subreddit::default()
}
} else if sub == subscribed {
if req.path().starts_with("/r/") {
subreddit(&sub).await.unwrap_or_default()
} else {
Subreddit::default()
}
} else {
Subreddit::default()
};
@ -84,11 +103,13 @@ pub async fn subscriptions(req: HttpRequest) -> HttpResponse {
if sub_list.is_empty() {
res.del_cookie(&Cookie::build("subscriptions", "").path("/").finish());
} else {
res.cookie(Cookie::build("subscriptions", sub_list.join(","))
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),);
res.cookie(
Cookie::build("subscriptions", sub_list.join("+"))
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),
);
}
// Redirect back to subreddit

View File

@ -145,7 +145,7 @@ pub fn prefs(req: HttpRequest) -> Preferences {
wide: cookie(&req, "wide"),
hide_nsfw: cookie(&req, "hide_nsfw"),
comment_sort: cookie(&req, "comment_sort"),
subs: cookie(&req, "subscriptions").split(",").map(String::from).filter(|s| s != "").collect(),
subs: cookie(&req, "subscriptions").split('+').map(String::from).filter(|s| s != "").collect(),
}
}

View File

@ -95,13 +95,23 @@ nav {
nav * { color: var(--text); }
nav #reddit, #code { color: var(--accent); }
nav #logo { grid-area: logo; }
nav #links { grid-area: links; }
nav #version { opacity: 50%; vertical-align: -2px; }
nav #libreddit { vertical-align: -2px; }
nav #links {
grid-area: links;
margin-left: 10px;
}
nav #version {
opacity: 50%;
vertical-align: -2px;
margin-right: 10px;
}
nav #libreddit {
vertical-align: -2px;
}
#settings_link {
margin-left: 10px;
opacity: 0.8;
}
@ -240,17 +250,18 @@ aside {
margin-top: 20px;
}
#sub_subscription > a {
#sub_subscription button {
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}
#sub_subscription > .add {
#subscribe {
color: var(--foreground);
background-color: var(--accent);
}
#sub_subscription > .remove {
#unsubscribe {
color: var(--text);
background-color: var(--highlighted);
}
@ -266,11 +277,10 @@ aside {
box-sizing: border-box;
font-size: 15px;
display: inline-block;
margin-left: 10px;
}
#subscriptions > summary {
padding: 10px 20px 10px 15px;
padding: 8px 15px;
}
#sub_list {

View File

@ -21,7 +21,7 @@
<div id="front_page">
<label for="front_page">Front page:</label>
<select name="front_page">
{% call utils::options(prefs.front_page, ["popular", "all"], "popular") %}
{% call utils::options(prefs.front_page, ["default", "popular", "all"], "default") %}
</select>
</div>
<div id="layout">

View File

@ -127,9 +127,13 @@
</div>
<div id="sub_subscription">
{% if prefs.subs.contains(sub.name) %}
<a href="/r/{{ sub.name }}/unsubscribe" class="subscribe remove">Unsubscribe</a>
<form action="/r/{{ sub.name }}/unsubscribe">
<button id="unsubscribe">Unsubscribe</button>
</form>
{% else %}
<a href="/r/{{ sub.name }}/subscribe" class="subscribe add">Subscribe</a>
<form action="/r/{{ sub.name }}/subscribe">
<button id="subscribe">Subscribe</button>
</form>
{% endif %}
</div>
</div>