Files
5chan/src/components/ReplyModal.jsx
T

206 lines
5.8 KiB
React
Raw Normal View History

2023-04-12 21:00:51 +02:00
import React, { useRef, useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { usePublishComment } from '@plebbit/plebbit-react-hooks';
2023-04-11 21:51:46 +02:00
import { StyledModal } from './styled/ReplyModal.styled';
2023-04-08 13:27:17 +02:00
import useGeneralStore from '../hooks/stores/useGeneralStore';
2023-03-17 14:35:03 +01:00
import Modal from 'react-modal';
import Draggable from 'react-draggable';
2023-04-12 21:00:51 +02:00
import useError from '../hooks/useError';
import useSuccess from '../hooks/useSuccess';
2023-03-17 14:35:03 +01:00
const ReplyModal = ({ isOpen, closeModal }) => {
2023-04-12 21:00:51 +02:00
const {
captchaResponse, setCaptchaResponse,
setChallengesArray,
setIsCaptchaOpen,
setPendingComment,
setResolveCaptchaPromise,
2023-04-12 21:00:51 +02:00
selectedAddress,
2023-04-12 21:56:25 +02:00
selectedParentCid,
selectedShortCid,
2023-04-12 21:00:51 +02:00
selectedStyle,
selectedThread,
} = useGeneralStore(state => state);
2023-03-17 14:35:03 +01:00
2023-04-12 21:00:51 +02:00
const navigate = useNavigate();
const nodeRef = useRef(null);
const nameRef = useRef();
const commentRef = useRef();
const linkRef = useRef();
const onChallengeVerificationRef = useRef();
const [errorMessage, setErrorMessage] = useState(null);
2023-04-20 16:50:15 +02:00
const [successMessage] = useState(null);
2023-04-12 21:00:51 +02:00
useError(errorMessage, [errorMessage]);
useSuccess(successMessage, [successMessage]);
const onChallengeVerification = (challengeVerification) => {
if (challengeVerification.challengeSuccess === true) {
2023-04-22 15:12:26 +02:00
console.log('challenge success');
2023-04-12 21:00:51 +02:00
}
else if (challengeVerification.challengeSuccess === false) {
setErrorMessage('challenge failed', {reason: challengeVerification.reason, errors: challengeVerification.errors});
}
};
const onChallenge = async (challenges, comment) => {
setPendingComment(comment);
let challengeAnswers = [];
try {
challengeAnswers = await getChallengeAnswersFromUser(challenges)
}
catch (error) {
setErrorMessage(error);
}
if (challengeAnswers) {
await comment.publishChallengeAnswers(challengeAnswers)
}
};
const [publishCommentOptions, setPublishCommentOptions] = useState({
subplebbitAddress: selectedAddress,
onChallenge,
onChallengeVerification: onChallengeVerificationRef.current,
onError: (error) => {
setErrorMessage(error);
},
});
const { publishComment, index } = usePublishComment(publishCommentOptions);
useEffect(() => {
if (index !== undefined) {
2023-04-20 16:50:15 +02:00
navigate(`/p/${selectedAddress}/c/${selectedThread}`)
localStorage.setItem("toastMessage", `Comment pending with index ${index}.`);
2023-04-12 21:00:51 +02:00
}
}, [index]);
onChallengeVerificationRef.current = onChallengeVerification;
const resetFields = () => {
nameRef.current.value = '';
commentRef.current.value = '';
linkRef.current.value = '';
};
useEffect(() => {
setPublishCommentOptions((prevPublishCommentOptions) => ({
...prevPublishCommentOptions,
subplebbitAddress: selectedAddress,
onChallengeVerification: onChallengeVerificationRef.current,
}));
}, [selectedAddress]);
const handleSubmit = async (event) => {
event.preventDefault();
setPublishCommentOptions((prevPublishCommentOptions) => ({
...prevPublishCommentOptions,
2023-04-16 11:21:05 +02:00
author: {
displayName: nameRef.current.value || undefined,
},
2023-04-12 21:00:51 +02:00
content: commentRef.current.value || undefined,
link: linkRef.current.value || undefined,
2023-04-12 21:56:25 +02:00
parentCid: selectedParentCid,
2023-04-12 21:00:51 +02:00
}));
};
useEffect(() => {
if (publishCommentOptions.content) {
(async () => {
await publishComment();
resetFields();
2023-04-21 11:59:17 +02:00
closeModal();
2023-04-12 21:00:51 +02:00
})();
}
}, [publishCommentOptions]);
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 = (event) => {
if (event.key === 'Enter') {
resolve(captchaResponse);
setIsCaptchaOpen(false);
document.removeEventListener('keydown', handleKeyDown);
event.preventDefault();
}
};
setCaptchaResponse('');
document.addEventListener('keydown', handleKeyDown);
useGeneralStore.getState().setResolveCaptchaPromise(resolve);
2023-04-12 21:00:51 +02:00
};
challengeImg.onerror = () => {
reject(setErrorMessage('Could not load challenges'));
};
});
2023-03-17 14:35:03 +01:00
};
2023-03-22 14:30:48 +01:00
2023-03-17 14:35:03 +01:00
return (
<StyledModal
isOpen={isOpen}
onRequestClose={closeModal}
contentLabel="Reply Modal"
shouldCloseOnEsc={false}
shouldCloseOnOverlayClick={false}
selectedStyle={selectedStyle}
overlayClassName="hide-modal-overlay">
2023-03-22 14:30:48 +01:00
<Draggable handle=".modal-header" nodeRef={nodeRef}>
<div className="modal-content" ref={nodeRef}>
2023-03-17 14:35:03 +01:00
<div className="modal-header">
2023-04-12 21:56:25 +02:00
Reply to c/{selectedShortCid}
2023-04-12 21:00:51 +02:00
<button className="icon" onClick={() => closeModal()} title="close" />
2023-03-17 14:35:03 +01:00
</div>
<div id="form">
<div>
2023-04-12 21:00:51 +02:00
<input id="name" type="text" placeholder="Name" ref={nameRef} />
2023-03-17 14:35:03 +01:00
</div>
<div>
2023-04-12 21:00:51 +02:00
<input id="name" type="text" placeholder="Embed link" ref={linkRef} />
2023-03-17 14:35:03 +01:00
</div>
2023-04-18 12:44:55 +02:00
<div className="textarea-wrapper">
<span className="fixed-text">{`c/${selectedShortCid}`}</span>
<textarea className="textarea" rows="4" placeholder="Comment" wrap="soft" ref={commentRef} />
2023-03-17 17:49:30 +01:00
</div>
<div>
2023-04-12 21:00:51 +02:00
<button id="next" onClick={handleSubmit}>Post</button>
2023-03-17 14:35:03 +01:00
</div>
</div>
</div>
</Draggable>
</StyledModal>
);
};
Modal.setAppElement('#root');
2023-03-21 11:17:54 +01:00
export default ReplyModal;