import { useState, useEffect, useRef } from "react";
import "./VerseValidator.css";
import { StringDiff } from "react-string-diff";
import { containsKorean, jamoSubstringMatch } from './utils';
const STATE = {
INCORRECT: 0,
PARTIAL: 1,
CORRECT: 2,
};
// function to render and handle logic of each of the cells
const VerseValidator = (
{ element:
{ pack, title, chapterTitle, reference, verse },
toHideReference,
liveValidation,
clearKey,
t,
index,
onShowAnswer
}) => { // useful use of destructuring here
const [inputReference, setReference] = useState('')
const [referenceBool, setReferenceBool] = useState(STATE.INCORRECT)
const [inputChapterTitle, setChapterTitle] = useState('')
const [chapterTitleBool, setChapterTitleBool] = useState(STATE.INCORRECT)
const [inputTitle, setTitle] = useState('')
const [titleBool, setTitleBool] = useState(STATE.INCORRECT)
const [inputVerse, setVerse] = useState('')
const [verseBool, setVerseBool] = useState(STATE.INCORRECT)
const [hintBool, setHintBool] = useState(false)
const [diffBool, setDiffBool] = useState(false)
const [isComposing, setIsComposing] = useState(false);
const isInitialMount = useRef(true);
// State for hint word counts
const [referenceHintCount, setReferenceHintCount] = useState(0);
const [titleHintCount, setTitleHintCount] = useState(0);
const [chapterTitleHintCount, setChapterTitleHintCount] = useState(0);
const [verseHintCount, setVerseHintCount] = useState(0);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
handleReset();
}
}, [clearKey]);
useEffect(() => {
// Re-run validation for all fields when liveValidation changes
// Using current input values to re-evaluate their state
validateReference(inputReference);
validateChapterTitle(inputChapterTitle);
validateTitle(inputTitle);
validateVerse(inputVerse);
}, [liveValidation]); // Dependency array: re-run effect when liveValidation changes
// handle reset
const handleReset = () => {
setReference('');
setReferenceBool(STATE.INCORRECT);
setChapterTitle('');
setChapterTitleBool(STATE.INCORRECT);
setTitle('');
setTitleBool(STATE.INCORRECT);
setVerse('');
setVerseBool(STATE.INCORRECT);
setDiffBool(false); // optionally hide answer again
setHintBool(false);
// Reset hint counts
setReferenceHintCount(0);
setTitleHintCount(0);
setChapterTitleHintCount(0);
setVerseHintCount(0);
};
// Handle the start of composition
const handleCompositionStart = () => {
setIsComposing(true);
};
function resultChecker(string1, string2, liveValidation) {
var result = STATE.INCORRECT; // init
// contains korean
if (containsKorean(string1)) {
if (string1 === string2) {
result = STATE.CORRECT;
} else if (liveValidation && jamoSubstringMatch(string2, string1) & string1 !== "") {
result = STATE.PARTIAL;
} else {
result = STATE.INCORRECT;
}
} else { // does not contain korean
if (string1 === string2) {
result = STATE.CORRECT;
} else if (liveValidation && string2.startsWith(string1) & string1 !== "") {
result = STATE.PARTIAL;
} else {
result = STATE.INCORRECT;
}
}
return result;
}
// function to check correctness of reference input
const validateReference = (value) => {
const string1 = String(value)
.replace(/\s+/g, "")
.toLowerCase()
.normalize("NFC");
const string2 = String(reference)
.replace(/\s+/g, "")
.toLowerCase()
.normalize("NFC");
const result = resultChecker(string1, string2, liveValidation);
setReferenceBool(result);
};
const referenceClassName = `reference-box${
referenceBool === STATE.CORRECT ? " correct" :
referenceBool === STATE.PARTIAL ? " partial" :
" incorrect"
}`;
{/* function to check correctness of title input */}
const validateTitle = (value) => {
let string1 = value;
let string2 = title;
string1 = String(string1)
.replace(/[\p{P}\p{S}]/gu, "") // Removes punctuation and symbols
.replace(/\s+/g, "") // Removes all whitespace
.toLowerCase()
.normalize("NFC"); // Normalizes to NFC form
string2 = String(string2)
.replace(/[\p{P}\p{S}]/gu, "")
.replace(/\s+/g, "")
.toLowerCase()
.normalize("NFC");
const result = resultChecker(string1, string2, liveValidation);
setTitleBool(result);
};
const titleClassName = `chapter-title-box${
titleBool=== STATE.CORRECT ? " correct" :
titleBool === STATE.PARTIAL ? " partial" :
" incorrect"
}`;
{/* function to check correctness of chapter title input */}
const validateChapterTitle = (value) => {
let string1 = value;
let string2 = chapterTitle;
string1 = String(string1)
.replace(/[\p{P}\p{S}]/gu, "")
.replace(/\s+/g, "")
.toLowerCase()
.normalize("NFC");
string2 = String(string2)
.replace(/[\p{P}\p{S}]/gu, "")
.replace(/\s+/g, "")
.toLowerCase()
.normalize("NFC");
const result = resultChecker(string1, string2, liveValidation);
setChapterTitleBool(result);
};
const chapterTitleClassName = `title-box${
chapterTitleBool=== STATE.CORRECT ? " correct" :
chapterTitleBool === STATE.PARTIAL ? " partial" :
" incorrect"
}`;
// check verse input
const validateVerse = (value) => {
let string1 = value;
let string2 = verse;
string1 = String(string1)
.replace(/[\p{P}\p{S}]/gu, "")
.replace(/\s+/g, "")
.toLowerCase()
.normalize("NFC");
string2 = String(string2)
.replace(/[\p{P}\p{S}]/gu, "")
.replace(/\s+/g, "")
.toLowerCase()
.normalize("NFC");
const result = resultChecker(string1, string2, liveValidation);
setVerseBool(result);
};
const verseClassName = `verse-box${
verseBool === STATE.CORRECT ? " correct" :
verseBool === STATE.PARTIAL ? " partial" :
" incorrect"
}`;
const DiffViewerStrict = ({oldValue, newValue}) => {
const string1 = String(oldValue)
.toLowerCase()
.normalize("NFC");
const string2 = String(newValue)
.toLowerCase()
.normalize("NFC");
let diffStyle = {
added: {
backgroundColor: 'var(--background-color-added)'
},
removed: {
backgroundColor: 'var(--background-color-removed)'
},
default: {}
};
return (