From e43e6c3d0a26a7a28067022c2154c78a3b0cfaf1 Mon Sep 17 00:00:00 2001 From: silverpill Date: Wed, 1 Dec 2021 21:55:38 +0000 Subject: [PATCH] Paginate home timeline --- src/mastodon_api/timelines/mod.rs | 1 + src/mastodon_api/timelines/types.rs | 12 ++++++++++++ src/mastodon_api/timelines/views.rs | 11 +++++++++-- src/models/posts/queries.rs | 8 ++++++-- 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/mastodon_api/timelines/types.rs diff --git a/src/mastodon_api/timelines/mod.rs b/src/mastodon_api/timelines/mod.rs index 38b4403..718ba5f 100644 --- a/src/mastodon_api/timelines/mod.rs +++ b/src/mastodon_api/timelines/mod.rs @@ -1 +1,2 @@ +mod types; pub mod views; diff --git a/src/mastodon_api/timelines/types.rs b/src/mastodon_api/timelines/types.rs new file mode 100644 index 0000000..db149e9 --- /dev/null +++ b/src/mastodon_api/timelines/types.rs @@ -0,0 +1,12 @@ +use serde::Deserialize; +use uuid::Uuid; + +fn default_page_size() -> i64 { 20 } + +#[derive(Deserialize)] +pub struct TimelineQueryParams { + pub max_id: Option, + + #[serde(default = "default_page_size")] + pub limit: i64, +} diff --git a/src/mastodon_api/timelines/views.rs b/src/mastodon_api/timelines/views.rs index cfd3b6d..0d7b601 100644 --- a/src/mastodon_api/timelines/views.rs +++ b/src/mastodon_api/timelines/views.rs @@ -1,3 +1,4 @@ +/// https://docs.joinmastodon.org/methods/timelines/ use actix_web::{get, web, HttpResponse, Scope}; use actix_web_httpauth::extractors::bearer::BearerAuth; @@ -11,17 +12,23 @@ use crate::models::posts::helpers::{ get_reposted_posts, }; use crate::models::posts::queries::get_home_timeline; +use super::types::TimelineQueryParams; -/// https://docs.joinmastodon.org/methods/timelines/ #[get("/home")] async fn home_timeline( auth: BearerAuth, config: web::Data, db_pool: web::Data, + query_params: web::Query, ) -> Result { let db_client = &**get_database_client(&db_pool).await?; let current_user = get_current_user(db_client, auth.token()).await?; - let mut posts = get_home_timeline(db_client, ¤t_user.id).await?; + let mut posts = get_home_timeline( + db_client, + ¤t_user.id, + query_params.limit, + query_params.max_id, + ).await?; get_reposted_posts(db_client, posts.iter_mut().collect()).await?; get_actions_for_posts( db_client, diff --git a/src/models/posts/queries.rs b/src/models/posts/queries.rs index c267c3a..2e4aed7 100644 --- a/src/models/posts/queries.rs +++ b/src/models/posts/queries.rs @@ -178,6 +178,8 @@ pub const RELATED_MENTIONS: &str = pub async fn get_home_timeline( db_client: &impl GenericClient, current_user_id: &Uuid, + limit: i64, + max_post_id: Option, ) -> Result, DatabaseError> { // Select posts from follows + own posts. // Exclude direct messages where current user is not mentioned. @@ -204,7 +206,9 @@ pub async fn get_home_timeline( WHERE post_id = post.id AND profile_id = $1 ) ) - ORDER BY post.created_at DESC + AND ($3::uuid IS NULL OR post.id < $3) + ORDER BY post.id DESC + LIMIT $2 ", related_attachments=RELATED_ATTACHMENTS, related_mentions=RELATED_MENTIONS, @@ -212,7 +216,7 @@ pub async fn get_home_timeline( ); let rows = db_client.query( statement.as_str(), - &[¤t_user_id], + &[¤t_user_id, &limit, &max_post_id], ).await?; let posts: Vec = rows.iter() .map(Post::try_from)