2023-04-07 17:47:51 +02:00
|
|
|
import React, { useEffect, useState, useRef } from 'react';
|
2023-04-08 13:27:17 +02:00
|
|
|
import useGeneralStore from '../hooks/stores/useGeneralStore';
|
2023-03-09 17:51:56 +01:00
|
|
|
import Modal from 'react-modal';
|
|
|
|
|
import styled from 'styled-components';
|
2023-03-16 21:16:59 +01:00
|
|
|
import Draggable from 'react-draggable';
|
|
|
|
|
|
2023-03-09 17:51:56 +01:00
|
|
|
|
|
|
|
|
const StyledModal = styled(Modal)`
|
2023-03-16 21:16:59 +01:00
|
|
|
.hide-modal-overlay {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-09 17:51:56 +01:00
|
|
|
.modal-content {
|
2023-03-16 21:16:59 +01:00
|
|
|
position: fixed;
|
2023-03-17 14:35:03 +01:00
|
|
|
top: calc(50% - 150px);
|
|
|
|
|
left: calc(50% - 150px);
|
2023-03-16 21:16:59 +01:00
|
|
|
display: block;
|
|
|
|
|
padding: 2px;
|
|
|
|
|
font-size: 10pt;
|
|
|
|
|
border-left: none;
|
|
|
|
|
border-top: none;
|
2023-03-09 17:51:56 +01:00
|
|
|
}
|
|
|
|
|
|
2023-03-16 21:16:59 +01:00
|
|
|
.modal-header {
|
|
|
|
|
font-size: 10pt;
|
|
|
|
|
text-align: center;
|
|
|
|
|
margin-bottom: 1px;
|
|
|
|
|
padding: 0;
|
|
|
|
|
height: 18px;
|
|
|
|
|
line-height: 18px;
|
|
|
|
|
cursor: move;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
all: unset;
|
|
|
|
|
float: right;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
margin-bottom: -4px;
|
|
|
|
|
width: 18px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-07 17:47:51 +02:00
|
|
|
#field {
|
2023-03-16 21:16:59 +01:00
|
|
|
border: 1px solid #aaa;
|
|
|
|
|
font-family: Arial, Helvetica, sans-serif;
|
|
|
|
|
font-size: 10pt;
|
|
|
|
|
outline: medium none;
|
|
|
|
|
width: 298px;
|
|
|
|
|
padding: 2px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
textarea {
|
|
|
|
|
min-width: 296px;
|
|
|
|
|
float: left;
|
|
|
|
|
font-size: 10pt;
|
|
|
|
|
font-family: Arial, Helvetica, sans-serif;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#captcha-container {
|
|
|
|
|
position: relative;
|
|
|
|
|
clear: both;
|
|
|
|
|
width: 302px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
margin-bottom: 3px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#response {
|
|
|
|
|
width: 100%;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
margin: 0px;
|
|
|
|
|
padding: 0px 2px;
|
|
|
|
|
font-family: monospace;
|
|
|
|
|
vertical-align: middle;
|
2023-03-09 17:51:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
img {
|
2023-03-16 21:16:59 +01:00
|
|
|
height: 100%;
|
|
|
|
|
width: 100%;
|
|
|
|
|
margin-top: 2px;
|
|
|
|
|
position: relative;
|
|
|
|
|
display: block;
|
2023-03-09 17:51:56 +01:00
|
|
|
}
|
|
|
|
|
|
2023-04-07 17:47:51 +02:00
|
|
|
#nav {
|
2023-03-16 21:16:59 +01:00
|
|
|
float: right;
|
|
|
|
|
margin: 0;
|
2023-04-07 17:47:51 +02:00
|
|
|
width: 40px;
|
2023-03-09 17:51:56 +01:00
|
|
|
}
|
2023-03-15 15:25:09 +01:00
|
|
|
|
|
|
|
|
${({ selectedStyle }) => {
|
|
|
|
|
switch (selectedStyle) {
|
|
|
|
|
case 'Yotsuba':
|
2023-03-16 21:16:59 +01:00
|
|
|
return `
|
|
|
|
|
.modal-content {
|
|
|
|
|
background-color: #f0e0d6;
|
|
|
|
|
border: 1px solid #d9bfb7;
|
|
|
|
|
}
|
2023-03-15 15:25:09 +01:00
|
|
|
|
2023-03-16 21:16:59 +01:00
|
|
|
.modal-header {
|
|
|
|
|
background-color: #ea8;
|
|
|
|
|
color: #800;
|
|
|
|
|
border: 1px solid #800;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
background-image: url(/assets/buttons/cross_red.png);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
color: maroon;
|
|
|
|
|
}`;
|
|
|
|
|
|
|
|
|
|
case 'Yotsuba-B':
|
|
|
|
|
return `
|
|
|
|
|
.modal-content {
|
|
|
|
|
background-color: #d6daf0;
|
|
|
|
|
border: 1px solid #b7c5d9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-header {
|
|
|
|
|
background-color: #98e;
|
|
|
|
|
color: #000;
|
|
|
|
|
border: 1px solid #000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
background-image: url(/assets/buttons/cross_blue.png);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
color: #000;
|
|
|
|
|
}`;
|
2023-03-15 15:25:09 +01:00
|
|
|
|
|
|
|
|
case 'Futaba':
|
2023-03-16 21:16:59 +01:00
|
|
|
return `
|
|
|
|
|
.modal-content {
|
|
|
|
|
background-color: #f0e0d6;
|
|
|
|
|
border: 1px solid #d9bfb7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-header {
|
|
|
|
|
background-color: #ea8;
|
|
|
|
|
color: #800;
|
|
|
|
|
border: 1px solid #800;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
background-image: url(/assets/buttons/cross_red.png);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
color: maroon;
|
|
|
|
|
}`;
|
2023-03-15 15:25:09 +01:00
|
|
|
|
|
|
|
|
case 'Burichan':
|
2023-03-16 21:16:59 +01:00
|
|
|
return `
|
|
|
|
|
.modal-content {
|
|
|
|
|
background-color: #d6daf0;
|
|
|
|
|
border: 1px solid #b7c5d9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-header {
|
|
|
|
|
background-color: #98e;
|
|
|
|
|
color: #000;
|
|
|
|
|
border: 1px solid #000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
background-image: url(/assets/buttons/cross_blue.png);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
color: #000;
|
|
|
|
|
}`;
|
2023-03-15 15:25:09 +01:00
|
|
|
|
|
|
|
|
case 'Tomorrow':
|
2023-03-16 21:16:59 +01:00
|
|
|
return `
|
|
|
|
|
.modal-content {
|
|
|
|
|
background-color: #282a2e;
|
|
|
|
|
border: 1px solid #111;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-header {
|
|
|
|
|
background-color: #282a2e;
|
|
|
|
|
color: #c5c8c6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
background-image: url(/assets/buttons/cross_dark.png);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-07 17:47:51 +02:00
|
|
|
#field {
|
2023-03-16 21:16:59 +01:00
|
|
|
background-color: #282a2e;
|
|
|
|
|
color: #c5c8c6;
|
|
|
|
|
border: 1px solid #515151;
|
|
|
|
|
width: 296px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
textarea {
|
|
|
|
|
background-color: #282a2e;
|
|
|
|
|
color: #c5c8c6;
|
|
|
|
|
border: 1px solid #515151;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#response {
|
|
|
|
|
background-color: #282a2e;
|
|
|
|
|
color: #c5c8c6;
|
|
|
|
|
outline: none;
|
|
|
|
|
border: 1px solid #515151;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
color: #c5c8c6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#next {
|
|
|
|
|
filter: brightness(80%);
|
|
|
|
|
}`;
|
2023-03-15 15:25:09 +01:00
|
|
|
|
|
|
|
|
case 'Photon':
|
2023-03-16 21:16:59 +01:00
|
|
|
return `
|
|
|
|
|
.modal-content {
|
|
|
|
|
background-color: #ddd;
|
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.modal-header {
|
|
|
|
|
background-color: #ddd;
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
background-image: url(/assets/buttons/cross_photon.png);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
color: #333;
|
|
|
|
|
}`;
|
2023-03-15 15:25:09 +01:00
|
|
|
}
|
|
|
|
|
}}
|
2023-03-09 17:51:56 +01:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
|
2023-04-07 17:47:51 +02:00
|
|
|
const CaptchaModal = ({ isOpen, closeModal }) => {
|
|
|
|
|
const {
|
|
|
|
|
challengesArray,
|
|
|
|
|
pendingComment,
|
|
|
|
|
selectedStyle,
|
|
|
|
|
setCaptchaResponse,
|
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-04-03 15:08:45 +02:00
|
|
|
const responseRef = useRef();
|
|
|
|
|
const nodeRef = useRef(null);
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
const handleKeyDown = (event) => {
|
|
|
|
|
if (event.key === "Enter") {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
setCaptchaResponse(responseRef.current.value);
|
|
|
|
|
closeModal();
|
|
|
|
|
}
|
2023-03-09 17:51:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<StyledModal
|
2023-03-16 21:16:59 +01:00
|
|
|
isOpen={isOpen}
|
|
|
|
|
onRequestClose={closeModal}
|
|
|
|
|
contentLabel="Captcha Modal"
|
|
|
|
|
shouldCloseOnEsc={false}
|
|
|
|
|
shouldCloseOnOverlayClick={false}
|
|
|
|
|
selectedStyle={selectedStyle}
|
|
|
|
|
overlayClassName="hide-modal-overlay">
|
2023-03-22 20:55:36 +01:00
|
|
|
<Draggable handle=".modal-header" nodeRef={nodeRef}>
|
|
|
|
|
<div className="modal-content" ref={nodeRef}>
|
2023-03-16 21:16:59 +01:00
|
|
|
<div className="modal-header">
|
2023-04-07 17:47:51 +02:00
|
|
|
{pendingComment.parentCid ?
|
|
|
|
|
("Challenges for Reply c/" + pendingComment.cid) :
|
|
|
|
|
"Challenges for New Thread"}
|
2023-04-03 15:08:45 +02:00
|
|
|
<button className="icon" onClick={() => closeModal()} title="close" />
|
2023-03-16 21:16:59 +01:00
|
|
|
</div>
|
|
|
|
|
<div id="form">
|
2023-04-07 17:47:51 +02:00
|
|
|
{pendingComment.displayName ? (
|
|
|
|
|
<div>
|
|
|
|
|
<input id="field" type="text" placeholder={pendingComment.displayName} disabled />
|
|
|
|
|
</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-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>
|
|
|
|
|
<button id="nav" onClick={() => {
|
|
|
|
|
setCurrentChallengeIndex((currentChallengeIndex + 1) % totalChallenges)
|
|
|
|
|
}
|
|
|
|
|
}>></button>
|
|
|
|
|
<button id="nav" onClick={()=> {
|
|
|
|
|
setCurrentChallengeIndex((currentChallengeIndex - 1 + totalChallenges) % totalChallenges)
|
|
|
|
|
}}><</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;
|