diff --git a/Cargo.toml b/Cargo.toml index 464b811..5483871 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,4 @@ chrono = { version = "0.4.41", features = ["serde"] } url = { version = "2.5", features = ["serde"] } urlencoding = "2.1" rocket_dyn_templates = { version = "0.2", features = ["tera"] } +plurify = "0.2" diff --git a/src/main.rs b/src/main.rs index 383e634..308ed4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,7 @@ fn index( storage: &State, meta: &State, ) -> Result> { + use plurify::Plurify; #[derive(Serialize)] #[serde(crate = "rocket::serde")] struct Row { @@ -45,32 +46,38 @@ fn index( size: String, torrent: Torrent, } - let rows = storage + let (total, torrents) = storage .torrents( Some((Sort::Modified, Order::Asc)), page.map(|p| if p > 0 { p - 1 } else { p } * storage.default_limit), Some(storage.default_limit), ) - .map_err(|e| Custom(Status::InternalServerError, e.to_string()))? - .into_iter() - .map(|torrent| Row { - created: torrent - .creation_date - .map(|t| t.format(&meta.format_time).to_string()), - indexed: torrent.time.format(&meta.format_time).to_string(), - magnet: format::magnet(&torrent.info_hash, meta.trackers.as_ref()), - size: format::bytes(torrent.size), - torrent, - }) - .collect::>(); + .map_err(|e| Custom(Status::InternalServerError, e.to_string()))?; Ok(Template::render( "index", context! { meta: meta.inner(), back: page.map(|p| uri!(index(if p > 2 { Some(p - 1) } else { None }))), - next: if rows.len() < storage.default_limit { None } + next: if page.unwrap_or(1) * storage.default_limit >= total { None } else { Some(uri!(index(Some(page.map_or(2, |p| p + 1))))) }, - rows + rows: torrents + .into_iter() + .map(|torrent| Row { + created: torrent + .creation_date + .map(|t| t.format(&meta.format_time).to_string()), + indexed: torrent.time.format(&meta.format_time).to_string(), + magnet: format::magnet(&torrent.info_hash, meta.trackers.as_ref()), + size: format::bytes(torrent.size), + torrent, + }) + .collect::>(), + pagination_totals: format!( + "Page {} / {} ({total} {} total)", + page.unwrap_or(1), + (total as f64 / storage.default_limit as f64).ceil(), + total.plurify(&["torrent", "torrents", "torrents"]) + ) }, )) } @@ -85,6 +92,7 @@ fn rss(feed: &State, storage: &State) -> Result, C Some(storage.default_limit), ) .map_err(|e| Custom(Status::InternalServerError, e.to_string()))? + .1 { feed.push(&mut b, torrent) } diff --git a/src/storage.rs b/src/storage.rs index f77d0eb..4db8182 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -76,9 +76,10 @@ impl Storage { sort_order: Option<(Sort, Order)>, start: Option, limit: Option, - ) -> Result, String> { + ) -> Result<(usize, Vec), String> { let f = self.files(sort_order)?; - let l = limit.unwrap_or(f.len()); + let t = f.len(); + let l = limit.unwrap_or(t); let mut b = Vec::with_capacity(l); for file in f.into_iter().skip(start.unwrap_or_default()).take(l) { if file @@ -163,7 +164,7 @@ impl Storage { .into(), }) } - Ok(b) + Ok((t, b)) } // Helpers diff --git a/templates/index.html.tera b/templates/index.html.tera index ab4b54c..cff4e5f 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -27,4 +27,5 @@ {% endif %} {% if next %}Next{% endif %} {% if back %}Back{% endif %} +{{ pagination_totals }} {% endblock content %} \ No newline at end of file diff --git a/templates/layout/default.html.tera b/templates/layout/default.html.tera index 3caa441..d830159 100644 --- a/templates/layout/default.html.tera +++ b/templates/layout/default.html.tera @@ -107,12 +107,12 @@ padding: 24px; } - /* description */ + /* item row description */ main > div > p { margin: 8px 0; } - /* meta, controls */ + /* item row meta, controls */ main > div > div { border-top: 1px #4f536a solid; margin-top: 16px; @@ -148,6 +148,13 @@ float: right; vertical-align: middle; } + + /* pagination info */ + main > span { + display: inline-block; + float: right; + padding: 8px; + }