Skip to content

Commit

Permalink
feat(be): Added recently like call
Browse files Browse the repository at this point in the history
  • Loading branch information
MendyBerger committed May 22, 2024
1 parent 0989420 commit fd4a60b
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 3 deletions.
22 changes: 22 additions & 0 deletions backend/api/sqlx-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -15409,6 +15409,28 @@
},
"query": "\n with cte as (\n select (array_agg(course.id))[1]\n from course_data \"cd\"\n inner join course on (draft_id = cd.id or (live_id = cd.id and cd.last_synced_at is not null and published_at is not null))\n left join course_admin_data \"admin\" on admin.course_id = course.id\n left join course_data_resource \"resource\" on cd.id = resource.course_data_id\n where (author_id = $1 or $1 is null)\n and (cd.draft_or_live = $2 or $2 is null)\n and (blocked = $5 or $5 is null)\n and (cd.privacy_level = any($3) or $3 = array[]::smallint[])\n and (resource.resource_type_id = any($4) or $4 = array[]::uuid[])\n group by coalesce(updated_at, created_at)\n )\n select count(*) as \"count!\" from unnest(array(select cte.array_agg from cte)) with ordinality t(id, ord)\n"
},
"e9c111c270b73f07f798be13ab0bd94518ee730997e60f7781cc81601aa5af72": {
"describe": {
"columns": [
{
"name": "jig_id",
"ordinal": 0,
"type_info": "Uuid"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Uuid",
"Int8",
"Int8"
]
}
},
"query": "\n select jig_id\n from jig_like\n where user_id = $1\n order by created_at desc\n offset $2\n limit $3\n \n "
},
"e9f633a72fa4fad7e52f4dd94aa9c6d1c2fd6b3f256fd21248297f254a5fbb79": {
"describe": {
"columns": [],
Expand Down
26 changes: 26 additions & 0 deletions backend/api/src/db/jig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,32 @@ select exists (
Ok(exists)
}

pub async fn list_liked(
db: &PgPool,
user_id: UserId,
page: u32,
page_limit: u32,
) -> sqlx::Result<Vec<JigId>> {
let rows = sqlx::query!(
r#"
select jig_id
from jig_like
where user_id = $1
order by created_at desc
offset $2
limit $3
"#,
user_id.0,
(page * page_limit) as i32,
page_limit as i32,
)
.fetch_all(db)
.await?;

Ok(rows.into_iter().map(|row| JigId(row.jig_id)).collect())
}

#[instrument(skip(db))]
pub async fn get_jig_playlists(
db: &sqlx::Pool<sqlx::Postgres>,
Expand Down
33 changes: 31 additions & 2 deletions backend/api/src/http/endpoints/jig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use actix_web::{
};
use futures::try_join;
use ji_core::settings::RuntimeSettings;
use shared::domain::{jig::JigTrendingResponse, user::UserScope};
use shared::domain::{
jig::{JigTrendingResponse, ListLikedResponse},
user::UserScope,
};
use shared::{
api::{endpoints::jig, ApiEndpoint, PathParts},
domain::{
Expand Down Expand Up @@ -431,6 +434,26 @@ async fn unlike(
Ok(HttpResponse::NoContent().finish())
}

/// Get users liked jigs
async fn list_liked(
db: Data<PgPool>,
claims: TokenUser,
query: Option<Query<<jig::Browse as ApiEndpoint>::Req>>,
) -> Result<Json<<jig::ListLiked as ApiEndpoint>::Res>, error::Server> {
let user_id = claims.user_id();
let query = query.map_or_else(Default::default, Query::into_inner);

let page_limit = page_limit(query.page_limit).await?;

let ids = db::jig::list_liked(&*db, user_id, query.page.unwrap_or(0), page_limit).await?;

let jigs = db::jig::get_by_ids(&db, &ids, DraftOrLive::Live, Some(user_id))
.await
.into_anyhow()?;

Ok(Json(ListLikedResponse { jigs }))
}

/// Add a play to a jig
async fn play(db: Data<PgPool>, path: web::Path<JigId>) -> Result<HttpResponse, error::NotFound> {
db::jig::jig_play(&*db, path.into_inner()).await?;
Expand Down Expand Up @@ -462,7 +485,9 @@ pub(crate) async fn page_limit(page_limit: Option<u32>) -> anyhow::Result<u32> {
if let Some(limit) = page_limit {
match limit > 0 && limit <= MAX_PAGE_LIMIT {
true => Ok(limit),
false => Err(anyhow::anyhow!("Page limit should be within 1-100")),
false => Err(anyhow::anyhow!(
"Page limit should be within 1-{MAX_PAGE_LIMIT}"
)),
}
} else {
Ok(DEFAULT_PAGE_LIMIT)
Expand Down Expand Up @@ -571,6 +596,10 @@ pub fn configure(cfg: &mut ServiceConfig) {
<jig::Trending as ApiEndpoint>::Path::PATH,
jig::Trending::METHOD.route().to(trending),
)
.route(
<jig::ListLiked as ApiEndpoint>::Path::PATH,
jig::ListLiked::METHOD.route().to(list_liked),
)
.route(
<jig::UpdateDraftData as ApiEndpoint>::Path::PATH,
jig::UpdateDraftData::METHOD.route().to(update_draft),
Expand Down
13 changes: 12 additions & 1 deletion shared/rust/src/api/endpoints/jig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use crate::{
JigId, JigLikePath, JigLikedPath, JigLikedResponse, JigPlayPath, JigPublishPath,
JigResponse, JigSearchPath, JigSearchQuery, JigSearchResponse, JigTransferAdminPath,
JigTrendingPath, JigTrendingResponse, JigUnlikePath, JigUpdateAdminDataRequest,
JigUpdateDraftDataPath, JigUpdateDraftDataRequest,
JigUpdateDraftDataPath, JigUpdateDraftDataRequest, ListLikedPath, ListLikedRequest,
ListLikedResponse,
},
CreateResponse,
},
Expand Down Expand Up @@ -153,6 +154,16 @@ impl ApiEndpoint for Trending {
const METHOD: Method = Method::Get;
}

/// List user's liked JIGs.
pub struct ListLiked;
impl ApiEndpoint for ListLiked {
type Req = ListLikedRequest;
type Res = ListLikedResponse;
type Path = ListLikedPath;
type Err = EmptyError;
const METHOD: Method = Method::Get;
}

/// Clone a JIG. This clones both the draft and live.
///
/// # Authorization
Expand Down
24 changes: 24 additions & 0 deletions shared/rust/src/domain/jig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,30 @@ pub struct JigTrendingResponse {
pub jigs: Vec<JigResponse>,
}

make_path_parts!(ListLikedPath => "/v1/jig/likes");

/// Response for request for list of liked jigs.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListLikedRequest {
/// The page number of the jigs to get.
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,

/// The hits per page to be returned
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub page_limit: Option<u32>,
}
/// Response for request for list of liked jigs.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListLikedResponse {
/// the jigs returned.
pub jigs: Vec<JigResponse>,
}

/// Response for successfully finding the draft of a jig.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
Expand Down

0 comments on commit fd4a60b

Please sign in to comment.