diff --git a/web/app/components/workflow/comment/thread.tsx b/web/app/components/workflow/comment/thread.tsx index 34a52de771..4fae9cd887 100644 --- a/web/app/components/workflow/comment/thread.tsx +++ b/web/app/components/workflow/comment/thread.tsx @@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next' import { RiArrowDownSLine, RiArrowUpSLine, RiCheckboxCircleFill, RiCheckboxCircleLine, RiCloseLine, RiDeleteBinLine, RiMoreFill } from '@remixicon/react' import Avatar from '@/app/components/base/avatar' import Divider from '@/app/components/base/divider' +import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem' import cn from '@/utils/classnames' import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now' import type { WorkflowCommentDetail, WorkflowCommentDetailReply } from '@/service/workflow-comment' @@ -197,21 +198,21 @@ export const CommentThread: FC = memo(({ const previousReplyCountRef = useRef(replies.length) const previousCommentIdRef = useRef(comment.id) - // Close dropdown when clicking outside + // Close dropdown when scrolling useEffect(() => { - if (!activeReplyMenuId) + const container = messageListRef.current + if (!container || !activeReplyMenuId) return - const handleClickOutside = (e: MouseEvent) => { - const target = e.target as HTMLElement - if (!target.closest('[data-reply-menu]')) - setActiveReplyMenuId(null) + const handleScroll = () => { + setActiveReplyMenuId(null) } - document.addEventListener('click', handleClickOutside) - return () => document.removeEventListener('click', handleClickOutside) + container.addEventListener('scroll', handleScroll) + return () => container.removeEventListener('scroll', handleScroll) }, [activeReplyMenuId]) + // Auto-scroll to bottom on new messages useEffect(() => { const container = messageListRef.current if (!container) @@ -333,44 +334,56 @@ export const CommentThread: FC = memo(({ className='group relative rounded-lg py-2 transition-colors hover:bg-components-panel-on-panel-item-bg' > {isOwnReply && !isReplyEditing && ( -
{ + if (!open) + setActiveReplyMenuId(null) + }} > - - {activeReplyMenuId === reply.id && ( -
+ - -
- )} -
+ + + + + + + )} {isReplyEditing ? (