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;
|