feat(archive): implement comment.archived and add archive page (#1074)

* feat(archive): implement comment.archived and add archive page

Add isCommentArchived() utility, /board/:boardIdentifier/archive route,
archive view with filtered feed, and UI integration (board buttons, edit
menu, catalog row, post). Archived indicator on catalog and posts.

* fix(archive): address review feedback from Bugbot and CodeRabbit

Add missing i18n keys (archived, thread_archived, view, loading_archive),
add /archive/settings route, replace hardcoded English in archive.tsx, and
fix mobile test state.
This commit is contained in:
Tommaso Casaburi
2026-03-13 16:06:36 +08:00
committed by GitHub
parent d7703953fb
commit aedee9fb83
65 changed files with 1384 additions and 62 deletions
+31 -1
View File
@@ -11,6 +11,7 @@ import {
} from '@bitsocialnet/bitsocial-react-hooks';
import styles from './edit-menu.module.css';
import { alertChallengeVerificationFailed } from '../../lib/utils/challenge-utils';
import { isCommentArchived } from '../../lib/utils/comment-moderation-utils';
import useChallengesStore from '../../stores/use-challenges-store';
import capitalize from 'lodash/capitalize';
import useIsMobile from '../../hooks/use-is-mobile';
@@ -36,6 +37,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
const resolvedPost = withResolvedCommentCommunityAddress(post);
const { author, cid, content, deleted, locked, parentCid, pinned, postCid, reason, removed, spoiler } = resolvedPost || {};
const communityAddress = getCommentCommunityAddress(resolvedPost);
const archived = isCommentArchived(resolvedPost);
const authorDisplayName = resolvedPost?.author?.displayName;
const modBanExpiresAt = resolvedPost?.commentModeration?.author?.banExpiresAt;
const purged = resolvedPost?.commentModeration?.purged ?? false;
@@ -67,6 +69,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
commentModeration: isAccountMod
? {
locked: locked ?? false,
archived: parentCid === undefined ? (archived ?? false) : undefined,
pinned: pinned ?? false,
removed: removed ?? false,
purged: purged ?? false,
@@ -82,7 +85,23 @@ const EditMenu = ({ post }: { post: Comment }) => {
alert('Comment edit failed. ' + error.message);
},
};
}, [isAccountMod, isAccountCommentAuthor, cid, content, deleted, locked, pinned, reason, removed, purged, spoiler, communityAddress, modBanExpiresAt, onChallenge]);
}, [
isAccountMod,
isAccountCommentAuthor,
archived,
cid,
content,
deleted,
locked,
pinned,
reason,
removed,
purged,
spoiler,
communityAddress,
modBanExpiresAt,
onChallenge,
]);
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState<PublishCommentEditOptions>(defaultPublishEditOptions);
@@ -112,6 +131,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
communityAddress,
commentModeration: {
locked: parentCid === undefined ? publishCommentEditOptions.commentModeration?.locked : undefined,
archived: parentCid === undefined ? publishCommentEditOptions.commentModeration?.archived : undefined,
pinned: publishCommentEditOptions.commentModeration?.pinned,
removed: publishCommentEditOptions.commentModeration?.removed,
purged: publishCommentEditOptions.commentModeration?.purged,
@@ -337,6 +357,16 @@ const EditMenu = ({ post }: { post: Comment }) => {
</label>
]
</div>
{!parentCid && (
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={publishCommentEditOptions.commentModeration?.archived ?? false} type='checkbox' id='archived' />
{capitalize(t('archived'))}?
</label>
]
</div>
)}
<div className={styles.menuItem}>
[
<label>