mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(mod-queue): rework excerpt hover preview, scope pending-age alerts (#1152)
Render the compact mod queue excerpt hover preview like the quote-link previews (clean read-only Post via useFloating, anchored to the right of the excerpt on desktop / below on mobile), cap its content at 350 chars, and scope the red pending-age timestamp to posts actually awaiting approval. Adds keyboard handlers to the span fallback.
This commit is contained in:
@@ -25,8 +25,10 @@ type TestComment = {
|
||||
linkWidth?: number;
|
||||
number?: number;
|
||||
parentCid?: string;
|
||||
pendingApproval?: boolean;
|
||||
pinned?: boolean;
|
||||
postCid?: string;
|
||||
approved?: boolean;
|
||||
removed?: boolean;
|
||||
replyCount?: number;
|
||||
replies?: {
|
||||
@@ -167,6 +169,8 @@ vi.mock('../../lib/utils/time-utils', () => ({
|
||||
|
||||
vi.mock('../../lib/utils/pending-approval-moderation', () => ({
|
||||
approvePendingCommentModeration: {},
|
||||
isPendingApprovalAwaiting: (comment?: TestComment) =>
|
||||
comment?.pendingApproval === true && comment?.approved !== true && comment?.approved !== false && !comment?.removed,
|
||||
isPendingApprovalRejected: () => false,
|
||||
rejectPendingCommentModeration: {},
|
||||
}));
|
||||
@@ -178,7 +182,7 @@ vi.mock('../../lib/utils/url-utils', () => ({
|
||||
|
||||
vi.mock('../../lib/utils/view-utils', () => ({
|
||||
isAllView: (pathname: string) => pathname === '/all',
|
||||
isModQueueView: () => false,
|
||||
isModQueueView: (pathname: string) => pathname === '/mod/queue' || pathname.endsWith('/mod/queue'),
|
||||
isModView: () => false,
|
||||
isPendingPostView: () => false,
|
||||
isPostPageView: (pathname: string) => pathname.includes('/thread/'),
|
||||
@@ -535,4 +539,34 @@ describe('post community address compatibility', () => {
|
||||
await renderWithRoute(createElement(PostMobile, { post: makeLegacyThreadWithoutReplies() }));
|
||||
expect(container.querySelector('.postMobile')?.getAttribute('data-pretext-height')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('does not show a mod queue age alert for published preview posts on the mod queue route', async () => {
|
||||
const publishedPost = {
|
||||
...makeLegacyThread(),
|
||||
pendingApproval: false,
|
||||
timestamp: 1_700_000_000,
|
||||
};
|
||||
|
||||
await renderWithRoute(createElement(PostDesktop, { post: publishedPost, showReplies: false }), '/mod/queue');
|
||||
expect(container.textContent).toContain('2026-03-13');
|
||||
expect(container.textContent).not.toContain('moments ago');
|
||||
|
||||
await renderWithRoute(createElement(PostMobile, { post: publishedPost, showReplies: false }), '/mod/queue');
|
||||
expect(container.textContent).toContain('2026-03-13');
|
||||
expect(container.textContent).not.toContain('moments ago');
|
||||
});
|
||||
|
||||
it('keeps the mod queue age alert for pending preview posts on the mod queue route', async () => {
|
||||
const pendingPost = {
|
||||
...makeLegacyThread(),
|
||||
pendingApproval: true,
|
||||
timestamp: 1_700_000_000,
|
||||
};
|
||||
|
||||
await renderWithRoute(createElement(PostDesktop, { post: pendingPost, showReplies: false }), '/mod/queue');
|
||||
expect(container.textContent).toContain('moments ago');
|
||||
|
||||
await renderWithRoute(createElement(PostMobile, { post: pendingPost, showReplies: false }), '/mod/queue');
|
||||
expect(container.textContent).toContain('moments ago');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import styles from '../../views/post/post.module.css';
|
||||
import { CommentMediaInfo, getHasThumbnail, getMediaDimensions, getPostMediaTypeLabel, getYouTubeEmbedPostMediaFileLink } from '../../lib/utils/media-utils';
|
||||
import { hashStringToColor, getTextColorForBackground } from '../../lib/utils/post-utils';
|
||||
import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils';
|
||||
import { approvePendingCommentModeration, isPendingApprovalRejected, rejectPendingCommentModeration } from '../../lib/utils/pending-approval-moderation';
|
||||
import { approvePendingCommentModeration, isPendingApprovalAwaiting, rejectPendingCommentModeration } from '../../lib/utils/pending-approval-moderation';
|
||||
import { isValidURL, parseHttpUrl } from '../../lib/utils/url-utils';
|
||||
import { isAllView, isModQueueView, isModView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||
import { formatUserIDForDisplay, truncateWithEllipsisInMiddle } from '../../lib/utils/string-utils';
|
||||
@@ -263,10 +263,7 @@ const PostInfo = ({
|
||||
const shouldShowPendingApprovalButtons = isInPostPageView && !isInModQueueView && pendingApproval && isAccountMod && communityAddress;
|
||||
|
||||
// Check if post is awaiting approval and over threshold (for mod queue view)
|
||||
const approved = post?.approved;
|
||||
const alreadyApproved = approved === true;
|
||||
const alreadyRejected = isPendingApprovalRejected(post);
|
||||
const isAwaitingApproval = isInModQueueView && !alreadyApproved && !alreadyRejected;
|
||||
const isAwaitingApproval = isInModQueueView && isPendingApprovalAwaiting(post);
|
||||
const timeWaiting = timestamp ? currentTime - timestamp : 0;
|
||||
const alertThresholdSeconds = getAlertThresholdSeconds();
|
||||
const isOverThreshold = isAwaitingApproval && timeWaiting > alertThresholdSeconds;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { shouldShowSnow } from '../../lib/snow';
|
||||
import { getHasThumbnail } from '../../lib/utils/media-utils';
|
||||
import { getTextColorForBackground, hashStringToColor } from '../../lib/utils/post-utils';
|
||||
import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils';
|
||||
import { approvePendingCommentModeration, isPendingApprovalRejected, rejectPendingCommentModeration } from '../../lib/utils/pending-approval-moderation';
|
||||
import { approvePendingCommentModeration, isPendingApprovalAwaiting, rejectPendingCommentModeration } from '../../lib/utils/pending-approval-moderation';
|
||||
import { isAllView, isModQueueView, isModView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||
import { formatUserIDForDisplay } from '../../lib/utils/string-utils';
|
||||
import useModQueueStore from '../../stores/use-mod-queue-store';
|
||||
@@ -210,10 +210,7 @@ const PostInfoAndMedia = ({
|
||||
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
|
||||
|
||||
// Check if post is awaiting approval and over threshold (for mod queue view)
|
||||
const approved = resolvedPost?.approved;
|
||||
const alreadyApproved = approved === true;
|
||||
const alreadyRejected = isPendingApprovalRejected(post);
|
||||
const isAwaitingApproval = isInModQueueView && !alreadyApproved && !alreadyRejected;
|
||||
const isAwaitingApproval = isInModQueueView && isPendingApprovalAwaiting(resolvedPost);
|
||||
const timeWaiting = timestamp ? currentTime - timestamp : 0;
|
||||
const alertThresholdSeconds = getAlertThresholdSeconds();
|
||||
const isOverThreshold = isAwaitingApproval && timeWaiting > alertThresholdSeconds;
|
||||
|
||||
Reference in New Issue
Block a user