fix: store in_reply_to on remote notes + use full handle in federation component links/actions
This commit is contained in:
@@ -144,6 +144,7 @@ impl ApObjectHandler for ThoughtsObjectHandler {
|
|||||||
note.sensitive,
|
note.sensitive,
|
||||||
note.summary,
|
note.summary,
|
||||||
visibility,
|
visibility,
|
||||||
|
note.in_reply_to.as_ref(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("{e}"))
|
.map_err(|e| anyhow!("{e}"))
|
||||||
|
|||||||
@@ -218,11 +218,24 @@ impl ActivityPubRepository for PgActivityPubRepository {
|
|||||||
sensitive: bool,
|
sensitive: bool,
|
||||||
content_warning: Option<String>,
|
content_warning: Option<String>,
|
||||||
visibility: &str,
|
visibility: &str,
|
||||||
|
in_reply_to: Option<&Url>,
|
||||||
) -> Result<(), DomainError> {
|
) -> Result<(), DomainError> {
|
||||||
let capped: String = content.chars().take(500).collect();
|
let capped: String = content.chars().take(500).collect();
|
||||||
|
let (in_reply_to_id, in_reply_to_url) = match in_reply_to {
|
||||||
|
Some(url) => {
|
||||||
|
// If the parent is a local thought, extract its UUID for in_reply_to_id.
|
||||||
|
let local_uuid = url
|
||||||
|
.path()
|
||||||
|
.strip_prefix("/thoughts/")
|
||||||
|
.and_then(|s| s.split('/').next())
|
||||||
|
.and_then(|s| uuid::Uuid::parse_str(s).ok());
|
||||||
|
(local_uuid, Some(url.as_str().to_string()))
|
||||||
|
}
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
"INSERT INTO thoughts(id,user_id,content,ap_id,visibility,sensitive,local,content_warning,created_at)
|
"INSERT INTO thoughts(id,user_id,content,ap_id,visibility,sensitive,local,content_warning,created_at,in_reply_to_id,in_reply_to_url)
|
||||||
VALUES($1,$2,$3,$4,$8,$5,false,$6,$7) ON CONFLICT(ap_id) DO NOTHING",
|
VALUES($1,$2,$3,$4,$8,$5,false,$6,$7,$9,$10) ON CONFLICT(ap_id) DO NOTHING",
|
||||||
)
|
)
|
||||||
.bind(uuid::Uuid::new_v4())
|
.bind(uuid::Uuid::new_v4())
|
||||||
.bind(author_id.as_uuid())
|
.bind(author_id.as_uuid())
|
||||||
@@ -232,6 +245,8 @@ impl ActivityPubRepository for PgActivityPubRepository {
|
|||||||
.bind(content_warning)
|
.bind(content_warning)
|
||||||
.bind(published)
|
.bind(published)
|
||||||
.bind(visibility)
|
.bind(visibility)
|
||||||
|
.bind(in_reply_to_id)
|
||||||
|
.bind(&in_reply_to_url)
|
||||||
.execute(&self.pool)
|
.execute(&self.pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| DomainError::Internal(e.to_string()))
|
.map_err(|e| DomainError::Internal(e.to_string()))
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ impl FederationEventService {
|
|||||||
note.sensitive,
|
note.sensitive,
|
||||||
note.content_warning,
|
note.content_warning,
|
||||||
"public",
|
"public",
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -391,6 +391,7 @@ pub trait ActivityPubRepository: Send + Sync {
|
|||||||
sensitive: bool,
|
sensitive: bool,
|
||||||
content_warning: Option<String>,
|
content_warning: Option<String>,
|
||||||
visibility: &str,
|
visibility: &str,
|
||||||
|
in_reply_to: Option<&url::Url>,
|
||||||
) -> Result<(), DomainError>;
|
) -> Result<(), DomainError>;
|
||||||
|
|
||||||
/// Apply an Update to a previously accepted remote Note.
|
/// Apply an Update to a previously accepted remote Note.
|
||||||
|
|||||||
@@ -847,6 +847,7 @@ impl ActivityPubRepository for TestStore {
|
|||||||
_sensitive: bool,
|
_sensitive: bool,
|
||||||
_content_warning: Option<String>,
|
_content_warning: Option<String>,
|
||||||
_visibility: &str,
|
_visibility: &str,
|
||||||
|
_in_reply_to: Option<&url::Url>,
|
||||||
) -> Result<(), DomainError> {
|
) -> Result<(), DomainError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export function PendingRequests({ compact = false }: Props) {
|
|||||||
className="flex items-center justify-between gap-3"
|
className="flex items-center justify-between gap-3"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={`/users/@${actor.handle}`}
|
href={`/users/@${fullFediverseHandle(actor.handle, actor.url)}`}
|
||||||
className="flex items-center gap-2 min-w-0 hover:opacity-80"
|
className="flex items-center gap-2 min-w-0 hover:opacity-80"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function RemoteFollowers() {
|
|||||||
{followers.map((actor) => (
|
{followers.map((actor) => (
|
||||||
<li key={actor.url} className="flex items-center justify-between gap-3">
|
<li key={actor.url} className="flex items-center justify-between gap-3">
|
||||||
<Link
|
<Link
|
||||||
href={`/users/@${actor.handle}`}
|
href={`/users/@${fullFediverseHandle(actor.handle, actor.url)}`}
|
||||||
className="flex items-center gap-2 min-w-0 hover:opacity-80"
|
className="flex items-center gap-2 min-w-0 hover:opacity-80"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ export function RemoteFollowing() {
|
|||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
}, [token]);
|
}, [token]);
|
||||||
|
|
||||||
const unfollow = async (handle: string) => {
|
const unfollow = async (actor: RemoteActor) => {
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
setFollowing((prev) => prev.filter((f) => f.handle !== handle));
|
const handle = fullFediverseHandle(actor.handle, actor.url);
|
||||||
|
setFollowing((prev) => prev.filter((f) => f.url !== actor.url));
|
||||||
await unfollowRemoteActor(handle, token).catch(() => {
|
await unfollowRemoteActor(handle, token).catch(() => {
|
||||||
toast.error("Failed to unfollow");
|
toast.error("Failed to unfollow");
|
||||||
});
|
});
|
||||||
@@ -39,7 +40,7 @@ export function RemoteFollowing() {
|
|||||||
{following.map((actor) => (
|
{following.map((actor) => (
|
||||||
<li key={actor.url} className="flex items-center justify-between gap-3">
|
<li key={actor.url} className="flex items-center justify-between gap-3">
|
||||||
<Link
|
<Link
|
||||||
href={`/users/@${actor.handle}`}
|
href={`/users/@${fullFediverseHandle(actor.handle, actor.url)}`}
|
||||||
className="flex items-center gap-2 min-w-0 hover:opacity-80"
|
className="flex items-center gap-2 min-w-0 hover:opacity-80"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
@@ -59,7 +60,7 @@ export function RemoteFollowing() {
|
|||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => unfollow(actor.handle)}
|
onClick={() => unfollow(actor)}
|
||||||
>
|
>
|
||||||
Unfollow
|
Unfollow
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user