Enable pagination on profile timeline

This commit is contained in:
silverpill 2021-12-14 16:16:30 +00:00
parent fc153a3156
commit 42624ab9a5
5 changed files with 54 additions and 9 deletions

View file

@ -5,6 +5,35 @@ info:
version: 1.0.0
paths:
/api/v1/accounts/{account_id}/statuses:
get:
summary: Statuses posted to the given account.
parameters:
- $ref: '#/components/parameters/account_id'
- name: max_id
in: query
description: Return results older than this ID.
required: false
schema:
type: string
format: uuid
- name: limit
in: query
description: Maximum number of results to return.
required: false
schema:
type: integer
default: 20
responses:
200:
description: Successful operation
content:
application/json:
schema:
description: Post list
type: array
items:
$ref: '#/components/schemas/Status'
/api/v1/statuses/{status_id}:
delete:
summary: Delete post
@ -132,6 +161,14 @@ paths:
components:
parameters:
account_id:
name: account_id
in: path
description: Profile ID
required: true
schema:
type: string
format: uuid
status_id:
name: status_id
in: path

View file

@ -14,12 +14,13 @@ use crate::config::Config;
use crate::database::{Pool, get_database_client};
use crate::errors::{HttpError, ValidationError};
use crate::ethereum::gate::is_allowed_user;
use crate::mastodon_api::statuses::types::Status;
use crate::mastodon_api::oauth::auth::get_current_user;
use crate::models::posts::helpers::{
get_actions_for_posts,
get_reposted_posts,
};
use crate::mastodon_api::statuses::types::Status;
use crate::mastodon_api::timelines::types::TimelineQueryParams;
use crate::models::posts::queries::get_posts_by_author;
use crate::models::profiles::queries::{
get_followers,
@ -257,6 +258,7 @@ async fn get_account_statuses(
config: web::Data<Config>,
db_pool: web::Data<Pool>,
web::Path(account_id): web::Path<Uuid>,
query_params: web::Query<TimelineQueryParams>,
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
let maybe_current_user = match auth {
@ -268,6 +270,8 @@ async fn get_account_statuses(
&account_id,
false,
false,
query_params.max_id,
query_params.limit,
).await?;
get_reposted_posts(db_client, posts.iter_mut().collect()).await?;
if let Some(user) = maybe_current_user {

View file

@ -1,2 +1,2 @@
mod types;
pub mod types;
pub mod views;

View file

@ -26,8 +26,8 @@ async fn home_timeline(
let mut posts = get_home_timeline(
db_client,
&current_user.id,
query_params.limit,
query_params.max_id,
query_params.limit,
).await?;
get_reposted_posts(db_client, posts.iter_mut().collect()).await?;
get_actions_for_posts(

View file

@ -208,8 +208,8 @@ pub const RELATED_TAGS: &str =
pub async fn get_home_timeline(
db_client: &impl GenericClient,
current_user_id: &Uuid,
limit: i64,
max_post_id: Option<Uuid>,
limit: i64,
) -> Result<Vec<Post>, DatabaseError> {
// Select posts from follows + own posts.
// Exclude direct messages where current user is not mentioned.
@ -237,9 +237,9 @@ pub async fn get_home_timeline(
WHERE post_id = post.id AND profile_id = $1
)
)
AND ($3::uuid IS NULL OR post.id < $3)
AND ($2::uuid IS NULL OR post.id < $2)
ORDER BY post.id DESC
LIMIT $2
LIMIT $3
",
related_attachments=RELATED_ATTACHMENTS,
related_mentions=RELATED_MENTIONS,
@ -248,7 +248,7 @@ pub async fn get_home_timeline(
);
let rows = db_client.query(
statement.as_str(),
&[&current_user_id, &limit, &max_post_id],
&[&current_user_id, &max_post_id, &limit],
).await?;
let posts: Vec<Post> = rows.iter()
.map(Post::try_from)
@ -290,8 +290,11 @@ pub async fn get_posts_by_author(
account_id: &Uuid,
include_replies: bool,
include_private: bool,
max_post_id: Option<Uuid>,
limit: i64,
) -> Result<Vec<Post>, DatabaseError> {
let mut condition = "post.author_id = $1".to_string();
let mut condition = "post.author_id = $1
AND ($2::uuid IS NULL OR post.id < $2)".to_string();
if !include_replies {
condition.push_str(" AND post.in_reply_to_id IS NULL");
};
@ -313,6 +316,7 @@ pub async fn get_posts_by_author(
JOIN actor_profile ON post.author_id = actor_profile.id
WHERE {condition}
ORDER BY post.created_at DESC
LIMIT $3
",
related_attachments=RELATED_ATTACHMENTS,
related_mentions=RELATED_MENTIONS,
@ -321,7 +325,7 @@ pub async fn get_posts_by_author(
);
let rows = db_client.query(
statement.as_str(),
&[&account_id],
&[&account_id, &max_post_id, &limit],
).await?;
let posts: Vec<Post> = rows.iter()
.map(Post::try_from)