Compare commits

...

9 Commits

11 changed files with 72 additions and 176 deletions

View File

@ -23,6 +23,10 @@ jobs:
- name: Build - name: Build
run: cargo build --release run: cargo build --release
- name: Publish to crates.io
continue-on-error: true
run: cargo publish --no-verify --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
- uses: actions/upload-artifact@v2.2.1 - uses: actions/upload-artifact@v2.2.1
name: Upload a Build Artifact name: Upload a Build Artifact
with: with:

157
Cargo.lock generated
View File

@ -99,12 +99,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base-x"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.13.0" version = "0.13.0"
@ -186,17 +180,11 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "const_fn"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7"
[[package]] [[package]]
name = "cookie" name = "cookie"
version = "0.15.1" version = "0.16.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d" checksum = "188a7c2ae2a1026b9831889fd6461db5d33c4f6d54d6f862bd8b81a2fcefbdba"
dependencies = [ dependencies = [
"time", "time",
"version_check", "version_check",
@ -253,12 +241,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "discard"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.1" version = "2.5.1"
@ -572,7 +554,7 @@ checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]] [[package]]
name = "libreddit" name = "libreddit"
version = "0.20.4" version = "0.21.3"
dependencies = [ dependencies = [
"askama", "askama",
"async-recursion", "async-recursion",
@ -740,26 +722,20 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.35" version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "392a54546fda6b7cc663379d0e6ce8b324cf88aecc5a499838e1be9781bdce2e" checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.10" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -811,15 +787,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.20.2" version = "0.20.2"
@ -908,21 +875,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.132" version = "1.0.132"
@ -954,12 +906,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "sha1"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.0" version = "1.4.0"
@ -997,64 +943,6 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "standback"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
dependencies = [
"version_check",
]
[[package]]
name = "stdweb"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
dependencies = [
"discard",
"rustc_version",
"stdweb-derive",
"stdweb-internal-macros",
"stdweb-internal-runtime",
"wasm-bindgen",
]
[[package]]
name = "stdweb-derive"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
dependencies = [
"proc-macro2",
"quote",
"serde",
"serde_derive",
"syn",
]
[[package]]
name = "stdweb-internal-macros"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
dependencies = [
"base-x",
"proc-macro2",
"quote",
"serde",
"serde_derive",
"serde_json",
"sha1",
"syn",
]
[[package]]
name = "stdweb-internal-runtime"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.10.0"
@ -1083,41 +971,20 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.2.27" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad"
dependencies = [ dependencies = [
"const_fn", "itoa 0.4.8",
"libc", "libc",
"standback",
"stdweb",
"time-macros", "time-macros",
"version_check",
"winapi",
] ]
[[package]] [[package]]
name = "time-macros" name = "time-macros"
version = "0.1.1" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
dependencies = [
"proc-macro-hack",
"time-macros-impl",
]
[[package]]
name = "time-macros-impl"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"standback",
"syn",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"

View File

@ -3,7 +3,7 @@ name = "libreddit"
description = " Alternative private front-end to Reddit" description = " Alternative private front-end to Reddit"
license = "AGPL-3.0" license = "AGPL-3.0"
repository = "https://github.com/spikecodes/libreddit" repository = "https://github.com/spikecodes/libreddit"
version = "0.20.4" version = "0.21.3"
authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"] authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"]
edition = "2021" edition = "2021"
@ -14,12 +14,12 @@ cached = "0.26.2"
clap = { version = "2.34.0", default-features = false } clap = { version = "2.34.0", default-features = false }
regex = "1.5.4" regex = "1.5.4"
serde = { version = "1.0.132", features = ["derive"] } serde = { version = "1.0.132", features = ["derive"] }
cookie = "0.15.1" cookie = "0.16.0-rc.1"
futures-lite = "1.12.0" futures-lite = "1.12.0"
hyper = { version = "0.14.16", features = ["full"] } hyper = { version = "0.14.16", features = ["full"] }
hyper-rustls = "0.23.0" hyper-rustls = "0.23.0"
route-recognizer = "0.3.1" route-recognizer = "0.3.1"
serde_json = "1.0.73" serde_json = "1.0.73"
tokio = { version = "1.15.0", features = ["full"] } tokio = { version = "1.15.0", features = ["full"] }
time = "0.2.7" time = "0.3.5"
url = "2.2.2" url = "2.2.2"

View File

@ -66,6 +66,7 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
| [libreddit.hu](https://libreddit.hu) | 🇫🇮 FI | ✅ | | [libreddit.hu](https://libreddit.hu) | 🇫🇮 FI | ✅ |
| [libreddit.totaldarkness.net](https://libreddit.totaldarkness.net) | 🇨🇦 CA | | | [libreddit.totaldarkness.net](https://libreddit.totaldarkness.net) | 🇨🇦 CA | |
| [libreddit.esmailelbob.xyz](https://libreddit.esmailelbob.xyz) | 🇪🇬 EG | | | [libreddit.esmailelbob.xyz](https://libreddit.esmailelbob.xyz) | 🇪🇬 EG | |
| [libreddit.nl](https://libreddit.nl) | 🇳🇱 NL | |
| [spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion](http://spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion) | 🇮🇳 IN | | | [spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion](http://spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion) | 🇮🇳 IN | |
| [fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion](http://fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion) | 🇩🇪 DE | | | [fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion](http://fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion) | 🇩🇪 DE | |
| [kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion](http://kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion) | 🇳🇱 NL | | | [kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion](http://kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion) | 🇳🇱 NL | |

View File

@ -97,12 +97,20 @@ async fn parse_post(json: &serde_json::Value) -> Post {
let awards: Awards = Awards::parse(&post["data"]["all_awardings"]); let awards: Awards = Awards::parse(&post["data"]["all_awardings"]);
let permalink = val(post, "permalink");
let body = if val(post, "removed_by_category") == "moderator" {
format!("<div class=\"md\"><p>[removed] — <a href=\"https://www.reveddit.com{}\">view removed post</a></p></div>", permalink)
} else {
rewrite_urls(&val(post, "selftext_html")).replace("\\", "")
};
// Build a post using data parsed from Reddit post API // Build a post using data parsed from Reddit post API
Post { Post {
id: val(post, "id"), id: val(post, "id"),
title: esc!(post, "title"), title: esc!(post, "title"),
community: val(post, "subreddit"), community: val(post, "subreddit"),
body: rewrite_urls(&val(post, "selftext_html")).replace("\\", ""), body,
author: Author { author: Author {
name: val(post, "author"), name: val(post, "author"),
flair: Flair { flair: Flair {
@ -117,7 +125,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
}, },
distinguished: val(post, "distinguished"), distinguished: val(post, "distinguished"),
}, },
permalink: val(post, "permalink"), permalink,
score: format_num(score), score: format_num(score),
upvote_ratio: ratio as i64, upvote_ratio: ratio as i64,
post_type, post_type,
@ -174,7 +182,6 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
let edited = data["edited"].as_f64().map_or((String::new(), String::new()), time); let edited = data["edited"].as_f64().map_or((String::new(), String::new()), time);
let score = data["score"].as_i64().unwrap_or(0); let score = data["score"].as_i64().unwrap_or(0);
let body = rewrite_urls(&val(&comment, "body_html"));
// If this comment contains replies, handle those too // If this comment contains replies, handle those too
let replies: Vec<Comment> = if data["replies"].is_object() { let replies: Vec<Comment> = if data["replies"].is_object() {
@ -191,6 +198,12 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
let id = val(&comment, "id"); let id = val(&comment, "id");
let highlighted = id == highlighted_comment; let highlighted = id == highlighted_comment;
let body = if val(&comment, "author") == "[deleted]" && val(&comment, "body") == "[removed]" {
format!("<div class=\"md\"><p>[removed] — <a href=\"https://www.reveddit.com{}{}\">view removed comment</a></p></div>", post_link, id)
} else {
rewrite_urls(&val(&comment, "body_html")).to_string()
};
let author = Author { let author = Author {
name: val(&comment, "author"), name: val(&comment, "author"),
flair: Flair { flair: Flair {

View File

@ -105,7 +105,7 @@ impl ResponseExt for Response<Body> {
fn remove_cookie(&mut self, name: String) { fn remove_cookie(&mut self, name: String) {
let mut cookie = Cookie::named(name); let mut cookie = Cookie::named(name);
cookie.set_path("/"); cookie.set_path("/");
cookie.set_max_age(Duration::second()); cookie.set_max_age(Duration::seconds(1));
if let Ok(val) = HeaderValue::from_str(&cookie.to_string()) { if let Ok(val) = HeaderValue::from_str(&cookie.to_string()) {
self.headers_mut().append("Set-Cookie", val); self.headers_mut().append("Set-Cookie", val);
} }

View File

@ -5,7 +5,7 @@ use crate::server::RequestExt;
use crate::utils::{error, filter_posts, format_url, get_filters, param, template, Post, Preferences, User}; use crate::utils::{error, filter_posts, format_url, get_filters, param, template, Post, Preferences, User};
use askama::Template; use askama::Template;
use hyper::{Body, Request, Response}; use hyper::{Body, Request, Response};
use time::OffsetDateTime; use time::{OffsetDateTime, macros::format_description};
// STRUCTS // STRUCTS
#[derive(Template)] #[derive(Template)]
@ -82,7 +82,8 @@ async fn user(name: &str) -> Result<User, String> {
// Send a request to the url // Send a request to the url
json(path, false).await.map(|res| { json(path, false).await.map(|res| {
// Grab creation date as unix timestamp // Grab creation date as unix timestamp
let created: i64 = res["data"]["created"].as_f64().unwrap_or(0.0).round() as i64; let created_unix = res["data"]["created"].as_f64().unwrap_or(0.0).round() as i64;
let created = OffsetDateTime::from_unix_timestamp(created_unix).unwrap_or(OffsetDateTime::UNIX_EPOCH);
// Closure used to parse JSON from Reddit APIs // Closure used to parse JSON from Reddit APIs
let about = |item| res["data"]["subreddit"][item].as_str().unwrap_or_default().to_string(); let about = |item| res["data"]["subreddit"][item].as_str().unwrap_or_default().to_string();
@ -93,7 +94,7 @@ async fn user(name: &str) -> Result<User, String> {
title: esc!(about("title")), title: esc!(about("title")),
icon: format_url(&about("icon_img")), icon: format_url(&about("icon_img")),
karma: res["data"]["total_karma"].as_i64().unwrap_or(0), karma: res["data"]["total_karma"].as_i64().unwrap_or(0),
created: OffsetDateTime::from_unix_timestamp(created).format("%b %d '%y"), created: created.format(format_description!("%b %d '%y")).unwrap_or_default(),
banner: esc!(about("banner_img")), banner: esc!(about("banner_img")),
description: about("public_description"), description: about("public_description"),
} }

View File

@ -9,7 +9,7 @@ use regex::Regex;
use serde_json::Value; use serde_json::Value;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::str::FromStr; use std::str::FromStr;
use time::{Duration, OffsetDateTime}; use time::{Duration, OffsetDateTime, macros::format_description};
use url::Url; use url::Url;
// Post flair with content, background color and foreground color // Post flair with content, background color and foreground color
@ -548,7 +548,7 @@ pub fn format_url(url: &str) -> String {
if url.is_empty() || url == "self" || url == "default" || url == "nsfw" || url == "spoiler" { if url.is_empty() || url == "self" || url == "default" || url == "nsfw" || url == "spoiler" {
String::new() String::new()
} else { } else {
Url::parse(url).map_or(String::new(), |parsed| { Url::parse(url).map_or(url.to_string(), |parsed| {
let domain = parsed.domain().unwrap_or_default(); let domain = parsed.domain().unwrap_or_default();
let capture = |regex: &str, format: &str, segments: i16| { let capture = |regex: &str, format: &str, segments: i16| {
@ -584,6 +584,9 @@ pub fn format_url(url: &str) -> String {
match domain { match domain {
"www.reddit.com" => capture(r"https://www\.reddit\.com/(.*)", "/", 1), "www.reddit.com" => capture(r"https://www\.reddit\.com/(.*)", "/", 1),
"old.reddit.com" => capture(r"https://old\.reddit\.com/(.*)", "/", 1),
"np.reddit.com" => capture(r"https://np\.reddit\.com/(.*)", "/", 1),
"reddit.com" => capture(r"https://reddit\.com/(.*)", "/", 1),
"v.redd.it" => chain!( "v.redd.it" => chain!(
capture(r"https://v\.redd\.it/(.*)/DASH_([0-9]{2,4}(\.mp4|$|\?source=fallback))", "/vid/", 2), capture(r"https://v\.redd\.it/(.*)/DASH_([0-9]{2,4}(\.mp4|$|\?source=fallback))", "/vid/", 2),
capture(r"https://v\.redd\.it/(.+)/(HLSPlaylist\.m3u8.*)$", "/hls/", 2) capture(r"https://v\.redd\.it/(.+)/(HLSPlaylist\.m3u8.*)$", "/hls/", 2)
@ -596,7 +599,7 @@ pub fn format_url(url: &str) -> String {
"external-preview.redd.it" => capture(r"https://external\-preview\.redd\.it/(.*)", "/preview/external-pre/", 1), "external-preview.redd.it" => capture(r"https://external\-preview\.redd\.it/(.*)", "/preview/external-pre/", 1),
"styles.redditmedia.com" => capture(r"https://styles\.redditmedia\.com/(.*)", "/style/", 1), "styles.redditmedia.com" => capture(r"https://styles\.redditmedia\.com/(.*)", "/style/", 1),
"www.redditstatic.com" => capture(r"https://www\.redditstatic\.com/(.*)", "/static/", 1), "www.redditstatic.com" => capture(r"https://www\.redditstatic\.com/(.*)", "/static/", 1),
_ => String::new(), _ => url.to_string(),
} }
}) })
} }
@ -634,12 +637,12 @@ pub fn format_num(num: i64) -> (String, String) {
// Parse a relative and absolute time from a UNIX timestamp // Parse a relative and absolute time from a UNIX timestamp
pub fn time(created: f64) -> (String, String) { pub fn time(created: f64) -> (String, String) {
let time = OffsetDateTime::from_unix_timestamp(created.round() as i64); let time = OffsetDateTime::from_unix_timestamp(created.round() as i64).unwrap_or(OffsetDateTime::UNIX_EPOCH);
let time_delta = OffsetDateTime::now_utc() - time; let time_delta = OffsetDateTime::now_utc() - time;
// If the time difference is more than a month, show full date // If the time difference is more than a month, show full date
let rel_time = if time_delta > Duration::days(30) { let rel_time = if time_delta > Duration::days(30) {
time.format("%b %d '%y") time.format(format_description!("%b %d '%y")).unwrap_or_default()
// Otherwise, show relative date/time // Otherwise, show relative date/time
} else if time_delta.whole_days() > 0 { } else if time_delta.whole_days() > 0 {
format!("{}d ago", time_delta.whole_days()) format!("{}d ago", time_delta.whole_days())
@ -649,7 +652,7 @@ pub fn time(created: f64) -> (String, String) {
format!("{}m ago", time_delta.whole_minutes()) format!("{}m ago", time_delta.whole_minutes())
}; };
(rel_time, time.format("%b %d %Y, %H:%M:%S UTC")) (rel_time, time.format(format_description!("%b %d %Y, %H:%M:%S UTC")).unwrap_or_default())
} }
// val() function used to parse JSON from Reddit APIs // val() function used to parse JSON from Reddit APIs

View File

@ -488,7 +488,7 @@ aside {
/* Sorting and Search */ /* Sorting and Search */
select, #search, #sort_options, #inside, #searchbox > *, #sort_submit { select, #search, #sort_options, #inside, #searchbox > *, #sort_submit {
height: 40px; height: 38px;
} }
.search_label { .search_label {
@ -505,7 +505,7 @@ select {
select, #search { select, #search {
border: none; border: none;
padding: 0 15px; padding: 0 10px;
appearance: none; appearance: none;
-webkit-appearance: none; -webkit-appearance: none;
@ -593,6 +593,7 @@ button.submit:hover > svg { stroke: var(--accent); }
#sort_options, footer > a { #sort_options, footer > a {
border-radius: 5px; border-radius: 5px;
align-items: center;
box-shadow: var(--shadow); box-shadow: var(--shadow);
background: var(--outside); background: var(--outside);
display: flex; display: flex;
@ -719,7 +720,7 @@ a.search_subreddit:hover {
} }
.post_score { .post_score {
padding-top: 16px; padding-top: 19px;
padding-left: 12px; padding-left: 12px;
font-size: 13px; font-size: 13px;
font-weight: bold; font-weight: bold;
@ -875,7 +876,7 @@ a.search_subreddit:hover {
#post_url { #post_url {
color: var(--accent); color: var(--accent);
margin: 5px 15px; margin: 5px 12px;
grid-area: post_media; grid-area: post_media;
} }
@ -902,7 +903,7 @@ a.search_subreddit:hover {
opacity: 0.5; opacity: 0.5;
font-size: 14px; font-size: 14px;
grid-area: post_footer; grid-area: post_footer;
margin: 5px 20px 15px 15px; margin: 5px 20px 15px 12px;
} }
.post_comments { .post_comments {
@ -1180,12 +1181,10 @@ summary.comment_data {
color: var(--accent); color: var(--accent);
} }
.prefs { .prefs {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
align-items: center;
padding: 20px; padding: 20px;
background: var(--post); background: var(--post);
border-radius: 5px; border-radius: 5px;
@ -1198,11 +1197,19 @@ summary.comment_data {
width: 100%; width: 100%;
height: 35px; height: 35px;
align-items: center; align-items: center;
margin-top: 10px; margin-top: 7px;
} }
.prefs > p { .prefs legend {
font-weight: 500; font-weight: 500;
border-bottom: 1px solid var(--highlighted);
font-size: 18px;
padding-bottom: 10px;
}
.prefs legend:not(:first-child) {
padding-top: 10px;
margin-top: 15px;
} }
.prefs select { .prefs select {

View File

@ -56,7 +56,7 @@
{% endif %} {% endif %}
</p> </p>
<p class="post_title"> <p class="post_title">
<a href="{{ post.permalink }}">{{ post.title }}</a> {{ post.title }}
{% if post.flair.flair_parts.len() > 0 %} {% if post.flair.flair_parts.len() > 0 %}
<a href="/r/{{ post.community }}/search?q=flair_name%3A%22{{ post.flair.text }}%22&restrict_sr=on" <a href="/r/{{ post.community }}/search?q=flair_name%3A%22{{ post.flair.text }}%22&restrict_sr=on"
class="post_flair" class="post_flair"

View File

@ -11,14 +11,14 @@
<div id="settings"> <div id="settings">
<form action="/settings" method="POST"> <form action="/settings" method="POST">
<div class="prefs"> <div class="prefs">
<p>Appearance</p> <legend>Appearance</legend>
<div id="theme"> <div id="theme">
<label for="theme">Theme:</label> <label for="theme">Theme:</label>
<select name="theme"> <select name="theme">
{% call utils::options(prefs.theme, ["system", "light", "dark", "black", "dracula", "nord", "laserwave", "violet", "gold", "rosebox"], "system") %} {% call utils::options(prefs.theme, ["system", "light", "dark", "black", "dracula", "nord", "laserwave", "violet", "gold", "rosebox"], "system") %}
</select> </select>
</div> </div>
<p>Interface</p> <legend>Interface</legend>
<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">
@ -36,7 +36,7 @@
<input type="hidden" value="off" name="wide"> <input type="hidden" value="off" name="wide">
<input type="checkbox" name="wide" {% if prefs.wide == "on" %}checked{% endif %}> <input type="checkbox" name="wide" {% if prefs.wide == "on" %}checked{% endif %}>
</div> </div>
<p>Content</p> <legend>Content</legend>
<div id="post_sort"> <div id="post_sort">
<label for="post_sort" title="Applies only to subreddit feeds">Default subreddit post sort:</label> <label for="post_sort" title="Applies only to subreddit feeds">Default subreddit post sort:</label>
<select name="post_sort"> <select name="post_sort">
@ -79,7 +79,7 @@
</form> </form>
{% if prefs.subscriptions.len() > 0 %} {% if prefs.subscriptions.len() > 0 %}
<div class="prefs" id="settings_subs"> <div class="prefs" id="settings_subs">
<p>Subscribed Feeds</p> <legend>Subscribed Feeds</legend>
{% for sub in prefs.subscriptions %} {% for sub in prefs.subscriptions %}
<div> <div>
{% let feed -%} {% let feed -%}
@ -94,7 +94,7 @@
{% endif %} {% endif %}
{% if !prefs.filters.is_empty() %} {% if !prefs.filters.is_empty() %}
<div class="prefs" id="settings_filters"> <div class="prefs" id="settings_filters">
<p>Filtered Feeds</p> <legend>Filtered Feeds</legend>
{% for sub in prefs.filters %} {% for sub in prefs.filters %}
<div> <div>
{% let feed -%} {% let feed -%}