feat: enhance review handling by adding actor URL support across multiple components
All checks were successful
CI / Check / Test (push) Successful in 1h3m53s
All checks were successful
CI / Check / Test (push) Successful in 1h3m53s
This commit is contained in:
@@ -322,10 +322,11 @@ impl DiaryRepository for PostgresDiaryRepository {
|
|||||||
to_char(r.watched_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS watched_at,
|
to_char(r.watched_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS watched_at,
|
||||||
to_char(r.created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS created_at,
|
to_char(r.created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') AS created_at,
|
||||||
r.remote_actor_url,
|
r.remote_actor_url,
|
||||||
COALESCE(u.email, r.remote_actor_url) AS user_email
|
COALESCE(u.email, a.handle, r.remote_actor_url) AS user_email
|
||||||
FROM reviews r
|
FROM reviews r
|
||||||
INNER JOIN movies m ON m.id = r.movie_id
|
INNER JOIN movies m ON m.id = r.movie_id
|
||||||
LEFT JOIN users u ON u.id = r.user_id
|
LEFT JOIN users u ON u.id = r.user_id
|
||||||
|
LEFT JOIN ap_remote_actors a ON a.url = r.remote_actor_url
|
||||||
WHERE {}
|
WHERE {}
|
||||||
ORDER BY {}
|
ORDER BY {}
|
||||||
LIMIT {} OFFSET {}",
|
LIMIT {} OFFSET {}",
|
||||||
|
|||||||
@@ -291,10 +291,11 @@ impl DiaryRepository for SqliteDiaryRepository {
|
|||||||
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
|
"SELECT m.id, m.external_metadata_id, m.title, m.release_year, m.director, m.poster_path,
|
||||||
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment,
|
r.id AS review_id, r.movie_id, r.user_id, r.rating, r.comment,
|
||||||
r.watched_at, r.created_at, r.remote_actor_url,
|
r.watched_at, r.created_at, r.remote_actor_url,
|
||||||
COALESCE(u.email, r.remote_actor_url) AS user_email
|
COALESCE(u.email, a.handle, r.remote_actor_url) AS user_email
|
||||||
FROM reviews r
|
FROM reviews r
|
||||||
INNER JOIN movies m ON m.id = r.movie_id
|
INNER JOIN movies m ON m.id = r.movie_id
|
||||||
LEFT JOIN users u ON u.id = r.user_id
|
LEFT JOIN users u ON u.id = r.user_id
|
||||||
|
LEFT JOIN ap_remote_actors a ON a.url = r.remote_actor_url
|
||||||
WHERE {}
|
WHERE {}
|
||||||
ORDER BY {}
|
ORDER BY {}
|
||||||
LIMIT ? OFFSET ?",
|
LIMIT ? OFFSET ?",
|
||||||
|
|||||||
@@ -55,9 +55,10 @@ pub struct FeedEntryDto {
|
|||||||
pub movie: MovieDto,
|
pub movie: MovieDto,
|
||||||
pub review: ReviewDto,
|
pub review: ReviewDto,
|
||||||
pub user_id: Uuid,
|
pub user_id: Uuid,
|
||||||
pub user_email: String,
|
|
||||||
pub user_display_name: String,
|
pub user_display_name: String,
|
||||||
pub is_federated: bool,
|
pub is_federated: bool,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub actor_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
||||||
|
|||||||
@@ -4,12 +4,17 @@ use domain::models::FeedEntry;
|
|||||||
use super::movies::{movie_to_dto, review_to_dto};
|
use super::movies::{movie_to_dto, review_to_dto};
|
||||||
|
|
||||||
pub fn feed_entry_to_dto(e: &FeedEntry) -> FeedEntryDto {
|
pub fn feed_entry_to_dto(e: &FeedEntry) -> FeedEntryDto {
|
||||||
|
use domain::models::ReviewSource;
|
||||||
|
let actor_url = match e.review().source() {
|
||||||
|
ReviewSource::Remote { actor_url } => Some(actor_url.clone()),
|
||||||
|
ReviewSource::Local => None,
|
||||||
|
};
|
||||||
FeedEntryDto {
|
FeedEntryDto {
|
||||||
movie: movie_to_dto(e.movie()),
|
movie: movie_to_dto(e.movie()),
|
||||||
review: review_to_dto(e.review()),
|
review: review_to_dto(e.review()),
|
||||||
user_id: e.review().user_id().value(),
|
user_id: e.review().user_id().value(),
|
||||||
user_email: e.user_email().to_string(),
|
|
||||||
user_display_name: e.user_display_name().to_string(),
|
user_display_name: e.user_display_name().to_string(),
|
||||||
is_federated: e.review().is_remote(),
|
is_federated: e.review().is_remote(),
|
||||||
|
actor_url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ type ReviewCardProps = {
|
|||||||
userName?: string
|
userName?: string
|
||||||
userId?: string
|
userId?: string
|
||||||
isFederated?: boolean
|
isFederated?: boolean
|
||||||
|
actorUrl?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ReviewCard({ movie, review, userName, userId, isFederated }: ReviewCardProps) {
|
export function ReviewCard({ movie, review, userName, userId, isFederated, actorUrl }: ReviewCardProps) {
|
||||||
return (
|
return (
|
||||||
<Card size="sm">
|
<Card size="sm">
|
||||||
<CardContent className="flex gap-3">
|
<CardContent className="flex gap-3">
|
||||||
@@ -28,6 +29,10 @@ export function ReviewCard({ movie, review, userName, userId, isFederated }: Rev
|
|||||||
<Link to="/users/$id" params={{ id: userId }} className="relative z-10 font-semibold text-primary">
|
<Link to="/users/$id" params={{ id: userId }} className="relative z-10 font-semibold text-primary">
|
||||||
{userName}
|
{userName}
|
||||||
</Link>
|
</Link>
|
||||||
|
) : actorUrl ? (
|
||||||
|
<a href={actorUrl} target="_blank" rel="noopener noreferrer" className="relative z-10 font-semibold text-primary">
|
||||||
|
{userName}
|
||||||
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<span>{userName}</span>
|
<span>{userName}</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ export const feedEntryDtoSchema = z.object({
|
|||||||
movie: movieDtoSchema,
|
movie: movieDtoSchema,
|
||||||
review: reviewDtoSchema,
|
review: reviewDtoSchema,
|
||||||
user_id: z.string().uuid(),
|
user_id: z.string().uuid(),
|
||||||
user_email: z.string(),
|
|
||||||
user_display_name: z.string(),
|
user_display_name: z.string(),
|
||||||
is_federated: z.boolean(),
|
is_federated: z.boolean(),
|
||||||
|
actor_url: z.string().optional(),
|
||||||
})
|
})
|
||||||
export type FeedEntryDto = z.infer<typeof feedEntryDtoSchema>
|
export type FeedEntryDto = z.infer<typeof feedEntryDtoSchema>
|
||||||
|
|
||||||
|
|||||||
@@ -115,8 +115,9 @@ function FeedTab() {
|
|||||||
movie={entry.movie}
|
movie={entry.movie}
|
||||||
review={entry.review}
|
review={entry.review}
|
||||||
userName={entry.user_display_name}
|
userName={entry.user_display_name}
|
||||||
userId={entry.user_id}
|
userId={entry.is_federated ? undefined : entry.user_id}
|
||||||
isFederated={entry.is_federated}
|
isFederated={entry.is_federated}
|
||||||
|
actorUrl={entry.actor_url}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
return entry.user_id === auth?.user_id ? (
|
return entry.user_id === auth?.user_id ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user