feat: followers/following links on remote profile; render remote post content as HTML
Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Failing after 9m39s
test / unit (pull_request) Failing after 10m48s
test / integration (pull_request) Failing after 16m54s
Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Failing after 9m39s
test / unit (pull_request) Failing after 10m48s
test / integration (pull_request) Failing after 16m54s
This commit is contained in:
@@ -1398,6 +1398,8 @@ impl domain::ports::FederationActionPort for ActivityPubService {
|
|||||||
banner_url: actor.banner_url.as_ref().map(|u| u.to_string()),
|
banner_url: actor.banner_url.as_ref().map(|u| u.to_string()),
|
||||||
also_known_as: actor.also_known_as.clone(),
|
also_known_as: actor.also_known_as.clone(),
|
||||||
outbox_url: Some(actor.outbox_url.to_string()),
|
outbox_url: Some(actor.outbox_url.to_string()),
|
||||||
|
followers_url: Some(actor.followers_url.to_string()),
|
||||||
|
following_url: Some(actor.following_url.to_string()),
|
||||||
attachment: actor
|
attachment: actor
|
||||||
.attachment
|
.attachment
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -45,6 +45,6 @@ impl RemoteActorRepository for PgRemoteActorRepository {
|
|||||||
"SELECT url,handle,display_name,inbox_url,shared_inbox_url,public_key,avatar_url,last_fetched_at FROM remote_actors WHERE url=$1"
|
"SELECT url,handle,display_name,inbox_url,shared_inbox_url,public_key,avatar_url,last_fetched_at FROM remote_actors WHERE url=$1"
|
||||||
).bind(url).fetch_optional(&self.pool).await
|
).bind(url).fetch_optional(&self.pool).await
|
||||||
.map_err(|e| DomainError::Internal(e.to_string()))
|
.map_err(|e| DomainError::Internal(e.to_string()))
|
||||||
.map(|o| o.map(|r| RemoteActor { url: r.url, handle: r.handle, display_name: r.display_name, inbox_url: r.inbox_url, shared_inbox_url: r.shared_inbox_url, public_key: r.public_key, avatar_url: r.avatar_url, last_fetched_at: r.last_fetched_at, bio: None, banner_url: None, also_known_as: None, outbox_url: None, attachment: vec![] }))
|
.map(|o| o.map(|r| RemoteActor { url: r.url, handle: r.handle, display_name: r.display_name, inbox_url: r.inbox_url, shared_inbox_url: r.shared_inbox_url, public_key: r.public_key, avatar_url: r.avatar_url, last_fetched_at: r.last_fetched_at, bio: None, banner_url: None, also_known_as: None, outbox_url: None, followers_url: None, following_url: None, attachment: vec![] }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,5 +106,7 @@ pub struct RemoteActorResponse {
|
|||||||
pub banner_url: Option<String>,
|
pub banner_url: Option<String>,
|
||||||
pub also_known_as: Option<String>,
|
pub also_known_as: Option<String>,
|
||||||
pub outbox_url: Option<String>,
|
pub outbox_url: Option<String>,
|
||||||
|
pub followers_url: Option<String>,
|
||||||
|
pub following_url: Option<String>,
|
||||||
pub attachment: Vec<ProfileField>,
|
pub attachment: Vec<ProfileField>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,7 @@ pub struct RemoteActor {
|
|||||||
pub banner_url: Option<String>,
|
pub banner_url: Option<String>,
|
||||||
pub also_known_as: Option<String>,
|
pub also_known_as: Option<String>,
|
||||||
pub outbox_url: Option<String>,
|
pub outbox_url: Option<String>,
|
||||||
|
pub followers_url: Option<String>,
|
||||||
|
pub following_url: Option<String>,
|
||||||
pub attachment: Vec<(String, String)>,
|
pub attachment: Vec<(String, String)>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ pub async fn lookup_handler(
|
|||||||
banner_url: actor.banner_url,
|
banner_url: actor.banner_url,
|
||||||
also_known_as: actor.also_known_as,
|
also_known_as: actor.also_known_as,
|
||||||
outbox_url: actor.outbox_url,
|
outbox_url: actor.outbox_url,
|
||||||
|
followers_url: actor.followers_url,
|
||||||
|
following_url: actor.following_url,
|
||||||
attachment: actor
|
attachment: actor
|
||||||
.attachment
|
.attachment
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|||||||
@@ -133,6 +133,31 @@ export function RemoteUserProfile({
|
|||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{(actor.followersUrl || actor.followingUrl) && (
|
||||||
|
<div className="mt-3 flex gap-3 text-sm">
|
||||||
|
{actor.followersUrl && (
|
||||||
|
<Link
|
||||||
|
href={actor.followersUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-muted-foreground hover:text-foreground hover:underline"
|
||||||
|
>
|
||||||
|
Followers
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
{actor.followingUrl && (
|
||||||
|
<Link
|
||||||
|
href={actor.followingUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-muted-foreground hover:text-foreground hover:underline"
|
||||||
|
>
|
||||||
|
Following
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{actor.alsoKnownAs && (
|
{actor.alsoKnownAs && (
|
||||||
<p className="mt-2 text-xs text-muted-foreground">
|
<p className="mt-2 text-xs text-muted-foreground">
|
||||||
Also known as:{" "}
|
Also known as:{" "}
|
||||||
|
|||||||
@@ -152,9 +152,16 @@ export function ThoughtCard({
|
|||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
|
{thought.author.local ? (
|
||||||
<p className="whitespace-pre-wrap break-words text-shadow-sm">
|
<p className="whitespace-pre-wrap break-words text-shadow-sm">
|
||||||
{thought.content}
|
{thought.content}
|
||||||
</p>
|
</p>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className="text-sm break-words [&_a]:underline [&_a]:text-primary [&_p]:mb-2"
|
||||||
|
dangerouslySetInnerHTML={{ __html: thought.content }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
{token && (
|
{token && (
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ export const RemoteActorSchema = z.object({
|
|||||||
bannerUrl: z.string().nullable(),
|
bannerUrl: z.string().nullable(),
|
||||||
alsoKnownAs: z.string().nullable(),
|
alsoKnownAs: z.string().nullable(),
|
||||||
outboxUrl: z.string().nullable(),
|
outboxUrl: z.string().nullable(),
|
||||||
|
followersUrl: z.string().nullable(),
|
||||||
|
followingUrl: z.string().nullable(),
|
||||||
attachment: z.array(ProfileFieldSchema),
|
attachment: z.array(ProfileFieldSchema),
|
||||||
});
|
});
|
||||||
export type RemoteActor = z.infer<typeof RemoteActorSchema>;
|
export type RemoteActor = z.infer<typeof RemoteActorSchema>;
|
||||||
|
|||||||
Reference in New Issue
Block a user