diff --git a/README.md b/README.md index 7ea145c5..6aae711d 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ - [Docker](#docker) - [Docker Compose](#docker-compose) - [Docker CLI](#docker-cli) - - Podman + - Podman - Quadlets - [Binary](#binary) @@ -216,7 +216,7 @@ Stream logs from the Redlib container: ```bash docker logs -f redlib ``` -## Podman +## Podman [Podman](https://podman.io/) lets you run containerized applications in a rootless fashion. Containers are loosely isolated environments that are lightweight and contain everything needed to run the application, so there's no need to rely on what's installed on the host. @@ -225,8 +225,8 @@ Container images for Redlib are available at [quay.io](https://quay.io/repositor ### Quadlets > [!IMPORTANT] -> These instructions assume that you are on a systemd based distro with [podman](https://podman.io/). If not, follow these [instructions on podman's website](https://podman.io/docs/installation) for how to do so. -> It also assumes you have used `loginctl enable-linger ` to enable the service to start for your user without logging in. +> These instructions assume that you are on a systemd based distro with [podman](https://podman.io/). If not, follow these [instructions on podman's website](https://podman.io/docs/installation) for how to do so. +> It also assumes you have used `loginctl enable-linger ` to enable the service to start for your user without logging in. Copy the `redlib.container` and `.env.example` files to `.config/containers/systemd/` and modify any relevant values (for example, the ports Redlib should listen on, renaming the .env file and editing its values, etc.). @@ -244,7 +244,7 @@ systemctl --user start redlib.service ``` You can check the status of your container by using the following command: -```bash +```bash systemctl --user status redlib.service ``` @@ -443,6 +443,7 @@ Assign a default value for each user-modifiable setting by passing environment v | `HIDE_SIDEBAR_AND_SUMMARY` | `["on", "off"]` | `off` | | `FIXED_NAVBAR` | `["on", "off"]` | `on` | | `REMOVE_DEFAULT_FEEDS` | `["on", "off"]` | `off` | +| `POSTS_PER_PAGE` | Integer 1-100 | 25 | ## Forward Proxies diff --git a/app.json b/app.json index 4af7cfec..b388c838 100644 --- a/app.json +++ b/app.json @@ -79,6 +79,9 @@ }, "REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS": { "required": false + }, + "REDLIB_DEFAULT_POSTS_PER_PAGE": { + "required": false } } } diff --git a/src/config.rs b/src/config.rs index 8f92c9b7..c895cc07 100644 --- a/src/config.rs +++ b/src/config.rs @@ -108,6 +108,9 @@ pub struct Config { #[serde(rename = "REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS")] pub(crate) default_remove_default_feeds: Option, + + #[serde(rename = "REDLIB_DEFAULT_POSTS_PER_PAGE")] + pub(crate) default_posts_per_page: Option, } impl Config { @@ -156,6 +159,7 @@ impl Config { enable_rss: parse("REDLIB_ENABLE_RSS"), full_url: parse("REDLIB_FULL_URL"), default_remove_default_feeds: parse("REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS"), + default_posts_per_page: parse("REDLIB_DEFAULT_POSTS_PER_PAGE"), } } } @@ -186,6 +190,7 @@ fn get_setting_from_config(name: &str, config: &Config) -> Option { "REDLIB_ENABLE_RSS" => config.enable_rss.clone(), "REDLIB_FULL_URL" => config.full_url.clone(), "REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS" => config.default_remove_default_feeds.clone(), + "REDLIB_DEFAULT_POSTS_PER_PAGE" => config.default_posts_per_page.clone(), _ => None, } } diff --git a/src/instance_info.rs b/src/instance_info.rs index 8fc46a6a..cb8c2662 100644 --- a/src/instance_info.rs +++ b/src/instance_info.rs @@ -151,6 +151,7 @@ impl InstanceInfo { ["Hide HLS notification", &convert(&self.config.default_hide_hls_notification)], ["Subscriptions", &convert(&self.config.default_subscriptions)], ["Filters", &convert(&self.config.default_filters)], + ["Posts per page", &convert(&self.config.default_posts_per_page)], ]) .with_header_row(["Default preferences"]), ); @@ -187,7 +188,8 @@ impl InstanceInfo { Default use HLS: {:?}\n Default hide HLS notification: {:?}\n Default subscriptions: {:?}\n - Default filters: {:?}\n", + Default filters: {:?}\n + Default posts per page: {:?}\n", self.package_name, self.crate_version, self.git_commit, @@ -215,6 +217,7 @@ impl InstanceInfo { self.config.default_hide_hls_notification, self.config.default_subscriptions, self.config.default_filters, + self.config.default_posts_per_page, ) } StringType::Html => self.to_table(), diff --git a/src/settings.rs b/src/settings.rs index 84cd41a5..02ad4884 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -24,7 +24,7 @@ struct SettingsTemplate { // CONSTANTS -const PREFS: [&str; 19] = [ +const PREFS: [&str; 20] = [ "theme", "front_page", "layout", @@ -44,6 +44,7 @@ const PREFS: [&str; 19] = [ "disable_visit_reddit_confirmation", "video_quality", "remove_default_feeds", + "posts_per_page", ]; // FUNCTIONS diff --git a/src/subreddit.rs b/src/subreddit.rs index 34877250..66cd491b 100644 --- a/src/subreddit.rs +++ b/src/subreddit.rs @@ -140,6 +140,11 @@ pub async fn community(req: Request) -> Result, String> { params.push_str(&format!("&geo_filter={geo_filter}")); } + let posts_per_page: u32 = setting(&req, "posts_per_page").parse().unwrap_or(25).clamp(1, 100); + if posts_per_page != 25 { + params.push_str(&format!("&limit={}", posts_per_page)); + } + let path = format!("/r/{}/{sort}.json?{}{params}", sub_name.replace('+', "%2B"), req.uri().query().unwrap_or_default()); let url = String::from(req.uri().path_and_query().map_or("", |val| val.as_str())); let redirect_url = url[1..].replace('?', "%3F").replace('&', "%26").replace('+', "%2B"); @@ -696,14 +701,14 @@ fn get_rss_image(post: &Post) -> Option { fn get_mime_type(url: &str) -> &'static str { // Extract the path component, removing query parameters let path = url.split('?').next().unwrap_or(url); - + // Get the file extension (everything after the last dot) let extension = path .rsplit('.') .next() .unwrap_or("") .to_lowercase(); - + // Match common image extensions match extension.as_str() { "jpg" | "jpeg" => "image/jpeg", diff --git a/src/utils.rs b/src/utils.rs index 36b798f4..057ddc2a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -618,7 +618,7 @@ pub struct Params { } #[derive(Default, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[revisioned(revision = 1)] +#[revisioned(revision = 2)] pub struct Preferences { #[revision(start = 1)] #[serde(skip_serializing, skip_deserializing)] @@ -667,6 +667,8 @@ pub struct Preferences { pub hide_score: String, #[revision(start = 1)] pub remove_default_feeds: String, + #[revision(start = 2)] + pub posts_per_page: String, } fn serialize_vec_with_plus(vec: &[String], serializer: S) -> Result @@ -725,6 +727,7 @@ impl Preferences { hide_awards: setting(req, "hide_awards"), hide_score: setting(req, "hide_score"), remove_default_feeds: setting(req, "remove_default_feeds"), + posts_per_page: setting(req, "posts_per_page"), } } @@ -1543,10 +1546,11 @@ mod tests { hide_awards: "off".to_owned(), hide_score: "off".to_owned(), remove_default_feeds: "off".to_owned(), + posts_per_page: "25".to_owned(), }; let urlencoded = serde_urlencoded::to_string(prefs).expect("Failed to serialize Prefs"); - assert_eq!(urlencoded, "theme=laserwave&front_page=default&layout=compact&wide=on&blur_spoiler=on&show_nsfw=off&blur_nsfw=on&hide_hls_notification=off&video_quality=best&hide_sidebar_and_summary=off&use_hls=on&autoplay_videos=on&fixed_navbar=on&disable_visit_reddit_confirmation=on&comment_sort=confidence&post_sort=top&subscriptions=memes%2Bmildlyinteresting&filters=&hide_awards=off&hide_score=off&remove_default_feeds=off"); + assert_eq!(urlencoded, "theme=laserwave&front_page=default&layout=compact&wide=on&blur_spoiler=on&show_nsfw=off&blur_nsfw=on&hide_hls_notification=off&video_quality=best&hide_sidebar_and_summary=off&use_hls=on&autoplay_videos=on&fixed_navbar=on&disable_visit_reddit_confirmation=on&comment_sort=confidence&post_sort=top&subscriptions=memes%2Bmildlyinteresting&filters=&hide_awards=off&hide_score=off&remove_default_feeds=off&posts_per_page=25"); } #[test] diff --git a/static/style.css b/static/style.css index c6dada03..711a98f0 100644 --- a/static/style.css +++ b/static/style.css @@ -659,6 +659,7 @@ aside { /* Sorting and Search */ select, +input[type="number"], #search, #sort_options, #listing_options, @@ -684,6 +685,7 @@ select { #searchbox > * { font-size: 15px; } select, +input[type="number"], #search { border: none; padding: 0 10px; @@ -1683,21 +1685,26 @@ summary.comment_data { margin-top: 7px; } -.prefs-group > *:not(:last-child) { +.prefs .prefs-group > *:not(:last-child) { margin-right: 1ch; } -.prefs-group > *:last-child { +.prefs .prefs-group > *:last-child { margin-left: auto; } -.prefs select { +.prefs select, +.prefs input[type="number"] { border-radius: 5px; box-shadow: var(--shadow); margin-left: 20px; background: var(--foreground); } +.prefs input[type="number"] { + max-width: 80px; +} + aside.prefs { margin-top: 20px; } @@ -1978,7 +1985,7 @@ th { max-width: 100%; } #user { margin: 0 0 20px; } - + body.fixed_navbar { min-height: calc(100vh - 75px); padding-top: 45px; diff --git a/templates/settings.html b/templates/settings.html index c3d8086b..33ccf15d 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -72,6 +72,10 @@ "confidence") %} +
+ + +
@@ -214,4 +218,4 @@
-{% endblock %} \ No newline at end of file +{% endblock %}