Added QuotedCidLink component in comment-content.tsx to render multiple quote links when quotedCids array exists. Updated ReplyQuotePreview to accept and display isOP prop, showing "(OP)" label for original post quotes in both desktop and mobile views. Prefers useComment hook over store when number property is available for deeper nested replies.

Added `QuotedCidLink` component in `comment-content.tsx` to render multiple quote links when `quotedCids` array exists. Updated `ReplyQuotePreview` to accept and display `isOP` prop, showing "(OP)" label for original post quotes in both desktop and mobile views. Prefers `useComment` hook over store when `number` property is available for deeper nested replies.
This commit is contained in:
plebeius
2026-02-09 19:23:15 +08:00
parent 41b7fee439
commit 0fb14e653c
2 changed files with 30 additions and 7 deletions
@@ -15,6 +15,15 @@ import Tooltip from '../../components/tooltip';
import styles from '../../views/post/post.module.css';
import _ from 'lodash';
const QuotedCidLink = ({ cid, postCid }: { cid: string; postCid: string }) => {
const commentFromStore = useSubplebbitsPagesStore((state) => state.comments[cid]);
const commentFromHook = useComment({ commentCid: cid, onlyIfCached: true });
// Prefer hook version to ensure 'number' property is populated for deeper nested replies in Virtuoso
const quotedComment = commentFromHook?.number !== undefined ? commentFromHook : commentFromStore;
const isOP = cid === postCid;
return <ReplyQuotePreview isQuotelinkReply={true} quotelinkReply={quotedComment} isOP={isOP} />;
};
const CommentContent = ({ comment: post }: { comment: Comment }) => {
const { t } = useTranslation();
const params = useParams();
@@ -23,7 +32,7 @@ const CommentContent = ({ comment: post }: { comment: Comment }) => {
const [showOriginal, setShowOriginal] = useState(false);
const isMobile = useIsMobile();
const { cid, content, deleted, edit, original, parentCid, postCid, pendingApproval, reason, removed, state, subplebbitAddress } = post || {};
const { cid, content, deleted, edit, original, parentCid, postCid, pendingApproval, quotedCids, reason, removed, state, subplebbitAddress } = post || {};
const banned = !!post?.author?.subplebbit?.banExpiresAt;
const [showFullComment, setShowFullComment] = useState(false);
@@ -49,7 +58,12 @@ const CommentContent = ({ comment: post }: { comment: Comment }) => {
return (
<blockquote className={`${styles.postMessage} ${!isReply && isMobile && styles.clampLines}`}>
{isReply && state !== 'failed' && isReplyingToReply && !(deleted || removed) && <ReplyQuotePreview isQuotelinkReply={true} quotelinkReply={quotelinkReply} />}
{isReply &&
state !== 'failed' &&
!(deleted || removed) &&
(quotedCids?.length > 0
? quotedCids.map((cid: string) => <QuotedCidLink key={cid} cid={cid} postCid={postCid} />)
: isReplyingToReply && <ReplyQuotePreview isQuotelinkReply={true} quotelinkReply={quotelinkReply} />)}
{removed ? (
reason ? (
<>
@@ -14,6 +14,7 @@ interface ReplyQuotePreviewProps {
backlinkReply?: Comment;
isQuotelinkReply?: boolean;
quotelinkReply?: Comment;
isOP?: boolean;
}
const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => {
@@ -54,7 +55,7 @@ const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => {
}
};
const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, isOP }: ReplyQuotePreviewProps) => {
const [hoveredCid, setHoveredCid] = useState<string | null>(null);
const [outOfViewCid, setOutOfViewCid] = useState<string | null>(null);
const placementRef = useRef<Placement>('right');
@@ -173,6 +174,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
onClick={(e) => handleClick(e, quotelinkReply?.cid, quotelinkReply?.subplebbitAddress)}
>
{`>>${quotelinkReply?.number ?? '?'}`}
{isOP && ' (OP)'}
{quotelinkReply?.author?.address === account?.author?.address && ' (You)'}
</Link>
<br />
@@ -190,7 +192,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
};
const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, isOP }: ReplyQuotePreviewProps) => {
const [hoveredCid, setHoveredCid] = useState<string | null>(null);
const [outOfViewCid, setOutOfViewCid] = useState<string | null>(null);
const directories = useDirectories();
@@ -286,6 +288,7 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
onMouseLeave={() => handleMouseLeave(quotelinkReply?.cid)}
>
{`>>${quotelinkReply?.number ?? '?'}`}
{isOP && ' (OP)'}
{quotelinkReply?.author?.address === account?.author?.address && ' (You)'}
</span>
{quotelinkReply?.number &&
@@ -317,13 +320,19 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
};
const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, isOP }: ReplyQuotePreviewProps) => {
const isMobile = useIsMobile();
return isMobile ? (
<MobileQuotePreview backlinkReply={backlinkReply} quotelinkReply={quotelinkReply} isBacklinkReply={isBacklinkReply} isQuotelinkReply={isQuotelinkReply} />
<MobileQuotePreview backlinkReply={backlinkReply} quotelinkReply={quotelinkReply} isBacklinkReply={isBacklinkReply} isQuotelinkReply={isQuotelinkReply} isOP={isOP} />
) : (
<DesktopQuotePreview backlinkReply={backlinkReply} quotelinkReply={quotelinkReply} isBacklinkReply={isBacklinkReply} isQuotelinkReply={isQuotelinkReply} />
<DesktopQuotePreview
backlinkReply={backlinkReply}
quotelinkReply={quotelinkReply}
isBacklinkReply={isBacklinkReply}
isQuotelinkReply={isQuotelinkReply}
isOP={isOP}
/>
);
};