Game working alright! 💪

This commit is contained in:
lingdocs 2022-04-12 16:05:14 +05:00
parent 0fb73af58b
commit dad93bfa14
5 changed files with 61 additions and 15 deletions

View File

@ -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",

View File

@ -11,6 +11,20 @@
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;

View File

@ -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 && <div className="d-flex flex-row justify-content-between align-items-center mt-3 mb-1" style={{ width: "100%" }}>
{vps.verb && !locked && <div className="d-flex flex-row justify-content-between align-items-center mt-3 mb-1" style={{ width: "100%" }}>
<div className="btn btn-light clickable" onClick={moveTense("back")}>
<i className="fas fa-chevron-left" />
</div>

View File

@ -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<T.PsString[]>;
@ -62,18 +67,26 @@ export function VPExplorer(props: {
);
const [mode, setMode] = useStickyState<"charts" | "phrases" | "quiz">("phrases", "verbExplorerMode");
const [quizState, setQuizState] = useState<QuizState | undefined>(undefined);
const [showCheck, setShowCheck] = useState<boolean>(false);
const [currentCorrectEmoji, setCurrentCorrectEmoji] = useState<string>(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();
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)}
/>
</div>
</div>
@ -228,10 +251,15 @@ export function VPExplorer(props: {
{(vps.verb && (mode === "charts")) && <ChartDisplay VS={vps.verb} opts={props.opts} />}
<span id="rewardId" />
{(mode === "quiz" && quizState) && <div className="text-center">
<div style={{ fontSize: "4rem" }} className={classNames("answer-feedback", { hide: !showCheck })}>
{currentCorrectEmoji}
</div>
{quizState.result === "waiting" ? <>
<div className="text-muted my-3">Choose a correct answer:</div>
{quizState.options.map(o => <div className="pb-3">
<div className="btn btn-outline-secondary" onClick={() => checkQuizAnswer(o)}>
{quizState.options.map(o => <div className="pb-3" key={o.f}>
<div className="btn btn-answer btn-outline-secondary" onClick={() => {
checkQuizAnswer(o);
}}>
<InlinePs opts={props.opts}>{o}</InlinePs>
</div>
</div>)}
@ -248,9 +276,6 @@ export function VPExplorer(props: {
</div>
</div>}
</div>}
{mode === "quiz" && <div style={{ height: "300px" }}>
{/* spacer for blank space while quizzing */}
</div>}
</div>
}
@ -398,7 +423,7 @@ function getRandomVPSelection(mix: MixType = "both") {
};
return {
subject: s,
verb: mix === "both" ? randomizeTense(v, false) : v,
verb: randomizeTense(v, true),
};
};
};

View File

@ -152,6 +152,12 @@ export function randomNumber(minInclusive: number, maxExclusive: number): number
return Math.floor(Math.random() * (maxExclusive - minInclusive) + minInclusive);
}
export function randFromArray<M>(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