0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2024-12-30 22:34:01 -05:00

Fixed intermittent error when posting a note in admin-x-activitypub (#21917)

refs
[AP-629](https://linear.app/ghost/issue/AP-629/notes-say-they-error-but-post-correctly)

Fixed intermittent error when posting a note in `admin-x-activitypub`

The error was intermittent due to it only occurring when a specific set
of steps occurred, and the query cache being periodically cleared.

The error itself was due to incorrectly expecting the `outbox:${handle}`
query to be an array when it was in fact an object.

This PR also resolves and issue where the reply count for new notes
would display `NaN` (because the `replyCount` property was not present
on newly created notes)
This commit is contained in:
Michael Barrett 2024-12-18 19:05:31 +00:00 committed by GitHub
parent 79e5991ac2
commit 06cd63a3ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 11 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@tryghost/admin-x-activitypub",
"version": "0.3.38",
"version": "0.3.39",
"license": "MIT",
"repository": {
"type": "git",

View file

@ -258,13 +258,13 @@ export class ActivityPubAPI {
};
}
async reply(id: string, content: string) {
async reply(id: string, content: string): Promise<Activity> {
const url = new URL(`.ghost/activitypub/actions/reply/${encodeURIComponent(id)}`, this.apiUrl);
const response = await this.fetchJSON(url, 'POST', {content});
return response;
}
async note(content: string) {
async note(content: string): Promise<Activity> {
const url = new URL('.ghost/activitypub/actions/note', this.apiUrl);
const response = await this.fetchJSON(url, 'POST', {content});
return response;

View file

@ -356,13 +356,13 @@ const ArticleModal: React.FC<ArticleModalProps> = ({
updateActivity(activityId, {
object: {
...object,
replyCount: object.replyCount + 1
replyCount: (object.replyCount ?? 0) + 1
}
} as Partial<Activity>);
// Update the replyCount on the current activity loaded in the modal
// This is used for when we navigate via the history
object.replyCount = object.replyCount + 1;
object.replyCount = (object.replyCount ?? 0) + 1;
}
const replyBoxRef = useRef<HTMLDivElement>(null);

View file

@ -17,23 +17,28 @@ const NewPostModal = NiceModal.create(() => {
const handlePost = async () => {
const trimmedContent = content.trim();
if (!trimmedContent) {
return;
}
await noteMutation.mutate({content: trimmedContent}, {
noteMutation.mutate({content: trimmedContent}, {
onSuccess() {
showToast({
message: 'Note posted',
type: 'success'
});
modal.remove();
},
onError() {
onError(error) {
showToast({
message: 'An error occurred while posting your note.',
type: 'error'
});
// eslint-disable-next-line no-console
console.error(error);
}
});
};

View file

@ -488,7 +488,8 @@ export function useReplyMutationForUser(handle: string) {
async mutationFn({id, content}: {id: string, content: string}) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return await api.reply(id, content) as Activity;
return api.reply(id, content);
}
});
}
@ -500,15 +501,27 @@ export function useNoteMutationForUser(handle: string) {
async mutationFn({content}: {content: string}) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return await api.note(content) as Activity;
return api.note(content);
},
onSuccess: (activity: Activity) => {
queryClient.setQueryData([`outbox:${handle}`], (current?: Activity[]) => {
queryClient.setQueryData([`outbox:${handle}`], (current?: {pages: {data: Activity[]}[]}) => {
if (current === undefined) {
return current;
}
return [activity, ...current];
return {
...current,
pages: current.pages.map((page: {data: Activity[]}, index: number) => {
if (index === 0) {
return {
...page,
data: [activity, ...page.data]
};
}
return page;
})
};
});
queryClient.setQueriesData([`activities:${handle}`, GET_ACTIVITIES_QUERY_KEY_FEED], (current?: {pages: {data: Activity[]}[]}) => {