feat: Implement pagination for user media retrieval and update related structures

This commit is contained in:
2025-11-15 18:06:09 +01:00
parent dd10211c63
commit ccb9f09d4a
8 changed files with 144 additions and 47 deletions

View File

@@ -17,7 +17,7 @@ use crate::{
error::ApiError,
extractors::query_options::ApiListMediaOptions,
middleware::auth::{OptionalUserId, UserId},
schema::{MediaDetailsResponse, MediaResponse},
schema::{MediaDetailsResponse, MediaResponse, PaginatedResponse, map_paginated_response},
state::AppState,
};
@@ -138,12 +138,12 @@ async fn list_user_media(
State(state): State<AppState>,
UserId(user_id): UserId,
ApiListMediaOptions(options): ApiListMediaOptions,
) -> Result<Json<Vec<MediaResponse>>, ApiError> {
let media_list = state
) -> Result<Json<PaginatedResponse<MediaResponse>>, ApiError> {
let core_paginated_result = state
.media_service
.list_user_media(user_id, options)
.await?;
let response = media_list.into_iter().map(MediaResponse::from).collect();
Ok(Json(response))
let api_response = map_paginated_response(core_paginated_result);
Ok(Json(api_response))
}

View File

@@ -2,6 +2,7 @@ use libertas_core::models::{
Album, AlbumPermission, FaceRegion, Media, MediaBundle, MediaMetadata, Person,
PersonPermission, Tag,
};
use libertas_core::schema::PaginatedResponse as CorePaginatedResponse;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@@ -246,3 +247,29 @@ pub struct PublicAlbumBundleResponse {
pub struct MergePersonRequest {
pub source_person_id: Uuid,
}
#[derive(Serialize)]
pub struct PaginatedResponse<T> {
pub data: Vec<T>,
pub page: u32,
pub limit: u32,
pub total_items: i64,
pub total_pages: u32,
pub has_next_page: bool,
pub has_prev_page: bool,
}
pub fn map_paginated_response<T, U>(core_response: CorePaginatedResponse<T>) -> PaginatedResponse<U>
where
U: From<T>,
{
PaginatedResponse {
data: core_response.data.into_iter().map(U::from).collect(),
page: core_response.page,
limit: core_response.limit,
total_items: core_response.total_items,
total_pages: core_response.total_pages,
has_next_page: core_response.has_next_page,
has_prev_page: core_response.has_prev_page,
}
}

View File

@@ -12,7 +12,7 @@ use libertas_core::{
media_utils::{extract_exif_data_from_bytes, get_storage_path_and_date},
models::{Media, MediaBundle},
repositories::{MediaMetadataRepository, MediaRepository, UserRepository},
schema::{ListMediaOptions, UploadMediaData},
schema::{ListMediaOptions, PaginatedResponse, UploadMediaData},
services::{AuthorizationService, MediaService},
};
use serde_json::json;
@@ -109,8 +109,14 @@ impl MediaService for MediaServiceImpl {
&self,
user_id: Uuid,
options: ListMediaOptions,
) -> CoreResult<Vec<Media>> {
self.repo.list_by_user(user_id, &options).await
) -> CoreResult<PaginatedResponse<Media>> {
let (data, total_items) = self.repo.list_by_user(user_id, &options).await?;
let pagination = options.pagination.unwrap();
let response = PaginatedResponse::new(data, pagination.page, pagination.limit, total_items);
Ok(response)
}
async fn get_media_filepath(&self, id: Uuid, user_id: Option<Uuid>) -> CoreResult<String> {