fix(edit-menu): allow pseudonymous reply deletion (#1076)

* fix(edit-menu): allow pseudonymous reply deletion

* fix(edit-menu): ignore non-pseudonymous mode
This commit is contained in:
Tommaso Casaburi
2026-03-13 16:37:44 +08:00
committed by GitHub
parent aedee9fb83
commit 726522586c
4 changed files with 127 additions and 17 deletions
+43 -16
View File
@@ -16,6 +16,7 @@ import useChallengesStore from '../../stores/use-challenges-store';
import capitalize from 'lodash/capitalize';
import useIsMobile from '../../hooks/use-is-mobile';
import useAuthorPrivileges from '../../hooks/use-author-privileges';
import { useBoardPseudonymityMode } from '../../hooks/use-board-pseudonymity-mode';
import { getCommentCommunityAddress, withResolvedCommentCommunityAddress } from '../../lib/utils/comment-utils';
const { addChallenge } = useChallengesStore.getState();
@@ -50,7 +51,12 @@ const EditMenu = ({ post }: { post: Comment }) => {
communityAddress: communityAddress || '',
postCid,
});
const signer = isAccountCommentAuthor ? account?.signer : null;
const pseudonymityMode = useBoardPseudonymityMode(communityAddress);
const allowsPseudonymousDelete = pseudonymityMode !== undefined && pseudonymityMode !== 'none';
const canAttemptAuthorDelete = isAccountCommentAuthor || allowsPseudonymousDelete;
const canOpenEditMenu = isAccountMod || canAttemptAuthorDelete;
const requiresDeleteSelection = canAttemptAuthorDelete && !isAccountCommentAuthor && !isAccountMod;
const signer = isAccountCommentAuthor ? account?.signer : undefined;
const latestPostRef = useRef(resolvedPost);
useEffect(() => {
latestPostRef.current = resolvedPost;
@@ -63,7 +69,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
communityAddress,
// Author edit properties
content: isAccountCommentAuthor ? content : undefined,
deleted: isAccountCommentAuthor ? (deleted ?? false) : undefined,
deleted: canAttemptAuthorDelete ? (deleted ?? false) : undefined,
spoiler: isAccountCommentAuthor ? (spoiler ?? false) : undefined,
// Mod edit properties
commentModeration: isAccountMod
@@ -88,6 +94,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
}, [
isAccountMod,
isAccountCommentAuthor,
canAttemptAuthorDelete,
archived,
cid,
content,
@@ -105,12 +112,10 @@ const EditMenu = ({ post }: { post: Comment }) => {
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState<PublishCommentEditOptions>(defaultPublishEditOptions);
const authorEditOptions = useMemo<PublishCommentEditOptions>(
() => ({
const authorEditOptions = useMemo<PublishCommentEditOptions>(() => {
const options: PublishCommentEditOptions = {
commentCid: cid,
communityAddress,
signer,
author: signer?.address === author?.address ? { address: signer?.address, displayName: authorDisplayName } : account?.author,
content: publishCommentEditOptions.content,
deleted: publishCommentEditOptions.deleted,
reason: publishCommentEditOptions.reason,
@@ -121,9 +126,18 @@ const EditMenu = ({ post }: { post: Comment }) => {
console.warn(error);
alert('Comment edit failed. ' + error.message);
},
}),
[publishCommentEditOptions, cid, communityAddress, signer, account?.author, author?.address, authorDisplayName, onChallenge],
);
};
if (!isAccountCommentAuthor) {
return options;
}
return {
...options,
signer,
author: signer?.address === author?.address ? { address: signer?.address, displayName: authorDisplayName } : account?.author,
};
}, [publishCommentEditOptions, cid, communityAddress, isAccountCommentAuthor, signer, account?.author, author?.address, authorDisplayName, onChallenge]);
const modEditOptions = useMemo<PublishCommentModerationOptions>(
() => ({
@@ -186,7 +200,9 @@ const EditMenu = ({ post }: { post: Comment }) => {
}
}
if (isAccountCommentAuthor) {
if (id === 'deleted' && canAttemptAuthorDelete) {
newState.deleted = checked;
} else if (isAccountCommentAuthor) {
newState[id] = checked;
}
@@ -247,13 +263,20 @@ const EditMenu = ({ post }: { post: Comment }) => {
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss, role]);
const headingId = useId();
const canSave = !requiresDeleteSelection || publishCommentEditOptions.deleted === true;
const _publishCommentEdit = async () => {
if (!canSave) {
return;
}
const shouldPublishAuthorEdit = isAccountCommentAuthor || (canAttemptAuthorDelete && publishCommentEditOptions.deleted === true);
try {
if (isAccountCommentAuthor && isAccountMod) {
if (shouldPublishAuthorEdit && isAccountMod) {
await publishAuthorEdit();
await publishCommentModeration();
} else if (isAccountCommentAuthor) {
} else if (shouldPublishAuthorEdit) {
await publishAuthorEdit();
} else if (isAccountMod) {
await publishCommentModeration();
@@ -273,7 +296,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
<input
type='checkbox'
onChange={() => {
if (cid && (isAccountCommentAuthor || isAccountMod)) {
if (cid && canOpenEditMenu) {
if (!isEditMenuOpen) {
resetMenuState();
setIsEditMenuOpen(true);
@@ -288,12 +311,12 @@ const EditMenu = ({ post }: { post: Comment }) => {
checked={isEditMenuOpen}
/>
</span>
{isEditMenuOpen && (isAccountCommentAuthor || isAccountMod) && (
{isEditMenuOpen && canOpenEditMenu && (
<FloatingPortal>
<FloatingFocusManager context={context} modal={false}>
<div className={styles.modal} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
<div className={styles.editMenu}>
{isAccountCommentAuthor && (
{canAttemptAuthorDelete && (
<>
<div className={styles.menuItem}>
<label>
@@ -302,6 +325,10 @@ const EditMenu = ({ post }: { post: Comment }) => {
{capitalize(t('delete'))}?]
</label>
</div>
</>
)}
{isAccountCommentAuthor && (
<>
<div className={styles.menuItem}>
<label>
[
@@ -422,7 +449,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
/>
</div>
<div className={styles.bottom}>
<button className={isMobile ? 'button' : ''} onClick={_publishCommentEdit}>
<button className={isMobile ? 'button' : ''} onClick={_publishCommentEdit} disabled={!canSave}>
{t('save')}
</button>
</div>