refactor: rename mod menu to edit menu, add author edit

This commit is contained in:
Tom (plebeius.eth)
2024-06-03 21:32:00 +02:00
parent 6f003f9c11
commit b260fa35bf
5 changed files with 88 additions and 63 deletions
@@ -2,19 +2,21 @@ import { useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { autoUpdate, flip, FloatingFocusManager, offset, shift, useClick, useDismiss, useFloating, useId, useInteractions, useRole } from '@floating-ui/react';
import { PublishCommentEditOptions, useComment, useEditedComment, usePublishCommentEdit } from '@plebbit/plebbit-react-hooks';
import styles from './mod-menu.module.css';
import styles from './edit-menu.module.css';
import { alertChallengeVerificationFailed } from '../../../lib/utils/challenge-utils';
import useChallengesStore from '../../../stores/use-challenges-store';
import _ from 'lodash';
const { addChallenge } = useChallengesStore.getState();
type ModMenuProps = {
type EditMenuProps = {
cid: string;
isAccountMod?: boolean;
isAccountCommentAuthor?: boolean;
isCommentAuthorMod?: boolean;
};
const ModMenu = ({ cid, isCommentAuthorMod }: ModMenuProps) => {
const EditMenu = ({ cid, isAccountMod, isAccountCommentAuthor, isCommentAuthorMod }: EditMenuProps) => {
const { t } = useTranslation();
let post: any;
@@ -26,9 +28,10 @@ const ModMenu = ({ cid, isCommentAuthorMod }: ModMenuProps) => {
post = comment;
}
const isReply = post?.parentCid;
const [isModMenuOpen, setIsModMenuOpen] = useState(false);
const [isEditMenuOpen, setIsEditMenuOpen] = useState(false);
const defaultPublishOptions: PublishCommentEditOptions = {
deleted: post?.deleted,
removed: post?.removed,
locked: post?.locked,
spoiler: post?.spoiler,
@@ -81,8 +84,8 @@ const ModMenu = ({ cid, isCommentAuthorMod }: ModMenuProps) => {
const { refs, floatingStyles, context } = useFloating({
placement: 'bottom-start',
open: isModMenuOpen,
onOpenChange: setIsModMenuOpen,
open: isEditMenuOpen,
onOpenChange: setIsEditMenuOpen,
middleware: [offset(2), flip({ fallbackAxisSideDirection: 'end' }), shift()],
whileElementsMounted: autoUpdate,
});
@@ -97,65 +100,82 @@ const ModMenu = ({ cid, isCommentAuthorMod }: ModMenuProps) => {
const handleSaveClick = async () => {
await publishCommentEdit();
setIsModMenuOpen(false);
setIsEditMenuOpen(false);
};
return (
<>
<span className={styles.checkbox} ref={refs.setReference} {...(cid && getReferenceProps())}>
<input type='checkbox' onChange={() => cid && setIsModMenuOpen(!isModMenuOpen)} checked={isModMenuOpen} />
<input type='checkbox' onChange={() => cid && setIsEditMenuOpen(!isEditMenuOpen)} checked={isEditMenuOpen} />
</span>
{isModMenuOpen && (
{isEditMenuOpen && (isAccountCommentAuthor || isAccountMod) && (
<FloatingFocusManager context={context} modal={false}>
<div className={styles.modal} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
<div className={styles.ModMenu}>
<div className={styles.menuItem}>
<label>
[
<input onChange={onCheckbox} checked={publishCommentEditOptions.removed} type='checkbox' id='removed' />
{_.capitalize(t('remove'))}? ]
</label>
</div>
{!isReply && (
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={publishCommentEditOptions.locked} type='checkbox' id='locked' />
{_.capitalize(t('close_thread'))}?
</label>
]
</div>
<div className={styles.editMenu}>
{isAccountCommentAuthor && (
<>
<div className={styles.menuItem}>
<label>
[
<input onChange={onCheckbox} checked={publishCommentEditOptions.deleted} type='checkbox' id='deleted' />
{_.capitalize(t('delete'))}? ]
</label>
</div>
</>
)}
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={publishCommentEditOptions.spoiler} type='checkbox' id='spoiler' />
{_.capitalize(t('spoiler'))}?
</label>
]
</div>
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={publishCommentEditOptions.pinned} type='checkbox' id='pinned' />
{_.capitalize(t('sticky'))}?
</label>
]
</div>
{!isCommentAuthorMod && (
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={!!publishCommentEditOptions.commentAuthor?.banExpiresAt} type='checkbox' id='banUser' />
<Trans
i18nKey='ban_user_for'
shouldUnescape={true}
components={{ 1: <input className={styles.banInput} onChange={onBanDurationChange} type='number' min={1} max={100} defaultValue={banDuration} /> }}
/>
?
</label>
]
</div>
{isAccountMod && (
<>
<div className={styles.menuItem}>
<label>
[
<input onChange={onCheckbox} checked={publishCommentEditOptions.removed} type='checkbox' id='removed' />
{_.capitalize(t('remove'))}? ]
</label>
</div>
{!isReply && (
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={publishCommentEditOptions.locked} type='checkbox' id='locked' />
{_.capitalize(t('close_thread'))}?
</label>
]
</div>
)}
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={publishCommentEditOptions.spoiler} type='checkbox' id='spoiler' />
{_.capitalize(t('spoiler'))}?
</label>
]
</div>
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={publishCommentEditOptions.pinned} type='checkbox' id='pinned' />
{_.capitalize(t('sticky'))}?
</label>
]
</div>
{!isCommentAuthorMod && (
<div className={styles.menuItem}>
[
<label>
<input onChange={onCheckbox} checked={!!publishCommentEditOptions.commentAuthor?.banExpiresAt} type='checkbox' id='banUser' />
<Trans
i18nKey='ban_user_for'
shouldUnescape={true}
components={{
1: <input className={styles.banInput} onChange={onBanDurationChange} type='number' min={1} max={100} defaultValue={banDuration} />,
}}
/>
?
</label>
]
</div>
)}
</>
)}
<div className={`${styles.menuItem} ${styles.menuReason}`}>
{_.capitalize(t('reason'))}?
@@ -172,4 +192,4 @@ const ModMenu = ({ cid, isCommentAuthorMod }: ModMenuProps) => {
);
};
export default ModMenu;
export default EditMenu;
+1
View File
@@ -0,0 +1 @@
export { default } from './edit-menu';
-1
View File
@@ -1 +0,0 @@
export { default } from './mod-menu';
@@ -2,7 +2,7 @@ import { useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { useLocation, useParams } from 'react-router-dom';
import { Link } from 'react-router-dom';
import { useAccount, useBlock, useEditedComment } from '@plebbit/plebbit-react-hooks';
import { useAccount, useBlock, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
import styles from '../post.module.css';
import { getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../../lib/utils/media-utils';
@@ -17,9 +17,9 @@ import { canEmbed } from '../../embed';
import LoadingEllipsis from '../../loading-ellipsis';
import Markdown from '../../markdown';
import PostMenuDesktop from './post-menu-desktop/';
import EditMenu from '../edit-menu/edit-menu';
import { PostProps } from '../post';
import _ from 'lodash';
import ModMenu from '../mod-menu';
const PostInfo = ({ openReplyModal, post, roles, isHidden }: PostProps) => {
const { t } = useTranslation();
@@ -39,13 +39,18 @@ const PostInfo = ({ openReplyModal, post, roles, isHidden }: PostProps) => {
const authorRole = roles?.[address]?.role;
const displayTitle = title && title.length > 75 ? title?.slice(0, 75) + '...' : title;
// pending reply by account is not yet published
const account = useAccount();
const accountShortAddress = account?.author?.shortAddress;
const accountShortAddress = account?.author?.shortAddress; // if reply by account is pending, it doesn't have an author yet
const subplebbit = useSubplebbit({ subplebbitAddress });
const commentAuthorRole = subplebbit?.roles?.[author?.address]?.role;
const isCommentAuthorMod = commentAuthorRole === 'admin' || commentAuthorRole === 'owner' || commentAuthorRole === 'moderator';
const accountAuthorRole = subplebbit?.roles?.[account?.author?.address]?.role;
const isAccountMod = accountAuthorRole === 'admin' || accountAuthorRole === 'owner' || accountAuthorRole === 'moderator';
const isAccountCommentAuthor = account?.author?.address === author?.address;
return (
<div className={styles.postInfo}>
{!isHidden && <ModMenu cid={cid} />}
{!isHidden && <EditMenu cid={cid} isAccountCommentAuthor={isAccountCommentAuthor} isAccountMod={isAccountMod} isCommentAuthorMod={isCommentAuthorMod} />}
{title && <span className={styles.subject}>{displayTitle} </span>}
<span className={styles.nameBlock}>
<span className={`${styles.name} ${(isDescription || isRules || authorRole) && styles.capcodeMod}`}>