diff --git a/package.json b/package.json
index a957a9c..127ae3b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@lingdocs/pashto-inflector",
- "version": "1.9.0",
+ "version": "1.9.1",
"author": "lingdocs.com",
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
"homepage": "https://verbs.lingdocs.com",
diff --git a/src/App.css b/src/App.css
index d3f9d76..2b03d02 100644
--- a/src/App.css
+++ b/src/App.css
@@ -10,7 +10,21 @@
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
-
+
+.answer-feedback {
+ transition: opacity 0.3s ease-in;
+ opacity: 0.8;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ z-index: 99999999;
+ transform: translate(-50%, -50%);
+}
+
+.hide {
+ opacity: 0;
+}
+
:root {
--secondary: #00c1fc;
--primary: #ffda54;
diff --git a/src/components/vp-explorer/TensePicker.tsx b/src/components/vp-explorer/TensePicker.tsx
index fa191a8..fa11cc6 100644
--- a/src/components/vp-explorer/TensePicker.tsx
+++ b/src/components/vp-explorer/TensePicker.tsx
@@ -68,10 +68,11 @@ export function getRandomTense(type: "basic" | "modal" | "perfect", o?: T.Perfec
return tns;
}
-function TensePicker({ onChange, vps, mode }: {
+function TensePicker({ onChange, vps, mode, locked }: {
vps: T.VPSelectionState,
onChange: (p: T.VPSelectionState) => void,
mode: "charts" | "phrases" | "quiz",
+ locked: boolean,
}) {
function onTenseSelect(o: { value: T.VerbTense | T.PerfectTense } | null) {
const value = o?.value ? o.value : undefined;
@@ -179,7 +180,7 @@ function TensePicker({ onChange, vps, mode }: {
options={tOptions}
{...zIndexProps}
/>
- {vps.verb &&
+ {vps.verb && !locked &&
diff --git a/src/components/vp-explorer/VPExplorer.tsx b/src/components/vp-explorer/VPExplorer.tsx
index 5d2d125..2b6233e 100644
--- a/src/components/vp-explorer/VPExplorer.tsx
+++ b/src/components/vp-explorer/VPExplorer.tsx
@@ -16,10 +16,13 @@ import { randomSubjObj } from "../../library";
import shuffleArray from "../../lib/shuffle-array";
import InlinePs from "../InlinePs";
import { psStringEquals } from "../../lib/p-text-helpers";
+import classNames from "classnames";
+import { randFromArray } from "../../lib/misc-helpers";
// import { useReward } from 'react-rewards';
const kingEmoji = "👑";
const servantEmoji = "🙇♂️";
+const correctEmoji = ["✅", '🤓', "✅", '😊', "🌹", "✅", "✅", "🕺", "💃", '🥳', "👏", "✅", "💯", "😎", "✅", "👍"];
// TODO: Drill Down text display options
@@ -34,6 +37,8 @@ const servantEmoji = "🙇♂️";
// TODO: error handling on error with rendering etc
+const checkDuration = 400;
+
type QuizState = {
answer: {
ps: T.SingleOrLengthOpts
;
@@ -62,18 +67,26 @@ export function VPExplorer(props: {
);
const [mode, setMode] = useStickyState<"charts" | "phrases" | "quiz">("phrases", "verbExplorerMode");
const [quizState, setQuizState] = useState(undefined);
+ const [showCheck, setShowCheck] = useState(false);
+ const [currentCorrectEmoji, setCurrentCorrectEmoji] = useState(randFromArray(correctEmoji));
// const { reward } = useReward('rewardId', "emoji", {
// emoji: ['🤓', '😊', '🥳', "👏", "💯", "😎", "👍"],
// lifetime: 50,
// elementCount: 10,
// elementSize: 30,
// });
+ useEffect(() => {
+ if (mode === "quiz") {
+ handleResetQuiz();
+ }
+ // eslint-disable-next-line
+ }, []);
useEffect(() => {
setVps(o => {
if (mode === "quiz") {
- return getRandomVPSelection("both")(
- makeVPSelectionState(props.verb, o)
- );
+ const { VPS, qs } = makeQuizState(vps);
+ setQuizState(qs);
+ return VPS;
}
return makeVPSelectionState(props.verb, o);
});
@@ -130,8 +143,17 @@ export function VPExplorer(props: {
function checkQuizAnswer(a: T.PsString) {
if (!quizState) return;
if (isInAnswer(a, quizState.answer)) {
- // reward();
- handleResetQuiz();
+ setShowCheck(true);
+ setTimeout(() => {
+ handleResetQuiz();
+ }, checkDuration / 2);
+ setTimeout(() => {
+ setShowCheck(false);
+ }, checkDuration);
+ // this sucks, have to do this so the emoji doesn't change in the middle of animation
+ setTimeout(() => {
+ setCurrentCorrectEmoji(randFromArray(correctEmoji));
+ }, checkDuration * 2);
} else {
setQuizState({
...quizState,
@@ -219,6 +241,7 @@ export function VPExplorer(props: {
vps={vps}
onChange={quizLock(setVps)}
mode={mode}
+ locked={!!(mode === "quiz" && quizState)}
/>
@@ -228,10 +251,15 @@ export function VPExplorer(props: {
{(vps.verb && (mode === "charts")) && }
{(mode === "quiz" && quizState) &&
+
+ {currentCorrectEmoji}
+
{quizState.result === "waiting" ? <>
Choose a correct answer:
- {quizState.options.map(o =>
-
checkQuizAnswer(o)}>
+ {quizState.options.map(o =>
+
{
+ checkQuizAnswer(o);
+ }}>
{o}
)}
@@ -248,9 +276,6 @@ export function VPExplorer(props: {
}
}
- {mode === "quiz" &&
- {/* spacer for blank space while quizzing */}
-
}
}
@@ -398,7 +423,7 @@ function getRandomVPSelection(mix: MixType = "both") {
};
return {
subject: s,
- verb: mix === "both" ? randomizeTense(v, false) : v,
+ verb: randomizeTense(v, true),
};
};
};
diff --git a/src/lib/misc-helpers.ts b/src/lib/misc-helpers.ts
index 2c539cf..2b480f9 100644
--- a/src/lib/misc-helpers.ts
+++ b/src/lib/misc-helpers.ts
@@ -152,6 +152,12 @@ export function randomNumber(minInclusive: number, maxExclusive: number): number
return Math.floor(Math.random() * (maxExclusive - minInclusive) + minInclusive);
}
+export function randFromArray(arr: M[]): M {
+ return arr[
+ Math.floor(Math.random()*arr.length)
+ ];
+}
+
// TODO: deprecate this because we have it in np-tools?
/**
* Sees if a possiblePerson (for subject/object) is possible, given the other person