feat: add author display name to thought schemas and update related components

This commit is contained in:
2025-09-07 22:54:34 +02:00
parent 2083f3bb16
commit 9b2a1139b5
7 changed files with 25 additions and 12 deletions

View File

@@ -38,6 +38,7 @@ pub async fn search_thoughts(
// We must join with the user table to get the author's username
let thoughts_with_authors = thought::Entity::find()
.column_as(user::Column::Username, "author_username")
.column_as(user::Column::DisplayName, "author_display_name")
.join(JoinType::InnerJoin, thought::Relation::User.def())
.filter(Expr::cust_with_values(
"thought.search_document @@ websearch_to_tsquery('english', $1)",

View File

@@ -102,6 +102,7 @@ pub async fn get_thoughts_by_user(
.column(thought::Column::CreatedAt)
.column(thought::Column::AuthorId)
.column(thought::Column::Visibility)
.column_as(user::Column::DisplayName, "author_display_name")
.column_as(user::Column::Username, "author_username")
.join(JoinType::InnerJoin, thought::Relation::User.def())
.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::AuthorId)
.column_as(user::Column::Username, "author_username")
.column_as(user::Column::DisplayName, "author_display_name")
.join(JoinType::InnerJoin, thought::Relation::User.def())
.filter(
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::Visibility)
.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::ThoughtTag.def())
.join(JoinType::InnerJoin, thought_tag::Relation::Tag.def())
@@ -288,6 +291,7 @@ pub async fn get_thought_with_replies(
ThoughtThreadSchema {
id: thought_schema.id,
author_username: thought_schema.author_username.clone(),
author_display_name: thought_schema.author_display_name.clone(),
content: thought_schema.content.clone(),
visibility: thought_schema.visibility.clone(),
reply_to_id: thought_schema.reply_to_id,

View File

@@ -14,6 +14,7 @@ pub struct ThoughtSchema {
pub id: Uuid,
#[schema(example = "frutiger")]
pub author_username: String,
pub author_display_name: Option<String>,
#[schema(example = "This is my first thought! #welcome")]
pub content: String,
pub visibility: Visibility,
@@ -23,15 +24,10 @@ pub struct ThoughtSchema {
impl ThoughtSchema {
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 {
id: thought.id,
author_username,
author_username: author.username.clone(),
author_display_name: author.display_name.clone(),
content: thought.content.clone(),
visibility: thought.visibility.clone(),
reply_to_id: thought.reply_to_id,
@@ -60,6 +56,7 @@ pub struct ThoughtWithAuthor {
pub visibility: Visibility,
pub author_id: Uuid,
pub author_username: String,
pub author_display_name: Option<String>,
pub reply_to_id: Option<Uuid>,
}
@@ -68,6 +65,7 @@ impl From<ThoughtWithAuthor> for ThoughtSchema {
Self {
id: model.id,
author_username: model.author_username,
author_display_name: model.author_display_name,
content: model.content,
created_at: model.created_at.into(),
reply_to_id: model.reply_to_id,
@@ -81,6 +79,7 @@ impl From<ThoughtWithAuthor> for ThoughtSchema {
pub struct ThoughtThreadSchema {
pub id: Uuid,
pub author_username: String,
pub author_display_name: Option<String>,
pub content: String,
pub visibility: Visibility,
pub reply_to_id: Option<Uuid>,

View File

@@ -44,6 +44,7 @@ interface ThoughtCardProps {
thought: Thought;
author: {
username: string;
displayName?: string | null;
avatarUrl?: string | null;
};
currentUser: Me | null;
@@ -112,9 +113,14 @@ export function ThoughtCard({
href={`/users/${author.username}`}
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">
<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">
{timeAgo}
</span>

View File

@@ -28,7 +28,7 @@ export function ThoughtList({
{thoughts.map((thought) => {
const author = {
username: thought.authorUsername,
avatarUrl: null,
displayName: thought.authorDisplayName,
...authorDetails.get(thought.authorUsername),
};
return (

View File

@@ -16,7 +16,7 @@ export function ThoughtThread({
}: ThoughtThreadProps) {
const author = {
username: thought.authorUsername,
avatarUrl: null,
displayName: thought.authorDisplayName,
...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"
>
{thought.replies.map((reply) => (
<ThoughtThread // RECURSIVE CALL
<ThoughtThread
key={reply.id}
thought={reply}
authorDetails={authorDetails}

View File

@@ -28,6 +28,7 @@ export const MeSchema = z.object({
export const ThoughtSchema = z.object({
id: z.uuid(),
authorUsername: z.string(),
authorDisplayName: z.string().nullable(),
content: z.string(),
visibility: z.enum(["Public", "FriendsOnly", "Private"]),
replyToId: z.uuid().nullable(),
@@ -87,6 +88,7 @@ export const CreateApiKeySchema = z.object({
export const ThoughtThreadSchema: z.ZodType<{
id: string;
authorUsername: string;
authorDisplayName: string | null;
content: string;
visibility: "Public" | "FriendsOnly" | "Private";
replyToId: string | null;
@@ -95,6 +97,7 @@ export const ThoughtThreadSchema: z.ZodType<{
}> = z.object({
id: z.uuid(),
authorUsername: z.string(),
authorDisplayName: z.string().nullable(),
content: z.string(),
visibility: z.enum(["Public", "FriendsOnly", "Private"]),
replyToId: z.uuid().nullable(),