Files
5chan/src/components/modals/CaptchaModal.jsx
T

191 lines
5.7 KiB
React
Raw Normal View History

2023-04-07 17:47:51 +02:00
import React, { useEffect, useState, useRef } from 'react';
2023-05-24 12:15:43 +02:00
import { StyledModal } from '../styled/modals/CaptchaModal.styled';
import useGeneralStore from '../../hooks/stores/useGeneralStore';
2023-03-09 17:51:56 +01:00
import Modal from 'react-modal';
2023-03-16 21:16:59 +01:00
import Draggable from 'react-draggable';
2023-03-09 17:51:56 +01:00
2023-04-09 20:55:55 +02:00
const CaptchaModal = () => {
2023-04-07 17:47:51 +02:00
const {
2023-05-27 14:09:49 +02:00
challengesArray, setChallengesArray,
2023-04-07 17:47:51 +02:00
pendingComment,
selectedStyle,
setCaptchaResponse,
2023-05-26 10:10:51 +02:00
isAuthorDelete, setIsAuthorDelete,
isAuthorEdit, setIsAuthorEdit,
2023-04-21 09:58:25 +02:00
isCaptchaOpen, setIsCaptchaOpen,
2023-05-26 10:10:51 +02:00
isModEdit, setIsModEdit,
resolveCaptchaPromise,
2023-04-21 09:58:25 +02:00
selectedShortCid,
2023-04-08 13:27:17 +02:00
} = useGeneralStore(state => state);
2023-03-12 22:07:15 +01:00
2023-04-07 17:47:51 +02:00
const [imageSources, setImageSources] = useState([]);
const [currentChallengeIndex, setCurrentChallengeIndex] = useState(0);
const [totalChallenges, setTotalChallenges] = useState(0);
2023-05-11 15:24:46 +02:00
const [isMobile, setIsMobile] = useState(window.innerWidth <= 480);
2023-04-03 15:08:45 +02:00
const responseRef = useRef();
const nodeRef = useRef(null);
2023-05-26 10:10:51 +02:00
useEffect(() => {
if (!isCaptchaOpen) {
setIsAuthorDelete(false);
setIsAuthorEdit(false);
setIsModEdit(false);
}
}, [isCaptchaOpen, setIsAuthorDelete, setIsAuthorEdit, setIsModEdit]);
2023-05-11 14:37:06 +02:00
2023-05-26 10:10:51 +02:00
useEffect(() => {
2023-05-11 14:37:06 +02:00
const handleResize = () => setIsMobile(window.innerWidth <= 480);
window.addEventListener('resize', handleResize);
// Cleanup function
return () => {
window.removeEventListener('resize', handleResize);
};
}, [setIsMobile]);
2023-04-07 17:47:51 +02:00
useEffect(() => {
if (challengesArray) {
const challenges = challengesArray.challenges;
const decryptedChallenges = [];
2023-04-08 09:54:35 +02:00
for (let i = 0; i < challenges?.length; i++) {
2023-04-07 17:47:51 +02:00
const imageString = challenges[i].challenge;
const imageSource = `data:image/png;base64,${imageString}`;
decryptedChallenges.push(imageSource);
}
setImageSources(decryptedChallenges);
setTotalChallenges(decryptedChallenges.length);
}
}, [challengesArray]);
2023-04-03 15:08:45 +02:00
2023-05-26 10:10:51 +02:00
2023-04-03 15:08:45 +02:00
const handleKeyDown = (event) => {
if (event.key === "Enter") {
2023-04-24 16:35:09 +02:00
event.preventDefault();
2023-04-22 14:02:20 +02:00
submitCaptcha();
2023-04-03 15:08:45 +02:00
}
2023-03-09 17:51:56 +01:00
};
2023-05-26 10:10:51 +02:00
2023-04-22 14:02:20 +02:00
const handleReturnKeyDown = () => {
2023-05-26 10:10:51 +02:00
submitCaptcha((response) => {
setCaptchaResponse(response);
resolveCaptchaPromise(response);
2023-04-22 14:02:20 +02:00
});
};
const submitCaptcha = (callback) => {
setCaptchaResponse(responseRef.current.value);
2023-05-27 14:09:49 +02:00
setImageSources([]);
setChallengesArray([]);
2023-04-22 14:02:20 +02:00
setIsCaptchaOpen(false);
2023-04-24 16:35:09 +02:00
2023-04-22 14:02:20 +02:00
if (callback) {
callback(responseRef.current.value);
}
2023-05-26 10:10:51 +02:00
};
2023-04-22 14:02:20 +02:00
2023-05-30 16:41:37 +02:00
const handleCloseModal = () => {
setImageSources([]);
setChallengesArray([]);
2023-07-08 09:03:36 +02:00
setCurrentChallengeIndex(0);
2023-05-30 16:41:37 +02:00
setIsCaptchaOpen(false);
};
2023-04-22 14:02:20 +02:00
2023-03-09 17:51:56 +01:00
return (
<StyledModal
2023-04-09 20:55:55 +02:00
isOpen={isCaptchaOpen}
2023-05-26 10:10:51 +02:00
onRequestClose={() => {
2023-05-30 16:41:37 +02:00
handleCloseModal();
submitCaptcha();}}
2023-03-16 21:16:59 +01:00
contentLabel="Captcha Modal"
shouldCloseOnEsc={false}
shouldCloseOnOverlayClick={false}
selectedStyle={selectedStyle}
overlayClassName="hide-modal-overlay">
2023-05-11 14:37:06 +02:00
<Draggable handle=".modal-header" nodeRef={nodeRef} disabled={isMobile}>
2023-03-22 20:55:36 +01:00
<div className="modal-content" ref={nodeRef}>
2023-03-16 21:16:59 +01:00
<div className="modal-header">
2023-05-26 10:10:51 +02:00
{isModEdit ? "Challenge for Moderator Action" :
isAuthorEdit ? "Challenge for Editing Post" :
isAuthorDelete ? "Challenge for Deleting Post" :
pendingComment.parentCid ?
2023-04-21 09:58:25 +02:00
("Challenges for Reply to c/" + selectedShortCid) :
2023-04-07 17:47:51 +02:00
"Challenges for New Thread"}
2023-05-30 16:41:37 +02:00
<button className="icon" onClick={() => handleCloseModal()} title="close" />
2023-03-16 21:16:59 +01:00
</div>
<div id="form">
2023-04-16 11:21:05 +02:00
{pendingComment.author?.displayName ? (
2023-04-07 17:47:51 +02:00
<div>
2023-04-16 11:21:05 +02:00
<input id="field" type="text" placeholder={pendingComment.author?.displayName} disabled />
2023-04-07 17:47:51 +02:00
</div>
) : null}
{pendingComment.title ? (
<div>
<input id="field" type="text" placeholder={pendingComment.title} disabled />
</div>
) : null}
{pendingComment.content ? (
<div>
<textarea
rows="4"
placeholder={pendingComment.content || "Comment"}
wrap="soft"
disabled
/>
</div>
) : null}
{pendingComment.link ? (
<div>
<input id="field" type="text" placeholder={pendingComment.link} disabled />
</div>
) : null}
2023-03-16 21:16:59 +01:00
<div id="captcha-container">
<input
id="response"
type="text"
autoComplete='off'
placeholder="TYPE THE CAPTCHA HERE AND PRESS ENTER"
2023-04-03 15:08:45 +02:00
ref={responseRef}
onKeyDown={handleKeyDown}
2023-05-24 14:22:04 +02:00
onInput={(e) => {
e.target.value = e.target.value.toUpperCase();
}}
2023-03-16 21:16:59 +01:00
autoFocus />
2023-04-07 17:47:51 +02:00
<img src={imageSources[currentChallengeIndex]} alt="captcha" />
2023-03-16 21:16:59 +01:00
</div>
<div>
2023-04-07 17:47:51 +02:00
<span style={{lineHeight: '1.7'}}>
Challenge {currentChallengeIndex + 1} of {totalChallenges}
</span>
2023-04-21 09:58:25 +02:00
<button
id="nav"
onClick={() => {
if (currentChallengeIndex + 1 < totalChallenges) {
setCurrentChallengeIndex((currentChallengeIndex + 1) % totalChallenges);
} else {
2023-04-22 14:02:20 +02:00
handleReturnKeyDown();
2023-04-21 09:58:25 +02:00
}
}}
>
2023-05-27 14:09:49 +02:00
{currentChallengeIndex + 1 < totalChallenges ? "Next" : "Submit"}
2023-04-21 09:58:25 +02:00
</button>
2023-03-16 21:16:59 +01:00
</div>
</div>
</div>
</Draggable>
2023-03-09 17:51:56 +01:00
</StyledModal>
);
};
Modal.setAppElement('#root');
2023-03-21 11:17:54 +01:00
export default CaptchaModal;