feat: add author display name to thought schemas and update related components
This commit is contained in:
@@ -38,6 +38,7 @@ pub async fn search_thoughts(
|
|||||||
// We must join with the user table to get the author's username
|
// We must join with the user table to get the author's username
|
||||||
let thoughts_with_authors = thought::Entity::find()
|
let thoughts_with_authors = thought::Entity::find()
|
||||||
.column_as(user::Column::Username, "author_username")
|
.column_as(user::Column::Username, "author_username")
|
||||||
|
.column_as(user::Column::DisplayName, "author_display_name")
|
||||||
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
||||||
.filter(Expr::cust_with_values(
|
.filter(Expr::cust_with_values(
|
||||||
"thought.search_document @@ websearch_to_tsquery('english', $1)",
|
"thought.search_document @@ websearch_to_tsquery('english', $1)",
|
||||||
|
@@ -102,6 +102,7 @@ pub async fn get_thoughts_by_user(
|
|||||||
.column(thought::Column::CreatedAt)
|
.column(thought::Column::CreatedAt)
|
||||||
.column(thought::Column::AuthorId)
|
.column(thought::Column::AuthorId)
|
||||||
.column(thought::Column::Visibility)
|
.column(thought::Column::Visibility)
|
||||||
|
.column_as(user::Column::DisplayName, "author_display_name")
|
||||||
.column_as(user::Column::Username, "author_username")
|
.column_as(user::Column::Username, "author_username")
|
||||||
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
||||||
.filter(apply_visibility_filter(user_id, viewer_id, &friend_ids))
|
.filter(apply_visibility_filter(user_id, viewer_id, &friend_ids))
|
||||||
@@ -137,6 +138,7 @@ pub async fn get_feed_for_user(
|
|||||||
.column(thought::Column::Visibility)
|
.column(thought::Column::Visibility)
|
||||||
.column(thought::Column::AuthorId)
|
.column(thought::Column::AuthorId)
|
||||||
.column_as(user::Column::Username, "author_username")
|
.column_as(user::Column::Username, "author_username")
|
||||||
|
.column_as(user::Column::DisplayName, "author_display_name")
|
||||||
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
||||||
.filter(
|
.filter(
|
||||||
Condition::any().add(following_ids.iter().fold(
|
Condition::any().add(following_ids.iter().fold(
|
||||||
@@ -173,6 +175,7 @@ pub async fn get_thoughts_by_tag_name(
|
|||||||
.column(thought::Column::AuthorId)
|
.column(thought::Column::AuthorId)
|
||||||
.column(thought::Column::Visibility)
|
.column(thought::Column::Visibility)
|
||||||
.column_as(user::Column::Username, "author_username")
|
.column_as(user::Column::Username, "author_username")
|
||||||
|
.column_as(user::Column::DisplayName, "author_display_name")
|
||||||
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
.join(JoinType::InnerJoin, thought::Relation::User.def())
|
||||||
.join(JoinType::InnerJoin, thought::Relation::ThoughtTag.def())
|
.join(JoinType::InnerJoin, thought::Relation::ThoughtTag.def())
|
||||||
.join(JoinType::InnerJoin, thought_tag::Relation::Tag.def())
|
.join(JoinType::InnerJoin, thought_tag::Relation::Tag.def())
|
||||||
@@ -288,6 +291,7 @@ pub async fn get_thought_with_replies(
|
|||||||
ThoughtThreadSchema {
|
ThoughtThreadSchema {
|
||||||
id: thought_schema.id,
|
id: thought_schema.id,
|
||||||
author_username: thought_schema.author_username.clone(),
|
author_username: thought_schema.author_username.clone(),
|
||||||
|
author_display_name: thought_schema.author_display_name.clone(),
|
||||||
content: thought_schema.content.clone(),
|
content: thought_schema.content.clone(),
|
||||||
visibility: thought_schema.visibility.clone(),
|
visibility: thought_schema.visibility.clone(),
|
||||||
reply_to_id: thought_schema.reply_to_id,
|
reply_to_id: thought_schema.reply_to_id,
|
||||||
|
@@ -14,6 +14,7 @@ pub struct ThoughtSchema {
|
|||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
#[schema(example = "frutiger")]
|
#[schema(example = "frutiger")]
|
||||||
pub author_username: String,
|
pub author_username: String,
|
||||||
|
pub author_display_name: Option<String>,
|
||||||
#[schema(example = "This is my first thought! #welcome")]
|
#[schema(example = "This is my first thought! #welcome")]
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub visibility: Visibility,
|
pub visibility: Visibility,
|
||||||
@@ -23,15 +24,10 @@ pub struct ThoughtSchema {
|
|||||||
|
|
||||||
impl ThoughtSchema {
|
impl ThoughtSchema {
|
||||||
pub fn from_models(thought: &thought::Model, author: &user::Model) -> Self {
|
pub fn from_models(thought: &thought::Model, author: &user::Model) -> Self {
|
||||||
let author_username = if let Some(display_name) = author.display_name.clone() {
|
|
||||||
display_name
|
|
||||||
} else {
|
|
||||||
author.username.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
id: thought.id,
|
id: thought.id,
|
||||||
author_username,
|
author_username: author.username.clone(),
|
||||||
|
author_display_name: author.display_name.clone(),
|
||||||
content: thought.content.clone(),
|
content: thought.content.clone(),
|
||||||
visibility: thought.visibility.clone(),
|
visibility: thought.visibility.clone(),
|
||||||
reply_to_id: thought.reply_to_id,
|
reply_to_id: thought.reply_to_id,
|
||||||
@@ -60,6 +56,7 @@ pub struct ThoughtWithAuthor {
|
|||||||
pub visibility: Visibility,
|
pub visibility: Visibility,
|
||||||
pub author_id: Uuid,
|
pub author_id: Uuid,
|
||||||
pub author_username: String,
|
pub author_username: String,
|
||||||
|
pub author_display_name: Option<String>,
|
||||||
pub reply_to_id: Option<Uuid>,
|
pub reply_to_id: Option<Uuid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +65,7 @@ impl From<ThoughtWithAuthor> for ThoughtSchema {
|
|||||||
Self {
|
Self {
|
||||||
id: model.id,
|
id: model.id,
|
||||||
author_username: model.author_username,
|
author_username: model.author_username,
|
||||||
|
author_display_name: model.author_display_name,
|
||||||
content: model.content,
|
content: model.content,
|
||||||
created_at: model.created_at.into(),
|
created_at: model.created_at.into(),
|
||||||
reply_to_id: model.reply_to_id,
|
reply_to_id: model.reply_to_id,
|
||||||
@@ -81,6 +79,7 @@ impl From<ThoughtWithAuthor> for ThoughtSchema {
|
|||||||
pub struct ThoughtThreadSchema {
|
pub struct ThoughtThreadSchema {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub author_username: String,
|
pub author_username: String,
|
||||||
|
pub author_display_name: Option<String>,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub visibility: Visibility,
|
pub visibility: Visibility,
|
||||||
pub reply_to_id: Option<Uuid>,
|
pub reply_to_id: Option<Uuid>,
|
||||||
|
@@ -44,6 +44,7 @@ interface ThoughtCardProps {
|
|||||||
thought: Thought;
|
thought: Thought;
|
||||||
author: {
|
author: {
|
||||||
username: string;
|
username: string;
|
||||||
|
displayName?: string | null;
|
||||||
avatarUrl?: string | null;
|
avatarUrl?: string | null;
|
||||||
};
|
};
|
||||||
currentUser: Me | null;
|
currentUser: Me | null;
|
||||||
@@ -112,9 +113,14 @@ export function ThoughtCard({
|
|||||||
href={`/users/${author.username}`}
|
href={`/users/${author.username}`}
|
||||||
className="flex items-center gap-4 text-shadow-md"
|
className="flex items-center gap-4 text-shadow-md"
|
||||||
>
|
>
|
||||||
<UserAvatar src={author.avatarUrl} alt={author.username} />
|
<UserAvatar
|
||||||
|
src={author.avatarUrl}
|
||||||
|
alt={author.displayName || author.username}
|
||||||
|
/>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="font-bold">{author.username}</span>
|
<span className="font-bold">
|
||||||
|
{author.displayName || author.username}
|
||||||
|
</span>
|
||||||
<span className="text-sm text-muted-foreground text-shadow-sm">
|
<span className="text-sm text-muted-foreground text-shadow-sm">
|
||||||
{timeAgo}
|
{timeAgo}
|
||||||
</span>
|
</span>
|
||||||
|
@@ -28,7 +28,7 @@ export function ThoughtList({
|
|||||||
{thoughts.map((thought) => {
|
{thoughts.map((thought) => {
|
||||||
const author = {
|
const author = {
|
||||||
username: thought.authorUsername,
|
username: thought.authorUsername,
|
||||||
avatarUrl: null,
|
displayName: thought.authorDisplayName,
|
||||||
...authorDetails.get(thought.authorUsername),
|
...authorDetails.get(thought.authorUsername),
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
@@ -16,7 +16,7 @@ export function ThoughtThread({
|
|||||||
}: ThoughtThreadProps) {
|
}: ThoughtThreadProps) {
|
||||||
const author = {
|
const author = {
|
||||||
username: thought.authorUsername,
|
username: thought.authorUsername,
|
||||||
avatarUrl: null,
|
displayName: thought.authorDisplayName,
|
||||||
...authorDetails.get(thought.authorUsername),
|
...authorDetails.get(thought.authorUsername),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export function ThoughtThread({
|
|||||||
className="pl-6 border-l-2 border-primary border-dashed ml-6 flex flex-col gap-4 pt-4"
|
className="pl-6 border-l-2 border-primary border-dashed ml-6 flex flex-col gap-4 pt-4"
|
||||||
>
|
>
|
||||||
{thought.replies.map((reply) => (
|
{thought.replies.map((reply) => (
|
||||||
<ThoughtThread // RECURSIVE CALL
|
<ThoughtThread
|
||||||
key={reply.id}
|
key={reply.id}
|
||||||
thought={reply}
|
thought={reply}
|
||||||
authorDetails={authorDetails}
|
authorDetails={authorDetails}
|
||||||
|
@@ -28,6 +28,7 @@ export const MeSchema = z.object({
|
|||||||
export const ThoughtSchema = z.object({
|
export const ThoughtSchema = z.object({
|
||||||
id: z.uuid(),
|
id: z.uuid(),
|
||||||
authorUsername: z.string(),
|
authorUsername: z.string(),
|
||||||
|
authorDisplayName: z.string().nullable(),
|
||||||
content: z.string(),
|
content: z.string(),
|
||||||
visibility: z.enum(["Public", "FriendsOnly", "Private"]),
|
visibility: z.enum(["Public", "FriendsOnly", "Private"]),
|
||||||
replyToId: z.uuid().nullable(),
|
replyToId: z.uuid().nullable(),
|
||||||
@@ -87,6 +88,7 @@ export const CreateApiKeySchema = z.object({
|
|||||||
export const ThoughtThreadSchema: z.ZodType<{
|
export const ThoughtThreadSchema: z.ZodType<{
|
||||||
id: string;
|
id: string;
|
||||||
authorUsername: string;
|
authorUsername: string;
|
||||||
|
authorDisplayName: string | null;
|
||||||
content: string;
|
content: string;
|
||||||
visibility: "Public" | "FriendsOnly" | "Private";
|
visibility: "Public" | "FriendsOnly" | "Private";
|
||||||
replyToId: string | null;
|
replyToId: string | null;
|
||||||
@@ -95,6 +97,7 @@ export const ThoughtThreadSchema: z.ZodType<{
|
|||||||
}> = z.object({
|
}> = z.object({
|
||||||
id: z.uuid(),
|
id: z.uuid(),
|
||||||
authorUsername: z.string(),
|
authorUsername: z.string(),
|
||||||
|
authorDisplayName: z.string().nullable(),
|
||||||
content: z.string(),
|
content: z.string(),
|
||||||
visibility: z.enum(["Public", "FriendsOnly", "Private"]),
|
visibility: z.enum(["Public", "FriendsOnly", "Private"]),
|
||||||
replyToId: z.uuid().nullable(),
|
replyToId: z.uuid().nullable(),
|
||||||
|
Reference in New Issue
Block a user