Set subscriptions as default front page
This commit is contained in:
parent
9c58d23b41
commit
21d96e261f
19
src/main.rs
19
src/main.rs
@ -54,7 +54,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.wrap_fn(move |req, srv| {
|
.wrap_fn(move |req, srv| {
|
||||||
let secure = req.connection_info().scheme() == "https";
|
let secure = req.connection_info().scheme() == "https";
|
||||||
let https_url = format!("https://{}{}", req.connection_info().host(), req.uri().to_string());
|
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 {
|
if force_https && !secure {
|
||||||
Ok(ServiceResponse::new(
|
Ok(ServiceResponse::new(
|
||||||
res.unwrap().request().to_owned(),
|
res.unwrap().request().to_owned(),
|
||||||
@ -63,16 +63,21 @@ async fn main() -> std::io::Result<()> {
|
|||||||
} else {
|
} else {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
})
|
})
|
||||||
// Append trailing slash and remove double slashes
|
// Append trailing slash and remove double slashes
|
||||||
.wrap(middleware::NormalizePath::default())
|
.wrap(middleware::NormalizePath::default())
|
||||||
// Apply default headers for security
|
// Apply default headers for security
|
||||||
.wrap(middleware::DefaultHeaders::new()
|
.wrap(
|
||||||
.header("Referrer-Policy", "no-referrer")
|
middleware::DefaultHeaders::new()
|
||||||
.header("X-Content-Type-Options", "nosniff")
|
.header("Referrer-Policy", "no-referrer")
|
||||||
.header("X-Frame-Options", "DENY")
|
.header("X-Content-Type-Options", "nosniff")
|
||||||
.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';"))
|
.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 in case no routes match
|
||||||
.default_service(web::get().to(|| utils::error("Nothing here".to_string())))
|
.default_service(web::get().to(|| utils::error("Nothing here".to_string())))
|
||||||
// Read static files
|
// Read static files
|
||||||
|
32
src/proxy.rs
32
src/proxy.rs
@ -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());
|
let decoded = decode(b64).map(|bytes| String::from_utf8(bytes).unwrap_or_default());
|
||||||
|
|
||||||
match decoded {
|
match decoded {
|
||||||
Ok(media) => {
|
Ok(media) => match Url::parse(media.as_str()) {
|
||||||
match Url::parse(media.as_str()) {
|
Ok(url) => {
|
||||||
Ok(url) => {
|
let domain = url.domain().unwrap_or_default();
|
||||||
let domain = url.domain().unwrap_or_default();
|
|
||||||
|
|
||||||
if domains.contains(&domain) {
|
if domains.contains(&domain) {
|
||||||
Client::default().get(media.replace("&", "&")).send().await.map_err(Error::from).map(|res| {
|
Client::default().get(media.replace("&", "&")).send().await.map_err(Error::from).map(|res| {
|
||||||
HttpResponse::build(res.status())
|
HttpResponse::build(res.status())
|
||||||
.header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
|
.header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
|
||||||
.header("Content-Length", res.headers().get("Content-Length").unwrap().to_owned())
|
.header("Content-Length", res.headers().get("Content-Length").unwrap().to_owned())
|
||||||
.header("Content-Type", res.headers().get("Content-Type").unwrap().to_owned())
|
.header("Content-Type", res.headers().get("Content-Type").unwrap().to_owned())
|
||||||
.streaming(res)
|
.streaming(res)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(error::ErrorForbidden("Resource must be from Reddit"))
|
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")),
|
_ => Err(error::ErrorBadRequest("Can't decode base64")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,25 +26,44 @@ struct WikiTemplate {
|
|||||||
|
|
||||||
// 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 subscribed = cookie(&req, "subscriptions");
|
||||||
let default = cookie(&req, "front_page");
|
let front_page = cookie(&req, "front_page");
|
||||||
|
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
|
||||||
|
|
||||||
let sub = req
|
let sub = req
|
||||||
.match_info()
|
.match_info()
|
||||||
.get("sub")
|
.get("sub")
|
||||||
.unwrap_or(if default.is_empty() { "popular" } else { default.as_str() })
|
.map(String::from)
|
||||||
.to_string();
|
.unwrap_or(if front_page == "default" || front_page.is_empty() {
|
||||||
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
|
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 {
|
match fetch_posts(&path, String::new()).await {
|
||||||
Ok((posts, after)) => {
|
Ok((posts, after)) => {
|
||||||
// If you can get subreddit posts, also request subreddit metadata
|
// 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()
|
subreddit(&sub).await.unwrap_or_default()
|
||||||
} else if sub.contains('+') {
|
} else if sub.contains('+') {
|
||||||
|
// Multireddit
|
||||||
Subreddit {
|
Subreddit {
|
||||||
name: sub,
|
name: sub,
|
||||||
..Subreddit::default()
|
..Subreddit::default()
|
||||||
}
|
}
|
||||||
|
} else if sub == subscribed {
|
||||||
|
if req.path().starts_with("/r/") {
|
||||||
|
subreddit(&sub).await.unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
Subreddit::default()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Subreddit::default()
|
Subreddit::default()
|
||||||
};
|
};
|
||||||
@ -84,11 +103,13 @@ pub async fn subscriptions(req: HttpRequest) -> HttpResponse {
|
|||||||
if sub_list.is_empty() {
|
if sub_list.is_empty() {
|
||||||
res.del_cookie(&Cookie::build("subscriptions", "").path("/").finish());
|
res.del_cookie(&Cookie::build("subscriptions", "").path("/").finish());
|
||||||
} else {
|
} else {
|
||||||
res.cookie(Cookie::build("subscriptions", sub_list.join(","))
|
res.cookie(
|
||||||
.path("/")
|
Cookie::build("subscriptions", sub_list.join("+"))
|
||||||
.http_only(true)
|
.path("/")
|
||||||
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
|
.http_only(true)
|
||||||
.finish(),);
|
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
|
||||||
|
.finish(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect back to subreddit
|
// Redirect back to subreddit
|
||||||
|
@ -145,7 +145,7 @@ pub fn prefs(req: HttpRequest) -> Preferences {
|
|||||||
wide: cookie(&req, "wide"),
|
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"),
|
||||||
subs: cookie(&req, "subscriptions").split(",").map(String::from).filter(|s| s != "").collect(),
|
subs: cookie(&req, "subscriptions").split('+').map(String::from).filter(|s| s != "").collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,13 +95,23 @@ nav {
|
|||||||
nav * { color: var(--text); }
|
nav * { color: var(--text); }
|
||||||
nav #reddit, #code { color: var(--accent); }
|
nav #reddit, #code { color: var(--accent); }
|
||||||
nav #logo { grid-area: logo; }
|
nav #logo { grid-area: logo; }
|
||||||
nav #links { grid-area: links; }
|
|
||||||
|
|
||||||
nav #version { opacity: 50%; vertical-align: -2px; }
|
nav #links {
|
||||||
nav #libreddit { vertical-align: -2px; }
|
grid-area: links;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav #version {
|
||||||
|
opacity: 50%;
|
||||||
|
vertical-align: -2px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav #libreddit {
|
||||||
|
vertical-align: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
#settings_link {
|
#settings_link {
|
||||||
margin-left: 10px;
|
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,17 +250,18 @@ aside {
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sub_subscription > a {
|
#sub_subscription button {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sub_subscription > .add {
|
#subscribe {
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
background-color: var(--accent);
|
background-color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
#sub_subscription > .remove {
|
#unsubscribe {
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
background-color: var(--highlighted);
|
background-color: var(--highlighted);
|
||||||
}
|
}
|
||||||
@ -266,11 +277,10 @@ aside {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#subscriptions > summary {
|
#subscriptions > summary {
|
||||||
padding: 10px 20px 10px 15px;
|
padding: 8px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sub_list {
|
#sub_list {
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<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, ["default", "popular", "all"], "default") %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div id="layout">
|
<div id="layout">
|
||||||
|
@ -127,9 +127,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="sub_subscription">
|
<div id="sub_subscription">
|
||||||
{% if prefs.subs.contains(sub.name) %}
|
{% 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 %}
|
{% 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 %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user