mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(mod queue): preserve moderated queue history
This commit is contained in:
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest';
|
||||
import { filterVisibleModQueueFeed, getModQueueCommentRoute, getQueuedCommentRouteState } from '../mod-queue-utils';
|
||||
|
||||
describe('mod queue utils', () => {
|
||||
it('keeps only comments still awaiting approval', () => {
|
||||
it('keeps all queue comments unless they were locally dismissed', () => {
|
||||
const feed = [
|
||||
{ cid: 'pending', communityAddress: 'tech.eth', pendingApproval: true },
|
||||
{ cid: 'approved', approved: true, communityAddress: 'tech.eth', pendingApproval: true },
|
||||
@@ -11,17 +11,24 @@ describe('mod queue utils', () => {
|
||||
{ cid: 'published', communityAddress: 'tech.eth', pendingApproval: false },
|
||||
];
|
||||
|
||||
expect(filterVisibleModQueueFeed(feed, null)).toEqual([{ cid: 'pending', communityAddress: 'tech.eth', pendingApproval: true }]);
|
||||
expect(filterVisibleModQueueFeed(feed, null, new Set(['approved']))).toEqual([
|
||||
{ cid: 'pending', communityAddress: 'tech.eth', pendingApproval: true },
|
||||
{ cid: 'rejected', approved: false, communityAddress: 'tech.eth', pendingApproval: true },
|
||||
{ cid: 'removed', communityAddress: 'tech.eth', pendingApproval: true, removed: true },
|
||||
{ cid: 'published', communityAddress: 'tech.eth', pendingApproval: false },
|
||||
]);
|
||||
});
|
||||
|
||||
it('applies the selected board filter after removing non-pending items', () => {
|
||||
it('applies the selected board filter after removing dismissed items', () => {
|
||||
const feed = [
|
||||
{ cid: 'tech-pending', communityAddress: 'tech.eth', pendingApproval: true },
|
||||
{ cid: 'g-pending', communityAddress: 'g.eth', pendingApproval: true },
|
||||
{ cid: 'tech-approved', approved: true, communityAddress: 'tech.eth', pendingApproval: true },
|
||||
];
|
||||
|
||||
expect(filterVisibleModQueueFeed(feed, 'tech.eth')).toEqual([{ cid: 'tech-pending', communityAddress: 'tech.eth', pendingApproval: true }]);
|
||||
expect(filterVisibleModQueueFeed(feed, 'tech.eth', new Set(['tech-pending']))).toEqual([
|
||||
{ cid: 'tech-approved', approved: true, communityAddress: 'tech.eth', pendingApproval: true },
|
||||
]);
|
||||
});
|
||||
|
||||
it('builds excerpt routes from the comment permalink cid', () => {
|
||||
|
||||
@@ -11,8 +11,9 @@ describe('pending approval moderation utils', () => {
|
||||
expect('removed' in rejectPendingCommentModeration).toBe(false);
|
||||
});
|
||||
|
||||
it('treats pending approved=false as rejected for display', () => {
|
||||
it('treats approved=false as rejected for display after pkc removes pendingApproval', () => {
|
||||
expect(isPendingApprovalRejected({ pendingApproval: true, approved: false })).toBe(true);
|
||||
expect(isPendingApprovalRejected({ pendingApproval: false, approved: false })).toBe(true);
|
||||
expect(isPendingApprovalAwaiting({ pendingApproval: true, approved: false })).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Comment } from '@bitsocialnet/bitsocial-react-hooks';
|
||||
import type { Comment } from '@bitsocialnet/bitsocial-react-hooks';
|
||||
import { getCommentCommunityAddress } from './comment-utils';
|
||||
import { isPendingApprovalAwaiting } from './pending-approval-moderation';
|
||||
import { getThreadTopNavigationState } from './thread-scroll-utils';
|
||||
|
||||
type ModQueueCommentLike = {
|
||||
@@ -27,72 +26,89 @@ type ModQueueCommentLike = {
|
||||
title?: Comment['title'];
|
||||
};
|
||||
|
||||
const emptyDismissedCommentCids = new Set<string>();
|
||||
|
||||
export type QueuedCommentRouteState = {
|
||||
scrollThreadContainerCid?: string;
|
||||
queuedComment?: {
|
||||
approved?: Comment['approved'];
|
||||
author?: Comment['author'];
|
||||
cid?: Comment['cid'];
|
||||
commentModeration?: Comment['commentModeration'];
|
||||
communityAddress?: string;
|
||||
content?: Comment['content'];
|
||||
deleted?: Comment['deleted'];
|
||||
link?: Comment['link'];
|
||||
linkHeight?: Comment['linkHeight'];
|
||||
linkWidth?: Comment['linkWidth'];
|
||||
number?: Comment['number'];
|
||||
parentCid?: Comment['parentCid'];
|
||||
pendingApproval?: Comment['pendingApproval'];
|
||||
postCid?: Comment['postCid'];
|
||||
reason?: Comment['reason'];
|
||||
removed?: Comment['removed'];
|
||||
replyCount?: Comment['replyCount'];
|
||||
threadCid?: Comment['threadCid'];
|
||||
thumbnailUrl?: Comment['thumbnailUrl'];
|
||||
timestamp?: Comment['timestamp'];
|
||||
title?: Comment['title'];
|
||||
};
|
||||
queuedComment?: QueuedCommentSnapshot;
|
||||
};
|
||||
|
||||
export type QueuedCommentSnapshot = {
|
||||
approved?: Comment['approved'];
|
||||
author?: Comment['author'];
|
||||
cid?: Comment['cid'];
|
||||
commentModeration?: Comment['commentModeration'];
|
||||
communityAddress?: string;
|
||||
content?: Comment['content'];
|
||||
deleted?: Comment['deleted'];
|
||||
link?: Comment['link'];
|
||||
linkHeight?: Comment['linkHeight'];
|
||||
linkWidth?: Comment['linkWidth'];
|
||||
number?: Comment['number'];
|
||||
parentCid?: Comment['parentCid'];
|
||||
pendingApproval?: Comment['pendingApproval'];
|
||||
postCid?: Comment['postCid'];
|
||||
reason?: Comment['reason'];
|
||||
removed?: Comment['removed'];
|
||||
replyCount?: Comment['replyCount'];
|
||||
threadCid?: Comment['threadCid'];
|
||||
thumbnailUrl?: Comment['thumbnailUrl'];
|
||||
timestamp?: Comment['timestamp'];
|
||||
title?: Comment['title'];
|
||||
};
|
||||
|
||||
export const getModQueueCommentRoute = (boardPath: string | undefined, commentCid: string | undefined): string | undefined =>
|
||||
boardPath && commentCid ? `/${boardPath}/thread/${commentCid}` : undefined;
|
||||
|
||||
export const getQueuedCommentRouteState = (comment: ModQueueCommentLike | undefined): QueuedCommentRouteState | undefined => {
|
||||
export const getQueuedCommentSnapshot = (comment: ModQueueCommentLike | undefined): QueuedCommentSnapshot | undefined => {
|
||||
if (!comment?.cid) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
...(comment.parentCid ? {} : getThreadTopNavigationState(comment.cid)),
|
||||
queuedComment: {
|
||||
approved: comment.approved,
|
||||
author: comment.author,
|
||||
cid: comment.cid,
|
||||
commentModeration: comment.commentModeration,
|
||||
communityAddress: getCommentCommunityAddress(comment),
|
||||
content: comment.content,
|
||||
deleted: comment.deleted,
|
||||
link: comment.link,
|
||||
linkHeight: comment.linkHeight,
|
||||
linkWidth: comment.linkWidth,
|
||||
number: comment.number,
|
||||
parentCid: comment.parentCid,
|
||||
pendingApproval: comment.pendingApproval,
|
||||
postCid: comment.postCid,
|
||||
reason: comment.reason,
|
||||
removed: comment.removed,
|
||||
replyCount: comment.replyCount,
|
||||
threadCid: comment.threadCid,
|
||||
thumbnailUrl: comment.thumbnailUrl,
|
||||
timestamp: comment.timestamp,
|
||||
title: comment.title,
|
||||
},
|
||||
approved: comment.approved,
|
||||
author: comment.author,
|
||||
cid: comment.cid,
|
||||
commentModeration: comment.commentModeration,
|
||||
communityAddress: getCommentCommunityAddress(comment),
|
||||
content: comment.content,
|
||||
deleted: comment.deleted,
|
||||
link: comment.link,
|
||||
linkHeight: comment.linkHeight,
|
||||
linkWidth: comment.linkWidth,
|
||||
number: comment.number,
|
||||
parentCid: comment.parentCid,
|
||||
pendingApproval: comment.pendingApproval,
|
||||
postCid: comment.postCid,
|
||||
reason: comment.reason,
|
||||
removed: comment.removed,
|
||||
replyCount: comment.replyCount,
|
||||
threadCid: comment.threadCid,
|
||||
thumbnailUrl: comment.thumbnailUrl,
|
||||
timestamp: comment.timestamp,
|
||||
title: comment.title,
|
||||
};
|
||||
};
|
||||
|
||||
export const filterVisibleModQueueFeed = <T extends ModQueueCommentLike>(feed: T[], selectedBoardFilter: string | null): T[] =>
|
||||
export const getQueuedCommentRouteState = (comment: ModQueueCommentLike | undefined): QueuedCommentRouteState | undefined => {
|
||||
const queuedComment = getQueuedCommentSnapshot(comment);
|
||||
if (!queuedComment) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
...(queuedComment.parentCid ? {} : getThreadTopNavigationState(queuedComment.cid)),
|
||||
queuedComment,
|
||||
};
|
||||
};
|
||||
|
||||
export const filterVisibleModQueueFeed = <T extends ModQueueCommentLike>(
|
||||
feed: T[],
|
||||
selectedBoardFilter: string | null,
|
||||
dismissedCommentCids: ReadonlySet<string> = emptyDismissedCommentCids,
|
||||
): T[] =>
|
||||
feed.filter((comment) => {
|
||||
if (!isPendingApprovalAwaiting(comment)) {
|
||||
if (comment.cid && dismissedCommentCids.has(comment.cid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,7 @@ type PendingApprovalDisplayState = {
|
||||
pendingApproval?: boolean;
|
||||
};
|
||||
|
||||
export const isPendingApprovalRejected = (comment?: PendingApprovalDisplayState) =>
|
||||
comment?.removed === true || (comment?.pendingApproval === true && comment?.approved === false);
|
||||
export const isPendingApprovalRejected = (comment?: PendingApprovalDisplayState) => comment?.removed === true || comment?.approved === false;
|
||||
|
||||
export const isPendingApprovalAwaiting = (comment?: PendingApprovalDisplayState) =>
|
||||
comment?.pendingApproval === true && comment?.approved !== true && !isPendingApprovalRejected(comment);
|
||||
|
||||
Reference in New Issue
Block a user