mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
enable editing comments published in anon mode
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useState, useMemo, useCallback } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { autoUpdate, FloatingFocusManager, offset, shift, useClick, useDismiss, useFloating, useId, useInteractions, useRole } from '@floating-ui/react';
|
||||
import { Comment, PublishCommentEditOptions, usePublishCommentEdit } from '@plebbit/plebbit-react-hooks';
|
||||
import { Comment, PublishCommentEditOptions, useAccount, usePublishCommentEdit } from '@plebbit/plebbit-react-hooks';
|
||||
import styles from './edit-menu.module.css';
|
||||
import { alertChallengeVerificationFailed } from '../../lib/utils/challenge-utils';
|
||||
import useChallengesStore from '../../stores/use-challenges-store';
|
||||
import _ from 'lodash';
|
||||
import useIsMobile from '../../hooks/use-is-mobile';
|
||||
import useAnonMode from '../../hooks/use-anon-mode';
|
||||
|
||||
const { addChallenge } = useChallengesStore.getState();
|
||||
|
||||
@@ -31,33 +32,66 @@ const timestampToDays = (timestamp: number) => {
|
||||
const EditMenu = ({ isAccountMod, isAccountCommentAuthor, isCommentAuthorMod, post }: EditMenuProps) => {
|
||||
const { t } = useTranslation();
|
||||
const isMobile = useIsMobile();
|
||||
const { cid, commentAuthor, content, deleted, locked, parentCid, pinned, reason, removed, spoiler, subplebbitAddress } = post || {};
|
||||
const { author, cid, commentAuthor, content, deleted, locked, parentCid, pinned, reason, removed, spoiler, subplebbitAddress } = post || {};
|
||||
const isReply = parentCid;
|
||||
const [isEditMenuOpen, setIsEditMenuOpen] = useState(false);
|
||||
const [isContentEditorOpen, setIsContentEditorOpen] = useState(false);
|
||||
|
||||
const defaultPublishEditOptions: PublishCommentEditOptions = {
|
||||
commentAuthor: isAccountMod && !isAccountCommentAuthor ? commentAuthor : undefined,
|
||||
commentCid: cid,
|
||||
content: isAccountCommentAuthor ? content : undefined,
|
||||
deleted: isAccountCommentAuthor ? deleted : undefined,
|
||||
locked: isAccountMod ? locked : undefined,
|
||||
pinned: isAccountMod ? pinned : undefined,
|
||||
reason,
|
||||
removed: isAccountMod ? removed : undefined,
|
||||
spoiler,
|
||||
subplebbitAddress,
|
||||
onChallenge: (...args: any) => addChallenge([...args, post]),
|
||||
onChallengeVerification: alertChallengeVerificationFailed,
|
||||
onError: (error: Error) => {
|
||||
console.warn(error);
|
||||
alert('Comment edit failed. ' + error.message);
|
||||
},
|
||||
};
|
||||
const { getExistingSigner } = useAnonMode(post?.postCid);
|
||||
|
||||
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState(defaultPublishEditOptions);
|
||||
const account = useAccount();
|
||||
const [signer, setSigner] = useState<any>(account?.signer);
|
||||
|
||||
const checkSigner = useCallback(async () => {
|
||||
if (isAccountCommentAuthor && post?.author?.address !== account?.author?.address) {
|
||||
const existingSigner = getExistingSigner(post?.author?.address);
|
||||
if (existingSigner) {
|
||||
setSigner(existingSigner);
|
||||
}
|
||||
} else {
|
||||
setSigner(null);
|
||||
}
|
||||
}, [isAccountCommentAuthor, post?.author?.address, getExistingSigner, account?.author?.address]);
|
||||
|
||||
useEffect(() => {
|
||||
checkSigner();
|
||||
}, [checkSigner]);
|
||||
|
||||
const defaultPublishEditOptions = useMemo(() => {
|
||||
return {
|
||||
commentAuthor: isAccountMod && !isAccountCommentAuthor ? commentAuthor : undefined,
|
||||
commentCid: cid,
|
||||
content: isAccountCommentAuthor ? content : undefined,
|
||||
deleted: isAccountCommentAuthor ? deleted ?? false : undefined,
|
||||
locked: isAccountMod ? locked ?? false : undefined,
|
||||
pinned: isAccountMod ? pinned ?? false : undefined,
|
||||
reason,
|
||||
removed: isAccountMod ? removed ?? false : undefined,
|
||||
spoiler: spoiler ?? false,
|
||||
subplebbitAddress,
|
||||
signer: signer,
|
||||
author: signer
|
||||
? {
|
||||
address: signer.address,
|
||||
displayName: post?.author?.displayName,
|
||||
}
|
||||
: author,
|
||||
onChallenge: (...args: any) => addChallenge([...args, post]),
|
||||
onChallengeVerification: alertChallengeVerificationFailed,
|
||||
onError: (error: Error) => {
|
||||
console.warn(error);
|
||||
alert('Comment edit failed. ' + error.message);
|
||||
},
|
||||
};
|
||||
}, [isAccountMod, isAccountCommentAuthor, commentAuthor, cid, content, deleted, locked, pinned, reason, removed, spoiler, subplebbitAddress, signer, post]);
|
||||
|
||||
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState<PublishCommentEditOptions>(defaultPublishEditOptions);
|
||||
const { publishCommentEdit } = usePublishCommentEdit(publishCommentEditOptions);
|
||||
|
||||
useEffect(() => {
|
||||
setPublishCommentEditOptions(defaultPublishEditOptions);
|
||||
}, [defaultPublishEditOptions]);
|
||||
|
||||
const [banDuration, setBanDuration] = useState(() =>
|
||||
publishCommentEditOptions.commentAuthor?.banExpiresAt ? timestampToDays(publishCommentEditOptions.commentAuthor.banExpiresAt) : 1,
|
||||
);
|
||||
@@ -101,13 +135,6 @@ const EditMenu = ({ isAccountMod, isAccountCommentAuthor, isCommentAuthorMod, po
|
||||
|
||||
const headingId = useId();
|
||||
|
||||
useEffect(() => {
|
||||
setPublishCommentEditOptions((prevOptions) => ({
|
||||
...prevOptions,
|
||||
commentCid: cid,
|
||||
}));
|
||||
}, [cid]);
|
||||
|
||||
const _publishCommentEdit = async () => {
|
||||
try {
|
||||
await publishCommentEdit();
|
||||
@@ -161,7 +188,7 @@ const EditMenu = ({ isAccountMod, isAccountCommentAuthor, isCommentAuthorMod, po
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
[
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.removed} type='checkbox' id='removed' />
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.removed ?? false} type='checkbox' id='removed' />
|
||||
{_.capitalize(t('remove'))}?]
|
||||
</label>
|
||||
</div>
|
||||
@@ -169,7 +196,7 @@ const EditMenu = ({ isAccountMod, isAccountCommentAuthor, isCommentAuthorMod, po
|
||||
<div className={styles.menuItem}>
|
||||
[
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.locked} type='checkbox' id='locked' />
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.locked ?? false} type='checkbox' id='locked' />
|
||||
{_.capitalize(t('close_thread'))}?
|
||||
</label>
|
||||
]
|
||||
@@ -178,7 +205,7 @@ const EditMenu = ({ isAccountMod, isAccountCommentAuthor, isCommentAuthorMod, po
|
||||
<div className={styles.menuItem}>
|
||||
[
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.spoiler} type='checkbox' id='spoiler' />
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.spoiler ?? false} type='checkbox' id='spoiler' />
|
||||
{_.capitalize(t('spoiler'))}?
|
||||
</label>
|
||||
]
|
||||
@@ -186,7 +213,7 @@ const EditMenu = ({ isAccountMod, isAccountCommentAuthor, isCommentAuthorMod, po
|
||||
<div className={styles.menuItem}>
|
||||
[
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.pinned} type='checkbox' id='pinned' />
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.pinned ?? false} type='checkbox' id='pinned' />
|
||||
{_.capitalize(t('sticky'))}?
|
||||
</label>
|
||||
]
|
||||
|
||||
+14
-10
@@ -1,5 +1,6 @@
|
||||
import { useAccount } from '@plebbit/plebbit-react-hooks';
|
||||
import useAnonModeStore from '../stores/use-anon-mode-store';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
const useAnonMode = (postCid?: string) => {
|
||||
const { anonMode, threadSigners, setThreadSigner, setAddressSigner, getAddressSigner, setCurrentAnonSignerAddress } = useAnonModeStore((state) => ({
|
||||
@@ -11,11 +12,11 @@ const useAnonMode = (postCid?: string) => {
|
||||
setCurrentAnonSignerAddress: state.setCurrentAnonSignerAddress,
|
||||
}));
|
||||
|
||||
const threadSigner = postCid ? threadSigners[postCid] : undefined;
|
||||
const threadSigner = useMemo(() => (postCid ? threadSigners[postCid] : undefined), [postCid, threadSigners]);
|
||||
|
||||
const account = useAccount();
|
||||
|
||||
const getNewSigner = async () => {
|
||||
const getNewSigner = useCallback(async () => {
|
||||
if (anonMode) {
|
||||
if (!postCid || !threadSigner) {
|
||||
try {
|
||||
@@ -43,15 +44,18 @@ const useAnonMode = (postCid?: string) => {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}, [anonMode, postCid, threadSigner, account, setThreadSigner, setAddressSigner, setCurrentAnonSignerAddress]);
|
||||
|
||||
const getExistingSigner = (address: string) => {
|
||||
const signer = getAddressSigner(address);
|
||||
if (signer) {
|
||||
setCurrentAnonSignerAddress(signer.address);
|
||||
}
|
||||
return signer;
|
||||
};
|
||||
const getExistingSigner = useCallback(
|
||||
(address: string) => {
|
||||
const signer = getAddressSigner(address);
|
||||
if (signer) {
|
||||
setCurrentAnonSignerAddress(signer.address);
|
||||
}
|
||||
return signer;
|
||||
},
|
||||
[getAddressSigner, setCurrentAnonSignerAddress],
|
||||
);
|
||||
|
||||
return { anonMode, getNewSigner, getExistingSigner };
|
||||
};
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useAccount, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||
import useAnonModeStore from '../stores/use-anon-mode-store';
|
||||
|
||||
interface AuthorPrivilegesProps {
|
||||
commentAuthorAddress: string;
|
||||
@@ -8,12 +10,23 @@ interface AuthorPrivilegesProps {
|
||||
const useAuthorPrivileges = ({ commentAuthorAddress, subplebbitAddress }: AuthorPrivilegesProps) => {
|
||||
const accountAuthorAddress = useAccount()?.author?.address;
|
||||
const { roles } = useSubplebbit({ subplebbitAddress }) || {};
|
||||
const { getAddressSigner } = useAnonModeStore();
|
||||
|
||||
const commentAuthorRole = roles?.[commentAuthorAddress]?.role;
|
||||
const isCommentAuthorMod = commentAuthorRole === 'admin' || commentAuthorRole === 'owner' || commentAuthorRole === 'moderator';
|
||||
const accountAuthorRole = roles?.[accountAuthorAddress]?.role;
|
||||
const isAccountMod = accountAuthorRole === 'admin' || accountAuthorRole === 'owner' || accountAuthorRole === 'moderator';
|
||||
const isAccountCommentAuthor = accountAuthorAddress === commentAuthorAddress;
|
||||
const { isCommentAuthorMod, isAccountMod, isAccountCommentAuthor, commentAuthorRole, accountAuthorRole } = useMemo(() => {
|
||||
const commentAuthorRole = roles?.[commentAuthorAddress]?.role;
|
||||
const isCommentAuthorMod = commentAuthorRole === 'admin' || commentAuthorRole === 'owner' || commentAuthorRole === 'moderator';
|
||||
const accountAuthorRole = roles?.[accountAuthorAddress]?.role;
|
||||
const isAccountMod = accountAuthorRole === 'admin' || accountAuthorRole === 'owner' || accountAuthorRole === 'moderator';
|
||||
|
||||
let isAccountCommentAuthor = accountAuthorAddress === commentAuthorAddress;
|
||||
|
||||
if (!isAccountCommentAuthor) {
|
||||
const existingSigner = getAddressSigner(commentAuthorAddress);
|
||||
isAccountCommentAuthor = !!existingSigner;
|
||||
}
|
||||
|
||||
return { isCommentAuthorMod, isAccountMod, isAccountCommentAuthor, commentAuthorRole, accountAuthorRole };
|
||||
}, [roles, commentAuthorAddress, accountAuthorAddress, getAddressSigner]);
|
||||
|
||||
return { isCommentAuthorMod, isAccountMod, isAccountCommentAuthor, commentAuthorRole, accountAuthorRole };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user