From 1b5d625b9cb48878ddea587651af72d78b454ed1 Mon Sep 17 00:00:00 2001 From: jmanczak Date: Thu, 9 Apr 2026 00:53:39 +0200 Subject: [PATCH 1/2] paginate the quotes, actually --- src/quotes/mod.rs | 12 ++++++++++ src/web/pages/quotes.rs | 50 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/quotes/mod.rs b/src/quotes/mod.rs index 9272f90..14bfbe5 100644 --- a/src/quotes/mod.rs +++ b/src/quotes/mod.rs @@ -131,6 +131,18 @@ impl Quote { ids.iter().map(|id| Self::get_by_id(conn, *id)).collect() } + pub fn get_chronological_offset( + conn: &Connection, + offset: i64, + limit: i64, + ) -> Result, QuoteError> { + let ids = conn + .prepare("SELECT id FROM quotes ORDER BY id DESC LIMIT ?1 OFFSET ?2")? + .query_map((limit, offset), |r| r.get(0))? + .collect::, _>>()?; + + ids.iter().map(|id| Self::get_by_id(conn, *id)).collect() + } pub fn create( conn: &Connection, lines: Vec<(String, Name)>, diff --git a/src/web/pages/quotes.rs b/src/web/pages/quotes.rs index 46d5c47..3c6858c 100644 --- a/src/web/pages/quotes.rs +++ b/src/web/pages/quotes.rs @@ -1,8 +1,9 @@ use axum::{ - extract::Request, + extract::{Query, Request}, response::{IntoResponse, Response}, }; use maud::{PreEscaped, html}; +use serde::Deserialize; use crate::{ database, @@ -21,10 +22,25 @@ use crate::{ pub mod add; -pub async fn page(req: Request) -> Result { +#[derive(Deserialize)] +pub struct PageQuery { + page: Option, +} + +pub async fn page( + Query(query): Query, + req: Request, +) -> Result { let u = User::authenticate(req.headers())?.required()?; let conn = database::conn()?; - let quotes = Quote::get_chronological_cursorscroll(&conn, None, 20)?; + + let page = query.page.unwrap_or(1).max(1); + let per_page = 10; + let offset = (page - 1) * per_page; + + let quotes = Quote::get_chronological_offset(&conn, offset, per_page)?; + let total_quotes = Quote::total_count(&conn)?; + let total_pages = (total_quotes as f64 / per_page as f64).ceil() as i64; Ok(base( "Quotes | Mnemosyne", @@ -50,9 +66,31 @@ pub async fn page(req: Request) -> Result { "Chronological" } } - div class="flex flex-col gap-4" { - @for q in quotes { - (quote(&q)) + div class="flex flex-col gap-4 mb-8" { + @for q in "es { + (quote(q)) + } + + div class="flex justify-between items-center mt-4 text-neutral-400" { + @if page > 1 { + a href=(format!("/quotes?page={}", (page - 1).min(1))) class="px-4 py-2 border border-neutral-200/25 hover:border-neutral-200/45 bg-neutral-200/5 hover:bg-neutral-200/15 rounded" { + "Previous" + } + } @else { + div {} + } + + span { + "Page " (page) " of " (total_pages) + } + + @if page < total_pages { + a href=(format!("/quotes?page={}", page + 1)) class="px-4 py-2 border border-neutral-200/25 hover:border-neutral-200/45 bg-neutral-200/5 hover:bg-neutral-200/15 rounded" { + "Next" + } + } @else { + div {} + } } } } From 3a811db71560a2ebbf711e0afb06100f2cbc6c4a Mon Sep 17 00:00:00 2001 From: jmanczak Date: Thu, 9 Apr 2026 00:55:38 +0200 Subject: [PATCH 2/2] don't throw on permission check lol --- src/users/permissions.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/users/permissions.rs b/src/users/permissions.rs index 991121a..0f9fc1e 100644 --- a/src/users/permissions.rs +++ b/src/users/permissions.rs @@ -31,6 +31,7 @@ impl User { return Ok(true); } - todo!("Do the permission checking here once permissions are modeled in the DB") + Ok(false) + // todo!("Do the permission checking here once permissions are modeled in the DB") } }