diff --git a/.github/workflows/all-dev-tn-new.yml b/.github/workflows/all-dev-tn-new.yml
index 97a56fc..8e5c148 100644
--- a/.github/workflows/all-dev-tn-new.yml
+++ b/.github/workflows/all-dev-tn-new.yml
@@ -3,7 +3,7 @@ name: ALL new tn dev Deployment
on:
push:
branches:
- - all-1.3-tn-dev-hotfix
+ - all-1.3-security-fixes
jobs:
deploy:
diff --git a/src/views/Practice/Practice.jsx b/src/views/Practice/Practice.jsx
index 8b69061..fc2c36b 100644
--- a/src/views/Practice/Practice.jsx
+++ b/src/views/Practice/Practice.jsx
@@ -636,116 +636,100 @@ const Practice = () => {
function highlightWords(sentence, matchedChar) {
const words = sentence.split(" ");
- matchedChar.sort(function (str1, str2) {
- return str2.length - str1.length;
- });
+ matchedChar.sort((str1, str2) => str2.length - str1.length);
- let type = currentContentType?.toLowerCase();
+ const type = currentContentType?.toLowerCase();
if (type === "char" || type === "word") {
- const word = splitGraphemes(words[0].toLowerCase()).filter(
- (item) => item !== "" && item !== "" && item !== " "
- );
- let highlightedString = [];
- let i = 0;
- for (const char of word) {
- let matchFound = false;
- for (const matched of matchedChar) {
- const length = splitGraphemes(matched).filter(
- (item) => item !== "" && item !== "" && item !== " "
- ).length;
- const substr = word.slice(i, i + length).join("");
-
- if (substr.includes(matched)) {
- highlightedString.push(
-
-
- {i === 0 ? substr.toUpperCase() : substr}
-
-
- );
- i += length - 1;
- matchFound = true;
- break;
- }
- }
- if (!matchFound) {
- highlightedString.push(
-
-
- {i === 0 ? char.toUpperCase() : char}
-
-
- );
- }
- i++;
- }
- return highlightedString;
+ return highlightCharacters(words[0], matchedChar);
} else {
- const highlightedSentence = words.map((word, index) => {
- const isMatched = matchedChar.some((char) =>
- word.toLowerCase().includes(char)
- );
- if (isMatched) {
- return (
-
-
- {word}
- {" "}
-
- );
- } else {
- return (
-
- {word + " "}
-
- );
- }
- });
- return highlightedSentence;
+ return highlightSentence(words, matchedChar);
+ }
+ }
+
+ function highlightCharacters(word, matchedChar) {
+ const graphemes = splitGraphemes(word.toLowerCase()).filter(isValidChar);
+ let highlightedString = [];
+ let i = 0;
+
+ while (i < graphemes.length) {
+ const match = findMatch(graphemes, matchedChar, i);
+
+ if (match) {
+ highlightedString.push(renderHighlightedText(match.substr, i, true));
+ i += match.length - 1;
+ } else {
+ highlightedString.push(renderHighlightedText(graphemes[i], i, false));
+ }
+ i++;
}
+
+ return highlightedString;
+ }
+
+ function findMatch(graphemes, matchedChar, index) {
+ for (const matched of matchedChar) {
+ const length = splitGraphemes(matched).filter(isValidChar).length;
+ const substr = graphemes.slice(index, index + length).join("");
+
+ if (substr.includes(matched)) {
+ return { substr, length };
+ }
+ }
+ return null;
+ }
+
+ function renderHighlightedText(content, index, isMatched) {
+ const styles = isMatched ? { background: "#FFF0BD" } : { color: "#333F61" };
+
+ return (
+
+
+ {index === 0 ? content.toUpperCase() : content}
+
+
+ );
+ }
+
+ function highlightSentence(words, matchedChar) {
+ return words.map((word, index) => {
+ const isMatched = matchedChar.some((char) =>
+ word.toLowerCase().includes(char)
+ );
+
+ return (
+
+
+ {word}
+ {" "}
+
+ );
+ });
+ }
+
+ function isValidChar(char) {
+ return char !== "" && char !== "" && char !== " ";
}
useEffect(() => {
@@ -958,7 +942,6 @@ const Practice = () => {
livesData,
setLivesData,
gameOverData,
- highlightWords,
matchedChar: !isShowCase && questions[currentQuestion]?.matchedChar,
percentage,
fluency,