mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
add functionality to moderation modal
This commit is contained in:
@@ -1,16 +1,139 @@
|
|||||||
import React from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Modal from "react-modal";
|
import Modal from "react-modal";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { usePublishCommentEdit } from "@plebbit/plebbit-react-hooks";
|
||||||
import { StyledModal } from "./styled/ModerationModal.styled";
|
import { StyledModal } from "./styled/ModerationModal.styled";
|
||||||
import useGeneralStore from "../hooks/stores/useGeneralStore";
|
import useGeneralStore from "../hooks/stores/useGeneralStore";
|
||||||
|
import useError from "../hooks/useError";
|
||||||
|
import useSuccess from "../hooks/useSuccess";
|
||||||
|
|
||||||
|
|
||||||
const ModerationModal = ({ isOpen, closeModal }) => {
|
const ModerationModal = ({ isOpen, closeModal }) => {
|
||||||
const selectedStyle = useGeneralStore(state => state.selectedStyle);
|
const {
|
||||||
|
selectedAddress,
|
||||||
|
selectedStyle,
|
||||||
|
setCaptchaResponse,
|
||||||
|
setChallengesArray,
|
||||||
|
setIsCaptchaOpen,
|
||||||
|
moderatingCommentCid,
|
||||||
|
setResolveCaptchaPromise,
|
||||||
|
} = useGeneralStore(state => state);
|
||||||
|
|
||||||
|
const [pin, setPin] = useState(false);
|
||||||
|
const [deleteThread, setDeleteThread] = useState(false);
|
||||||
|
const [close, setClose] = useState(false);
|
||||||
|
const [reason, setReason] = useState('');
|
||||||
|
const [triggerPublishCommentEdit, setTriggerPublishCommentEdit] = useState(false);
|
||||||
|
|
||||||
|
const [errorMessage, setErrorMessage] = useState(null);
|
||||||
|
const [successMessage, setSuccessMessage] = useState(null);
|
||||||
|
useError(errorMessage, [errorMessage]);
|
||||||
|
useSuccess(successMessage, [successMessage]);
|
||||||
|
|
||||||
const handleCloseModal = () => {
|
const handleCloseModal = () => {
|
||||||
closeModal();
|
closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const onChallengeVerification = (challengeVerification) => {
|
||||||
|
if (challengeVerification.challengeSuccess === true) {
|
||||||
|
setSuccessMessage('Challenge Success');
|
||||||
|
} else if (challengeVerification.challengeSuccess === false) {
|
||||||
|
setErrorMessage('Challenge Failed', {reason: challengeVerification.reason, errors: challengeVerification.errors});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const onChallenge = async (challenges, comment) => {
|
||||||
|
|
||||||
|
let challengeAnswers = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
challengeAnswers = await getChallengeAnswersFromUser(challenges)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
setErrorMessage(error);
|
||||||
|
}
|
||||||
|
if (challengeAnswers) {
|
||||||
|
await comment.publishChallengeAnswers(challengeAnswers)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const getChallengeAnswersFromUser = async (challenges) => {
|
||||||
|
setChallengesArray(challenges);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const imageString = challenges?.challenges[0].challenge;
|
||||||
|
const imageSource = `data:image/png;base64,${imageString}`;
|
||||||
|
const challengeImg = new Image();
|
||||||
|
challengeImg.src = imageSource;
|
||||||
|
|
||||||
|
challengeImg.onload = () => {
|
||||||
|
setIsCaptchaOpen(true);
|
||||||
|
|
||||||
|
const handleKeyDown = async (event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
const currentCaptchaResponse = useGeneralStore.getState().captchaResponse;
|
||||||
|
resolve(currentCaptchaResponse);
|
||||||
|
setIsCaptchaOpen(false);
|
||||||
|
document.removeEventListener('keydown', handleKeyDown);
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setCaptchaResponse('');
|
||||||
|
document.addEventListener('keydown', handleKeyDown);
|
||||||
|
|
||||||
|
setResolveCaptchaPromise(resolve);
|
||||||
|
};
|
||||||
|
|
||||||
|
challengeImg.onerror = () => {
|
||||||
|
reject(setErrorMessage('Could not load challenges'));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState({
|
||||||
|
commentCid: moderatingCommentCid,
|
||||||
|
subplebbitAddress: selectedAddress,
|
||||||
|
onChallenge,
|
||||||
|
onChallengeVerification,
|
||||||
|
onError: (error) => {
|
||||||
|
setErrorMessage(error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const {error, publishCommentEdit } = usePublishCommentEdit(publishCommentEditOptions);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (error) {
|
||||||
|
setErrorMessage(error);
|
||||||
|
}
|
||||||
|
}, [error]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPublishCommentEditOptions((prevOptions) => ({
|
||||||
|
...prevOptions,
|
||||||
|
commentCid: moderatingCommentCid,
|
||||||
|
}));
|
||||||
|
}, [moderatingCommentCid]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
|
(async () => {
|
||||||
|
await publishCommentEdit();
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledModal
|
<StyledModal
|
||||||
@@ -29,7 +152,8 @@ const ModerationModal = ({ isOpen, closeModal }) => {
|
|||||||
</div>
|
</div>
|
||||||
<ul className="settings-cat">
|
<ul className="settings-cat">
|
||||||
<li className="settings-cat-lbl">
|
<li className="settings-cat-lbl">
|
||||||
<input type="checkbox" style={{marginRight: "10px"}} />
|
<input type="checkbox" style={{marginRight: "10px"}}
|
||||||
|
checked={pin} onChange={() => setPin(!pin)} />
|
||||||
Pin thread
|
Pin thread
|
||||||
</li>
|
</li>
|
||||||
<li className="settings-tip">
|
<li className="settings-tip">
|
||||||
@@ -38,7 +162,8 @@ const ModerationModal = ({ isOpen, closeModal }) => {
|
|||||||
</ul>
|
</ul>
|
||||||
<ul className="settings-cat">
|
<ul className="settings-cat">
|
||||||
<li className="settings-cat-lbl">
|
<li className="settings-cat-lbl">
|
||||||
<input type="checkbox" style={{marginRight: "10px"}} />
|
<input type="checkbox" style={{marginRight: "10px"}}
|
||||||
|
checked={deleteThread} onChange={() => setDeleteThread(!deleteThread)} />
|
||||||
Delete thread
|
Delete thread
|
||||||
</li>
|
</li>
|
||||||
<li className="settings-tip">
|
<li className="settings-tip">
|
||||||
@@ -47,7 +172,8 @@ const ModerationModal = ({ isOpen, closeModal }) => {
|
|||||||
</ul>
|
</ul>
|
||||||
<ul className="settings-cat">
|
<ul className="settings-cat">
|
||||||
<li className="settings-cat-lbl">
|
<li className="settings-cat-lbl">
|
||||||
<input type="checkbox" style={{marginRight: "10px"}} />
|
<input type="checkbox" style={{marginRight: "10px"}}
|
||||||
|
checked={close} onChange={() => setClose(!close)} />
|
||||||
Close thread
|
Close thread
|
||||||
</li>
|
</li>
|
||||||
<li className="settings-tip">
|
<li className="settings-tip">
|
||||||
@@ -62,17 +188,23 @@ const ModerationModal = ({ isOpen, closeModal }) => {
|
|||||||
Help people become better posters by giving a short reason why their post was removed.
|
Help people become better posters by giving a short reason why their post was removed.
|
||||||
</li>
|
</li>
|
||||||
<li className="settings-input" style={{marginTop: "-10px"}}>
|
<li className="settings-input" style={{marginTop: "-10px"}}>
|
||||||
<textarea placeholder="Enter reason here..." />
|
<textarea value={reason} placeholder="Enter reason here..."
|
||||||
|
onChange={e => setReason(e.target.value)}/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<button
|
<button
|
||||||
className="save-button"
|
className="save-button"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
// await deleteCaches();
|
setPublishCommentEditOptions(prevOptions => ({
|
||||||
// localStorage.setItem("cacheCleared", "true");
|
...prevOptions,
|
||||||
// window.location.reload();
|
pinned: pin,
|
||||||
}
|
removed: deleteThread,
|
||||||
}
|
locked: close,
|
||||||
|
reason: reason
|
||||||
|
}));
|
||||||
|
setTriggerPublishCommentEdit(true);
|
||||||
|
handleCloseModal();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ const Board = () => {
|
|||||||
setIsCaptchaOpen,
|
setIsCaptchaOpen,
|
||||||
isModerationOpen, setIsModerationOpen,
|
isModerationOpen, setIsModerationOpen,
|
||||||
isSettingsOpen, setIsSettingsOpen,
|
isSettingsOpen, setIsSettingsOpen,
|
||||||
|
setModeratingCommentCid,
|
||||||
setPendingComment,
|
setPendingComment,
|
||||||
setPendingCommentIndex,
|
setPendingCommentIndex,
|
||||||
setResolveCaptchaPromise,
|
setResolveCaptchaPromise,
|
||||||
@@ -68,6 +69,8 @@ const Board = () => {
|
|||||||
const { subscribed, subscribe, unsubscribe } = useSubscribe({subplebbitAddress: selectedAddress});
|
const { subscribed, subscribe, unsubscribe } = useSubscribe({subplebbitAddress: selectedAddress});
|
||||||
const stateString = useStateString(subplebbit);
|
const stateString = useStateString(subplebbit);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [isReplyOpen, setIsReplyOpen] = useState(false);
|
const [isReplyOpen, setIsReplyOpen] = useState(false);
|
||||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||||
const [visible, setVisible] = useState(true);
|
const [visible, setVisible] = useState(true);
|
||||||
@@ -865,6 +868,7 @@ const Board = () => {
|
|||||||
<ul className="dropdown-menu"
|
<ul className="dropdown-menu"
|
||||||
style={{display: isModToolsOpen ? 'block': 'none'}}>
|
style={{display: isModToolsOpen ? 'block': 'none'}}>
|
||||||
<li onClick={() => {
|
<li onClick={() => {
|
||||||
|
setModeratingCommentCid(thread.cid);
|
||||||
setIsModerationOpen(true);
|
setIsModerationOpen(true);
|
||||||
handleOptionClick(thread.cid);
|
handleOptionClick(thread.cid);
|
||||||
}}>
|
}}>
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ const useGeneralStore = create((set) => ({
|
|||||||
isSettingsOpen: false,
|
isSettingsOpen: false,
|
||||||
setIsSettingsOpen: (isOpen) => set({ isSettingsOpen: isOpen }),
|
setIsSettingsOpen: (isOpen) => set({ isSettingsOpen: isOpen }),
|
||||||
|
|
||||||
|
moderatingCommentCid: '',
|
||||||
|
setModeratingCommentCid: (cid) => set({ moderatingCommentCid: cid }),
|
||||||
|
|
||||||
pendingComment: '',
|
pendingComment: '',
|
||||||
setPendingComment: (comment) => set({ pendingComment: comment }),
|
setPendingComment: (comment) => set({ pendingComment: comment }),
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user