mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
added functionality to captcha modal
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useRef } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import useAppStore from '../useAppStore';
|
import useAppStore from '../useAppStore';
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
@@ -42,7 +42,7 @@ const StyledModal = styled(Modal)`
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#name {
|
#field {
|
||||||
border: 1px solid #aaa;
|
border: 1px solid #aaa;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
@@ -85,10 +85,10 @@ const StyledModal = styled(Modal)`
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#next {
|
#nav {
|
||||||
float: right;
|
float: right;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 75px;
|
width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
${({ selectedStyle }) => {
|
${({ selectedStyle }) => {
|
||||||
@@ -193,7 +193,7 @@ const StyledModal = styled(Modal)`
|
|||||||
background-image: url(/assets/buttons/cross_dark.png);
|
background-image: url(/assets/buttons/cross_dark.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
#name {
|
#field {
|
||||||
background-color: #282a2e;
|
background-color: #282a2e;
|
||||||
color: #c5c8c6;
|
color: #c5c8c6;
|
||||||
border: 1px solid #515151;
|
border: 1px solid #515151;
|
||||||
@@ -245,13 +245,35 @@ const StyledModal = styled(Modal)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
const CaptchaModal = ({ isOpen, closeModal, captchaImage }) => {
|
const CaptchaModal = ({ isOpen, closeModal }) => {
|
||||||
const { setCaptchaResponse } = useAppStore(state => state);
|
const {
|
||||||
const selectedStyle = useAppStore(state => state.selectedStyle);
|
challengesArray,
|
||||||
|
pendingComment,
|
||||||
|
selectedStyle,
|
||||||
|
setCaptchaResponse,
|
||||||
|
} = useAppStore(state => state);
|
||||||
|
|
||||||
|
const [imageSources, setImageSources] = useState([]);
|
||||||
|
const [currentChallengeIndex, setCurrentChallengeIndex] = useState(0);
|
||||||
|
const [totalChallenges, setTotalChallenges] = useState(0);
|
||||||
const responseRef = useRef();
|
const responseRef = useRef();
|
||||||
const nodeRef = useRef(null);
|
const nodeRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (challengesArray) {
|
||||||
|
const challenges = challengesArray.challenges;
|
||||||
|
const decryptedChallenges = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < challenges.length; i++) {
|
||||||
|
const imageString = challenges[i].challenge;
|
||||||
|
const imageSource = `data:image/png;base64,${imageString}`;
|
||||||
|
decryptedChallenges.push(imageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
setImageSources(decryptedChallenges);
|
||||||
|
setTotalChallenges(decryptedChallenges.length);
|
||||||
|
}
|
||||||
|
}, [challengesArray]);
|
||||||
|
|
||||||
const handleKeyDown = (event) => {
|
const handleKeyDown = (event) => {
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
@@ -261,7 +283,6 @@ const CaptchaModal = ({ isOpen, closeModal, captchaImage }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledModal
|
<StyledModal
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
@@ -274,16 +295,37 @@ const CaptchaModal = ({ isOpen, closeModal, captchaImage }) => {
|
|||||||
<Draggable handle=".modal-header" nodeRef={nodeRef}>
|
<Draggable handle=".modal-header" nodeRef={nodeRef}>
|
||||||
<div className="modal-content" ref={nodeRef}>
|
<div className="modal-content" ref={nodeRef}>
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
Challenges for
|
{pendingComment.parentCid ?
|
||||||
|
("Challenges for Reply c/" + pendingComment.cid) :
|
||||||
|
"Challenges for New Thread"}
|
||||||
<button className="icon" onClick={() => closeModal()} title="close" />
|
<button className="icon" onClick={() => closeModal()} title="close" />
|
||||||
</div>
|
</div>
|
||||||
<div id="form">
|
<div id="form">
|
||||||
<div>
|
{pendingComment.displayName ? (
|
||||||
<input id="name" type="text" placeholder="Name" disabled></input>
|
<div>
|
||||||
</div>
|
<input id="field" type="text" placeholder={pendingComment.displayName} disabled />
|
||||||
<div>
|
</div>
|
||||||
<textarea rows="4" placeholder="Comment" wrap="soft" disabled></textarea>
|
) : null}
|
||||||
</div>
|
{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}
|
||||||
<div id="captcha-container">
|
<div id="captcha-container">
|
||||||
<input
|
<input
|
||||||
id="response"
|
id="response"
|
||||||
@@ -293,11 +335,19 @@ const CaptchaModal = ({ isOpen, closeModal, captchaImage }) => {
|
|||||||
ref={responseRef}
|
ref={responseRef}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
autoFocus />
|
autoFocus />
|
||||||
<img src={captchaImage} alt="captcha" />
|
<img src={imageSources[currentChallengeIndex]} alt="captcha" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>Challenge 1 of 3</span>
|
<span style={{lineHeight: '1.7'}}>
|
||||||
<button id="next">Next</button>
|
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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ import useSuccess from '../../hooks/useSuccess';
|
|||||||
const Board = () => {
|
const Board = () => {
|
||||||
const {
|
const {
|
||||||
captchaResponse, setCaptchaResponse,
|
captchaResponse, setCaptchaResponse,
|
||||||
|
setChallengesArray,
|
||||||
defaultSubplebbits,
|
defaultSubplebbits,
|
||||||
isSettingsOpen, setIsSettingsOpen,
|
isSettingsOpen, setIsSettingsOpen,
|
||||||
|
setPendingComment,
|
||||||
selectedAddress, setSelectedAddress,
|
selectedAddress, setSelectedAddress,
|
||||||
selectedStyle,
|
selectedStyle,
|
||||||
setSelectedThread,
|
setSelectedThread,
|
||||||
@@ -41,7 +43,6 @@ const Board = () => {
|
|||||||
|
|
||||||
const [isCaptchaOpen, setIsCaptchaOpen] = useState(false);
|
const [isCaptchaOpen, setIsCaptchaOpen] = useState(false);
|
||||||
const [isReplyOpen, setIsReplyOpen] = useState(false);
|
const [isReplyOpen, setIsReplyOpen] = useState(false);
|
||||||
const [captchaImage, setCaptchaImage] = useState('');
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||||
const [visible, setVisible] = useState(true);
|
const [visible, setVisible] = useState(true);
|
||||||
@@ -55,10 +56,6 @@ const Board = () => {
|
|||||||
useSuccess(successMessage, [successMessage]);
|
useSuccess(successMessage, [successMessage]);
|
||||||
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// console.log(selectedFeed[3]);
|
|
||||||
// }, [selectedFeed]);
|
|
||||||
|
|
||||||
// temporary title from JSON, gets subplebbitAddress from URL
|
// temporary title from JSON, gets subplebbitAddress from URL
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelectedAddress(subplebbitAddress);
|
setSelectedAddress(subplebbitAddress);
|
||||||
@@ -110,7 +107,8 @@ const Board = () => {
|
|||||||
|
|
||||||
|
|
||||||
const onChallenge = async (challenges, comment) => {
|
const onChallenge = async (challenges, comment) => {
|
||||||
console.log("onChallenge:", challenges, comment)
|
|
||||||
|
setPendingComment(comment);
|
||||||
let challengeAnswers = [];
|
let challengeAnswers = [];
|
||||||
try {
|
try {
|
||||||
challengeAnswers = await getChallengeAnswersFromUser(challenges)
|
challengeAnswers = await getChallengeAnswersFromUser(challenges)
|
||||||
@@ -150,6 +148,8 @@ const Board = () => {
|
|||||||
|
|
||||||
|
|
||||||
const getChallengeAnswersFromUser = async (challenges) => {
|
const getChallengeAnswersFromUser = async (challenges) => {
|
||||||
|
setChallengesArray(challenges);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const imageString = challenges?.challenges[0].challenge;
|
const imageString = challenges?.challenges[0].challenge;
|
||||||
const imageSource = `data:image/png;base64,${imageString}`;
|
const imageSource = `data:image/png;base64,${imageString}`;
|
||||||
@@ -158,11 +158,9 @@ const Board = () => {
|
|||||||
|
|
||||||
challengeImg.onload = () => {
|
challengeImg.onload = () => {
|
||||||
setIsCaptchaOpen(true);
|
setIsCaptchaOpen(true);
|
||||||
setCaptchaImage(imageSource);
|
|
||||||
|
|
||||||
const handleKeyDown = (event) => {
|
const handleKeyDown = (event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
setCaptchaImage('');
|
|
||||||
resolve(captchaResponse);
|
resolve(captchaResponse);
|
||||||
setIsCaptchaOpen(false);
|
setIsCaptchaOpen(false);
|
||||||
document.removeEventListener('keydown', handleKeyDown);
|
document.removeEventListener('keydown', handleKeyDown);
|
||||||
@@ -175,7 +173,7 @@ const Board = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
challengeImg.onerror = () => {
|
challengeImg.onerror = () => {
|
||||||
reject(setErrorMessage('Could not load challenge image'));
|
reject(setErrorMessage('Could not load challenges'));
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -213,8 +211,7 @@ const Board = () => {
|
|||||||
<CaptchaModal
|
<CaptchaModal
|
||||||
selectedStyle={selectedStyle}
|
selectedStyle={selectedStyle}
|
||||||
isOpen={isCaptchaOpen}
|
isOpen={isCaptchaOpen}
|
||||||
closeModal={() => setIsCaptchaOpen(false)}
|
closeModal={() => setIsCaptchaOpen(false)} />
|
||||||
captchaImage={captchaImage} />
|
|
||||||
<ReplyModal
|
<ReplyModal
|
||||||
selectedStyle={selectedStyle}
|
selectedStyle={selectedStyle}
|
||||||
isOpen={isReplyOpen}
|
isOpen={isReplyOpen}
|
||||||
|
|||||||
+12
-3
@@ -1,9 +1,6 @@
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
|
|
||||||
const useAppStore = create((set) => ({
|
const useAppStore = create((set) => ({
|
||||||
captchaResponse: '',
|
|
||||||
setCaptchaResponse: (response) => set({ captchaResponse: response }),
|
|
||||||
|
|
||||||
bodyStyle: JSON.parse(localStorage.getItem('bodyStyle')) || {
|
bodyStyle: JSON.parse(localStorage.getItem('bodyStyle')) || {
|
||||||
background: '#ffe url(/assets/fade.png) top repeat-x',
|
background: '#ffe url(/assets/fade.png) top repeat-x',
|
||||||
color: 'maroon',
|
color: 'maroon',
|
||||||
@@ -14,12 +11,24 @@ const useAppStore = create((set) => ({
|
|||||||
set(() => ({ bodyStyle }));
|
set(() => ({ bodyStyle }));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
captchaResponse: '',
|
||||||
|
setCaptchaResponse: (response) => set({ captchaResponse: response }),
|
||||||
|
|
||||||
|
challengesArray: [],
|
||||||
|
setChallengesArray: (challengesArray) => set({ challengesArray }),
|
||||||
|
|
||||||
defaultSubplebbits: [],
|
defaultSubplebbits: [],
|
||||||
setDefaultSubplebbits: (subplebbits) => set({ defaultSubplebbits: subplebbits }),
|
setDefaultSubplebbits: (subplebbits) => set({ defaultSubplebbits: subplebbits }),
|
||||||
|
|
||||||
isSettingsOpen: false,
|
isSettingsOpen: false,
|
||||||
setIsSettingsOpen: (isOpen) => set({ isSettingsOpen: isOpen }),
|
setIsSettingsOpen: (isOpen) => set({ isSettingsOpen: isOpen }),
|
||||||
|
|
||||||
|
pendingComment: '',
|
||||||
|
setPendingComment: (comment) => set({ pendingComment: comment }),
|
||||||
|
|
||||||
|
publishedComment: '',
|
||||||
|
setPublishedComment: (comment) => set({ publishedComment: comment }),
|
||||||
|
|
||||||
selectedAddress: '',
|
selectedAddress: '',
|
||||||
setSelectedAddress: (address) => set({ selectedAddress: address }),
|
setSelectedAddress: (address) => set({ selectedAddress: address }),
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user