mirror of
https://github.com/plebbit/seedit.git
synced 2026-04-21 15:48:43 -04:00
refactor(comment tools): move mod tools out
This commit is contained in:
@@ -54,38 +54,6 @@
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.modal {
|
||||
z-index: 7;
|
||||
background-color: var(--background);
|
||||
padding: 5px;
|
||||
color: var(--text-info);
|
||||
font-weight: bold;
|
||||
border: 1px solid var(--border-text);
|
||||
}
|
||||
|
||||
.modal input {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
padding-bottom: 5px;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
.menuReason {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.menuItem input[type="text"] {
|
||||
padding: 2px;
|
||||
box-shadow: var(--box-shadow);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.menuItem button {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-weight: normal !important;
|
||||
color: var(--text) !important;
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PublishCommentEditOptions, useAccount, useComment, usePublishCommentEdit, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||
import { autoUpdate, flip, FloatingFocusManager, offset, shift, useClick, useDismiss, useFloating, useId, useInteractions, useRole } from '@floating-ui/react';
|
||||
import { useAccount, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||
import styles from './comment-tools.module.css';
|
||||
import { FailedLabel, PendingLabel, SpoilerLabel } from '../label';
|
||||
import challengesStore from '../../../hooks/use-challenges';
|
||||
import { alertChallengeVerificationFailed } from '../../../lib/utils/challenge-utils';
|
||||
import { getShareLink } from '../../../lib/utils/url-utils';
|
||||
|
||||
const { addChallenge } = challengesStore.getState();
|
||||
import ModTools from './mod-tools';
|
||||
|
||||
interface CommentToolsProps {
|
||||
cid: string;
|
||||
@@ -22,102 +18,6 @@ interface CommentToolsProps {
|
||||
showReplyForm?: () => void;
|
||||
}
|
||||
|
||||
const ModTools = ({ cid }: CommentToolsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const post = useComment({ commentCid: cid });
|
||||
const [isModToolsOpen, setIsModToolsOpen] = useState(false);
|
||||
|
||||
const defaultPublishOptions: PublishCommentEditOptions = {
|
||||
removed: post?.removed,
|
||||
locked: post?.locked,
|
||||
spoiler: post?.spoiler,
|
||||
pinned: post?.pinned,
|
||||
commentCid: post?.cid,
|
||||
subplebbitAddress: post?.subplebbitAddress,
|
||||
onChallenge: (...args: any) => addChallenge([...args, post]),
|
||||
onChallengeVerification: alertChallengeVerificationFailed,
|
||||
onError: (error: Error) => {
|
||||
console.warn(error);
|
||||
alert(error.message);
|
||||
},
|
||||
};
|
||||
|
||||
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState(defaultPublishOptions);
|
||||
const { state, publishCommentEdit } = usePublishCommentEdit(publishCommentEditOptions);
|
||||
|
||||
// close the modal after publishing
|
||||
useEffect(() => {
|
||||
if (state && state !== 'failed' && state !== 'initializing' && state !== 'ready') {
|
||||
setIsModToolsOpen(false);
|
||||
}
|
||||
}, [state, setIsModToolsOpen]);
|
||||
|
||||
const onCheckbox = (e: React.ChangeEvent<HTMLInputElement>) => setPublishCommentEditOptions((state) => ({ ...state, [e.target.id]: e.target.checked }));
|
||||
|
||||
const onReason = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setPublishCommentEditOptions((state) => ({ ...state, reason: e.target.value ? e.target.value : undefined }));
|
||||
|
||||
const { refs, floatingStyles, context } = useFloating({
|
||||
placement: 'bottom-start',
|
||||
open: isModToolsOpen,
|
||||
onOpenChange: setIsModToolsOpen,
|
||||
middleware: [offset(2), flip({ fallbackAxisSideDirection: 'end' }), shift()],
|
||||
whileElementsMounted: autoUpdate,
|
||||
});
|
||||
|
||||
const click = useClick(context);
|
||||
const dismiss = useDismiss(context);
|
||||
const role = useRole(context);
|
||||
|
||||
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss, role]);
|
||||
|
||||
const headingId = useId();
|
||||
|
||||
return (
|
||||
<>
|
||||
<li className={styles.button} ref={refs.setReference} {...getReferenceProps()}>
|
||||
<span onClick={() => setIsModToolsOpen(!isModToolsOpen)}>{t('moderation')}</span>
|
||||
</li>
|
||||
{isModToolsOpen && (
|
||||
<FloatingFocusManager context={context} modal={false}>
|
||||
<div className={styles.modal} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
|
||||
<div className={styles.modTools}>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.removed} type='checkbox' id='removed' />
|
||||
{t('removed')}
|
||||
</label>
|
||||
</div>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.locked} type='checkbox' id='locked' />
|
||||
locked
|
||||
</label>
|
||||
</div>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.spoiler} type='checkbox' id='spoiler' />
|
||||
{t('spoiler')}
|
||||
</label>
|
||||
</div>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.pinned} type='checkbox' id='pinned' />
|
||||
{t('announcement')}
|
||||
</label>
|
||||
</div>
|
||||
<div className={`${styles.menuItem} ${styles.menuReason}`}>
|
||||
<input type='text' onChange={onReason} defaultValue={post?.reason} size={14} placeholder='reason' />
|
||||
<button onClick={publishCommentEdit}>{t('edit')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FloatingFocusManager>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const PostTools = ({ cid, hasLabel, subplebbitAddress, replyCount = 0 }: CommentToolsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const validReplyCount = isNaN(replyCount) ? 0 : replyCount;
|
||||
@@ -208,7 +108,7 @@ const CommentTools = ({ cid, failed, hasLabel = false, isReply, replyCount, spoi
|
||||
) : (
|
||||
<PostTools cid={cid} hasLabel={hasLabel} subplebbitAddress={subplebbitAddress} replyCount={replyCount} />
|
||||
)}
|
||||
{isMod && <ModTools cid={cid} subplebbitAddress={subplebbitAddress} />}
|
||||
{isMod && <ModTools cid={cid} />}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
1
src/components/post/comment-tools/mod-tools/index.ts
Normal file
1
src/components/post/comment-tools/mod-tools/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export {default} from './mod-tools';
|
||||
@@ -0,0 +1,39 @@
|
||||
.button {
|
||||
color: var(--text-info);
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
padding: 0 4px 0 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal {
|
||||
z-index: 7;
|
||||
background-color: var(--background);
|
||||
padding: 5px;
|
||||
color: var(--text-info);
|
||||
font-weight: bold;
|
||||
border: 1px solid var(--border-text);
|
||||
}
|
||||
|
||||
.modal input {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
padding-bottom: 5px;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
.menuReason {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.menuItem input[type="text"] {
|
||||
padding: 2px;
|
||||
box-shadow: var(--box-shadow);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.menuItem button {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
111
src/components/post/comment-tools/mod-tools/mod-tools.tsx
Normal file
111
src/components/post/comment-tools/mod-tools/mod-tools.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { autoUpdate, flip, FloatingFocusManager, offset, shift, useClick, useDismiss, useFloating, useId, useInteractions, useRole } from '@floating-ui/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PublishCommentEditOptions, useComment, usePublishCommentEdit } from '@plebbit/plebbit-react-hooks';
|
||||
import styles from './mod-tools.module.css';
|
||||
import { alertChallengeVerificationFailed } from '../../../../lib/utils/challenge-utils';
|
||||
import challengesStore from '../../../../hooks/use-challenges';
|
||||
|
||||
const { addChallenge } = challengesStore.getState();
|
||||
|
||||
type ModToolsProps = {
|
||||
cid: string;
|
||||
};
|
||||
|
||||
const ModTools = ({cid}: ModToolsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const post = useComment({ commentCid: cid });
|
||||
const [isModToolsOpen, setIsModToolsOpen] = useState(false);
|
||||
|
||||
const defaultPublishOptions: PublishCommentEditOptions = {
|
||||
removed: post?.removed,
|
||||
locked: post?.locked,
|
||||
spoiler: post?.spoiler,
|
||||
pinned: post?.pinned,
|
||||
commentCid: post?.cid,
|
||||
subplebbitAddress: post?.subplebbitAddress,
|
||||
onChallenge: (...args: any) => addChallenge([...args, post]),
|
||||
onChallengeVerification: alertChallengeVerificationFailed,
|
||||
onError: (error: Error) => {
|
||||
console.warn(error);
|
||||
alert(error.message);
|
||||
},
|
||||
};
|
||||
|
||||
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState(defaultPublishOptions);
|
||||
const { state, publishCommentEdit } = usePublishCommentEdit(publishCommentEditOptions);
|
||||
|
||||
// close the modal after publishing
|
||||
useEffect(() => {
|
||||
if (state && state !== 'failed' && state !== 'initializing' && state !== 'ready') {
|
||||
setIsModToolsOpen(false);
|
||||
}
|
||||
}, [state, setIsModToolsOpen]);
|
||||
|
||||
const onCheckbox = (e: React.ChangeEvent<HTMLInputElement>) => setPublishCommentEditOptions((state) => ({ ...state, [e.target.id]: e.target.checked }));
|
||||
|
||||
const onReason = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setPublishCommentEditOptions((state) => ({ ...state, reason: e.target.value ? e.target.value : undefined }));
|
||||
|
||||
const { refs, floatingStyles, context } = useFloating({
|
||||
placement: 'bottom-start',
|
||||
open: isModToolsOpen,
|
||||
onOpenChange: setIsModToolsOpen,
|
||||
middleware: [offset(2), flip({ fallbackAxisSideDirection: 'end' }), shift()],
|
||||
whileElementsMounted: autoUpdate,
|
||||
});
|
||||
|
||||
const click = useClick(context);
|
||||
const dismiss = useDismiss(context);
|
||||
const role = useRole(context);
|
||||
|
||||
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss, role]);
|
||||
|
||||
const headingId = useId();
|
||||
|
||||
return (
|
||||
<>
|
||||
<li className={styles.button} ref={refs.setReference} {...getReferenceProps()}>
|
||||
<span onClick={() => setIsModToolsOpen(!isModToolsOpen)}>{t('moderation')}</span>
|
||||
</li>
|
||||
{isModToolsOpen && (
|
||||
<FloatingFocusManager context={context} modal={false}>
|
||||
<div className={styles.modal} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
|
||||
<div className={styles.modTools}>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.removed} type='checkbox' id='removed' />
|
||||
{t('removed')}
|
||||
</label>
|
||||
</div>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.locked} type='checkbox' id='locked' />
|
||||
locked
|
||||
</label>
|
||||
</div>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.spoiler} type='checkbox' id='spoiler' />
|
||||
{t('spoiler')}
|
||||
</label>
|
||||
</div>
|
||||
<div className={styles.menuItem}>
|
||||
<label>
|
||||
<input onChange={onCheckbox} checked={publishCommentEditOptions.pinned} type='checkbox' id='pinned' />
|
||||
{t('announcement')}
|
||||
</label>
|
||||
</div>
|
||||
<div className={`${styles.menuItem} ${styles.menuReason}`}>
|
||||
<input type='text' onChange={onReason} defaultValue={post?.reason} size={14} placeholder='reason' />
|
||||
<button onClick={publishCommentEdit}>{t('edit')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FloatingFocusManager>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModTools;
|
||||
Reference in New Issue
Block a user