From bd2a0369ed63ed162472aaa5481ef20990f2340c Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Thu, 19 Sep 2024 15:35:49 +0700 Subject: [PATCH] Added new reply to the comments state ref https://linear.app/tryghost/issue/AP-395 This is a stopgap solution, because currently we don't have any of our own reply data in the frontend, so this will show the new reply, but it won't be present on page reload. Should be enough for a demo video, but I think we need to either fetch our outbox, or make a new replies endpoint and fetch from there --- .../src/components/feed/ArticleModal.tsx | 13 +++++++++---- .../src/components/global/APReplyBox.tsx | 6 +++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/apps/admin-x-activitypub/src/components/feed/ArticleModal.tsx b/apps/admin-x-activitypub/src/components/feed/ArticleModal.tsx index b045689616..13cc3d6e47 100644 --- a/apps/admin-x-activitypub/src/components/feed/ArticleModal.tsx +++ b/apps/admin-x-activitypub/src/components/feed/ArticleModal.tsx @@ -78,6 +78,7 @@ const FeedItemDivider: React.FC = () => ( const ArticleModal: React.FC = ({object, actor, comments, allComments, focusReply}) => { const MODAL_SIZE_SM = 640; const MODAL_SIZE_LG = 2800; + const [commentsState, setCommentsState] = useState(comments); const [isFocused, setFocused] = useState(focusReply ? 1 : 0); function setReplyBoxFocused(focused: boolean) { if (focused) { @@ -114,7 +115,7 @@ const ArticleModal: React.FC = ({object, actor, comments, all }; const navigateForward = (nextObject: ObjectProperties, nextActor: ActorProperties, nextComments: Activity[]) => { setCanNavigateBack(true); - setNavigationStack([...navigationStack, [object, actor, comments]]); + setNavigationStack([...navigationStack, [object, actor, commentsState]]); modal.show({ object: nextObject, @@ -127,6 +128,10 @@ const ArticleModal: React.FC = ({object, actor, comments, all setModalSize(modalSize === MODAL_SIZE_SM ? MODAL_SIZE_LG : MODAL_SIZE_SM); }; + function handleNewReply(activity: Activity) { + setCommentsState(prev => [activity].concat(prev)); + } + return ( = ({object, actor, comments, all setReplyBoxFocused(true); }} /> - + {/* {object.content &&
} */} @@ -175,8 +180,8 @@ const ArticleModal: React.FC = ({object, actor, comments, all */} - {comments.map((comment, index) => { - const showDivider = index !== comments.length - 1; + {commentsState.map((comment, index) => { + const showDivider = index !== commentsState.length - 1; const nestedComments = allComments.get(comment.object.id) ?? []; const hasNestedComments = nestedComments.length > 0; diff --git a/apps/admin-x-activitypub/src/components/global/APReplyBox.tsx b/apps/admin-x-activitypub/src/components/global/APReplyBox.tsx index 3674c6279e..4624ab7210 100644 --- a/apps/admin-x-activitypub/src/components/global/APReplyBox.tsx +++ b/apps/admin-x-activitypub/src/components/global/APReplyBox.tsx @@ -2,6 +2,7 @@ import React, {HTMLProps, useEffect, useId, useRef, useState} from 'react'; import * as FormPrimitive from '@radix-ui/react-form'; import APAvatar from './APAvatar'; +import Activity from '../activities/ActivityItem'; import clsx from 'clsx'; import getUsername from '../../utils/get-username'; import {Button, showToast} from '@tryghost/admin-x-design-system'; @@ -18,6 +19,7 @@ export interface APTextAreaProps extends HTMLProps { hint?: React.ReactNode; className?: string; onChange?: (event: React.ChangeEvent) => void; + onNewReply?: (activity: Activity) => void; object: ObjectProperties; focused: number; } @@ -32,6 +34,7 @@ const APReplyBox: React.FC = ({ className, object, focused, + onNewReply, // onChange, // onFocus, // onBlur, @@ -61,12 +64,13 @@ const APReplyBox: React.FC = ({ async function handleClick(event: React.MouseEvent) { event.preventDefault(); await replyMutation.mutate({id: object.id, content: textValue}, { - onSuccess() { + onSuccess(activity) { setTextValue(''); showToast({ message: 'Reply sent', type: 'success' }); + onNewReply(activity); } }); }