mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(reply-quote-preview): keep floating OP previews at desktop width
This commit is contained in:
@@ -4,6 +4,7 @@ import { createRoot, type Root } from 'react-dom/client';
|
|||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import ExternalNumberQuoteLink from '../external-number-quote-link';
|
import ExternalNumberQuoteLink from '../external-number-quote-link';
|
||||||
|
import postStyles from '../../../views/post/post.module.css';
|
||||||
|
|
||||||
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
||||||
const act = (React as { act?: (cb: () => void | Promise<void>) => void | Promise<void> }).act as (cb: () => void | Promise<void>) => void | Promise<void>;
|
const act = (React as { act?: (cb: () => void | Promise<void>) => void | Promise<void> }).act as (cb: () => void | Promise<void>) => void | Promise<void>;
|
||||||
@@ -146,4 +147,41 @@ describe('ExternalNumberQuoteLink', () => {
|
|||||||
|
|
||||||
expect(document.body.querySelector('[data-testid="post-preview"]')?.textContent).toBe('cid-77');
|
expect(document.body.querySelector('[data-testid="post-preview"]')?.textContent).toBe('cid-77');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses the OP preview width class for resolved external OP previews', async () => {
|
||||||
|
testState.resolveExternalQuoteTargetMock.mockResolvedValue({
|
||||||
|
boardPath: 'fit',
|
||||||
|
cid: 'cid-77',
|
||||||
|
comment: { cid: 'cid-77' },
|
||||||
|
isUnavailable: false,
|
||||||
|
route: '/fit/thread/cid-77',
|
||||||
|
communityAddress: 'fit',
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.render(
|
||||||
|
createElement(
|
||||||
|
MemoryRouter,
|
||||||
|
{},
|
||||||
|
createElement(ExternalNumberQuoteLink, {
|
||||||
|
reference: {
|
||||||
|
boardIdentifier: 'fit',
|
||||||
|
kind: 'cross-board',
|
||||||
|
number: 77,
|
||||||
|
raw: '>>>/fit/77',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
container.querySelector('a')?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
|
||||||
|
await Promise.resolve();
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
});
|
||||||
|
|
||||||
|
const preview = document.body.querySelector(`.${postStyles.replyQuotePreview}`);
|
||||||
|
expect(preview?.classList.contains(postStyles.replyQuotePreviewOp)).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -260,6 +260,10 @@ const ExternalNumberQuoteLink = ({ reference }: ExternalNumberQuoteLinkProps) =>
|
|||||||
) : (
|
) : (
|
||||||
<div className={`${styles.externalQuotePreviewState} ${styles.externalQuotePreviewError}`}>{previewState.message}</div>
|
<div className={`${styles.externalQuotePreviewState} ${styles.externalQuotePreviewError}`}>{previewState.message}</div>
|
||||||
);
|
);
|
||||||
|
const previewClassName =
|
||||||
|
previewState.kind === 'resolved' && previewState.target.comment && !previewState.target.comment.parentCid
|
||||||
|
? `${postStyles.replyQuotePreview} ${postStyles.replyQuotePreviewOp}`
|
||||||
|
: postStyles.replyQuotePreview;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -280,7 +284,7 @@ const ExternalNumberQuoteLink = ({ reference }: ExternalNumberQuoteLinkProps) =>
|
|||||||
previewContent &&
|
previewContent &&
|
||||||
createPortal(
|
createPortal(
|
||||||
<div
|
<div
|
||||||
className={postStyles.replyQuotePreview}
|
className={previewClassName}
|
||||||
data-thread-scroll-preview='true'
|
data-thread-scroll-preview='true'
|
||||||
ref={previewRef}
|
ref={previewRef}
|
||||||
style={{ left: previewPosition.left, position: 'fixed', top: previewPosition.top, zIndex: 1000 }}
|
style={{ left: previewPosition.left, position: 'fixed', top: previewPosition.top, zIndex: 1000 }}
|
||||||
|
|||||||
@@ -401,6 +401,36 @@ describe('ReplyQuotePreview', () => {
|
|||||||
outOfView.remove();
|
outOfView.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses the OP preview width class for floating desktop OP quotelinks', async () => {
|
||||||
|
const outOfView = appendReplyElement({ cid: 'thread-cid', inViewport: false, isThreadCard: true });
|
||||||
|
|
||||||
|
await renderPreview({
|
||||||
|
isOP: true,
|
||||||
|
isQuotelinkReply: true,
|
||||||
|
quotelinkReply: {
|
||||||
|
cid: 'thread-cid',
|
||||||
|
number: 1,
|
||||||
|
communityAddress: 'music-posting.eth',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const link = queryAnchorByText('>>1 (OP)');
|
||||||
|
expect(link).toBeTruthy();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
link?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
|
||||||
|
});
|
||||||
|
|
||||||
|
const preview = document.querySelector(`.${styles.replyQuotePreview}`);
|
||||||
|
expect(preview?.classList.contains(styles.replyQuotePreviewOp)).toBe(true);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
link?.dispatchEvent(new MouseEvent('mouseout', { bubbles: true }));
|
||||||
|
});
|
||||||
|
|
||||||
|
outOfView.remove();
|
||||||
|
});
|
||||||
|
|
||||||
it('marks quotelinks as your own via the direct account comment lookup before author fallback', async () => {
|
it('marks quotelinks as your own via the direct account comment lookup before author fallback', async () => {
|
||||||
testState.account = {
|
testState.account = {
|
||||||
id: 'account-1',
|
id: 'account-1',
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ interface ReplyQuotePreviewProps {
|
|||||||
showTrailingBreak?: boolean;
|
showTrailingBreak?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getQuotePreviewClassName = (previewPost?: Comment) =>
|
||||||
|
!previewPost?.parentCid ? `${styles.replyQuotePreview} ${styles.replyQuotePreviewOp}` : styles.replyQuotePreview;
|
||||||
|
|
||||||
const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => {
|
const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => {
|
||||||
const targetElements = document.querySelectorAll(`[data-cid="${cid}"]`);
|
const targetElements = document.querySelectorAll(`[data-cid="${cid}"]`);
|
||||||
const isOpElement = (element: HTMLElement) => element.getAttribute('data-post-cid') === cid;
|
const isOpElement = (element: HTMLElement) => element.getAttribute('data-post-cid') === cid;
|
||||||
@@ -209,7 +212,7 @@ const DesktopQuotePreview = ({
|
|||||||
{hoveredCid === normalizedBacklinkReply?.cid &&
|
{hoveredCid === normalizedBacklinkReply?.cid &&
|
||||||
outOfViewCid === normalizedBacklinkReply?.cid &&
|
outOfViewCid === normalizedBacklinkReply?.cid &&
|
||||||
createPortal(
|
createPortal(
|
||||||
<div className={styles.replyQuotePreview} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
<div className={getQuotePreviewClassName(normalizedBacklinkReply)} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
||||||
<Post post={normalizedBacklinkReply} showReplies={false} />
|
<Post post={normalizedBacklinkReply} showReplies={false} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
@@ -265,7 +268,7 @@ const DesktopQuotePreview = ({
|
|||||||
{showTrailingBreak && <br />}
|
{showTrailingBreak && <br />}
|
||||||
{shouldShowQuotelinkPreview &&
|
{shouldShowQuotelinkPreview &&
|
||||||
createPortal(
|
createPortal(
|
||||||
<div className={styles.replyQuotePreview} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
<div className={getQuotePreviewClassName(normalizedQuotelinkReply)} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
||||||
<Post post={normalizedQuotelinkReply} showReplies={false} />
|
<Post post={normalizedQuotelinkReply} showReplies={false} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
@@ -373,7 +376,7 @@ const MobileQuotePreview = ({
|
|||||||
{hoveredCid === normalizedBacklinkReply?.cid &&
|
{hoveredCid === normalizedBacklinkReply?.cid &&
|
||||||
outOfViewCid === normalizedBacklinkReply?.cid &&
|
outOfViewCid === normalizedBacklinkReply?.cid &&
|
||||||
createPortal(
|
createPortal(
|
||||||
<div className={styles.replyQuotePreview} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
<div className={getQuotePreviewClassName(normalizedBacklinkReply)} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
||||||
<Post post={normalizedBacklinkReply} showReplies={false} />
|
<Post post={normalizedBacklinkReply} showReplies={false} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
@@ -427,7 +430,7 @@ const MobileQuotePreview = ({
|
|||||||
{showTrailingBreak && <br />}
|
{showTrailingBreak && <br />}
|
||||||
{shouldShowQuotelinkPreview &&
|
{shouldShowQuotelinkPreview &&
|
||||||
createPortal(
|
createPortal(
|
||||||
<div className={styles.replyQuotePreview} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
<div className={getQuotePreviewClassName(normalizedQuotelinkReply)} data-thread-scroll-preview='true' ref={refs.setFloating} style={floatingStyles}>
|
||||||
<Post post={normalizedQuotelinkReply} showReplies={false} />
|
<Post post={normalizedQuotelinkReply} showReplies={false} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
|
|||||||
@@ -672,6 +672,8 @@
|
|||||||
border: var(--quote-preview-border);
|
border: var(--quote-preview-border);
|
||||||
border-right: var(--quote-preview-border-right);
|
border-right: var(--quote-preview-border-right);
|
||||||
border-bottom: var(--quote-preview-border-bottom);
|
border-bottom: var(--quote-preview-border-bottom);
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-width: calc(100vw - 20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.postDesktop .replyQuotePreviewSpacer {
|
.postDesktop .replyQuotePreviewSpacer {
|
||||||
@@ -724,6 +726,10 @@
|
|||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.replyQuotePreviewOp {
|
||||||
|
width: min(520px, calc(100vw - 20px));
|
||||||
|
}
|
||||||
|
|
||||||
.postMobile {
|
.postMobile {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user