diff --git a/src/App.tsx b/src/App.tsx index 68e8418..46f30f9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -87,6 +87,10 @@ function App() { if (transitivity === "grammatically transitive") { setVerbTypeShowing("simple"); } + if (transitivity === "intransitive" && verbTypeShowing === "dynamic compound") { + setTransitivityShowing("transitive"); + return; + } setTransitivityShowing(e.target.value as T.Transitivity); } const isRegularVerb = (entry: T.DictionaryEntry): boolean => ( diff --git a/src/components/vp-explorer/TensePicker.tsx b/src/components/vp-explorer/TensePicker.tsx index a46fb7b..fa191a8 100644 --- a/src/components/vp-explorer/TensePicker.tsx +++ b/src/components/vp-explorer/TensePicker.tsx @@ -6,7 +6,7 @@ import * as T from "../../types"; import ButtonSelect from "../ButtonSelect"; import { isPerfectTense } from "../../lib/phrase-building/vp-tools"; -const tenseOptions: { label: string | JSX.Element, value: T.VerbTense }[] = [{ +const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense }[] = [{ label:
present
, value: "presentVerb", }, { @@ -55,34 +55,53 @@ const perfectTenseOptions: { label: string | JSX.Element, value: T.PerfectTense value: "pastSubjunctive perfect", }]; -function TensePicker({ onChange, verb, mode }: { - verb: T.VerbSelection, - onChange: (p: T.VerbSelection) => void, +export function getRandomTense(type: "basic" | "modal", o?: T.VerbTense): T.VerbTense; +export function getRandomTense(type: "perfect", o?: T.PerfectTense | T.VerbTense): T.PerfectTense; +export function getRandomTense(type: "basic" | "modal" | "perfect", o?: T.PerfectTense | T.VerbTense): T.PerfectTense | T.VerbTense { + let tns: T.PerfectTense | T.VerbTense; + const tenseOptions = type === "perfect" ? perfectTenseOptions : verbTenseOptions; + do { + tns = tenseOptions[ + Math.floor(Math.random()*tenseOptions.length) + ].value; + } while (o === tns); + return tns; +} + +function TensePicker({ onChange, vps, mode }: { + vps: T.VPSelectionState, + onChange: (p: T.VPSelectionState) => void, mode: "charts" | "phrases" | "quiz", }) { function onTenseSelect(o: { value: T.VerbTense | T.PerfectTense } | null) { const value = o?.value ? o.value : undefined; - if (verb && value) { + if (vps.verb && value) { if (isPerfectTense(value)) { onChange({ - ...verb, - tense: value, - tenseCategory: "perfect", + ...vps, + verb: { + ...vps.verb, + tense: value, + tenseCategory: "perfect", + }, }); } else { onChange({ - ...verb, - tense: value, - tenseCategory: verb.tenseCategory === "perfect" ? "basic" : verb.tenseCategory, + ...vps, + verb: { + ...vps.verb, + tense: value, + tenseCategory: vps.verb.tenseCategory === "perfect" ? "basic" : vps.verb.tenseCategory, + }, }); } } } function moveTense(dir: "forward" | "back") { - if (!verb) return; + if (!vps.verb) return; return () => { - const tenses = verb.tenseCategory === "perfect" ? perfectTenseOptions : tenseOptions; - const currIndex = tenses.findIndex(tn => tn.value === verb.tense) + const tenses = vps.verb.tenseCategory === "perfect" ? perfectTenseOptions : verbTenseOptions; + const currIndex = tenses.findIndex(tn => tn.value === vps.verb.tense) if (currIndex === -1) { console.error("error moving tense", dir); return; @@ -95,39 +114,48 @@ function TensePicker({ onChange, verb, mode }: { }; } function onPosNegSelect(value: string) { - if (verb) { + if (vps.verb) { onChange({ - ...verb, - negative: value === "true", + ...vps, + verb: { + ...vps.verb, + negative: value === "true", + }, }); } } function onTenseCategorySelect(value: "basic" | "modal" | "perfect") { - if (verb) { + if (vps.verb) { if (value === "perfect") { onChange({ - ...verb, - tenseCategory: value, - tense: isPerfectTense(verb.tense) ? verb.tense : "present perfect", + ...vps, + verb: { + ...vps.verb, + tenseCategory: value, + tense: isPerfectTense(vps.verb.tense) ? vps.verb.tense : "present perfect", + }, }); } else { onChange({ - ...verb, - tenseCategory: value, - tense: isPerfectTense(verb.tense) ? "presentVerb" : verb.tense, + ...vps, + verb: { + ...vps.verb, + tenseCategory: value, + tense: isPerfectTense(vps.verb.tense) ? "presentVerb" : vps.verb.tense, + } }); } } } - const tOptions = (verb?.tenseCategory === "perfect") ? perfectTenseOptions : tenseOptions; + const tOptions = (vps.verb?.tenseCategory === "perfect") ? perfectTenseOptions : verbTenseOptions; return
Tense:
- {verb &&
+ {vps.verb &&
o.value === verb.tense))} + value={vps.verb && ([...verbTenseOptions, ...perfectTenseOptions].find(o => o.value === vps.verb.tense))} onChange={onTenseSelect} className="mb-2" options={tOptions} {...zIndexProps} /> - {verb &&
+ {vps.verb &&
{mode !== "charts" && ({ removeKing: false, shrinkServant: false }, "abbreviationForm"); const [OSV, setOSV] = useStickyState(false, "includeOSV"); const result = compileVP(renderVP(VP), { ...form, OSV }); @@ -46,7 +46,7 @@ function VPDisplay({ VP, opts }: { VP: T.VPSelection, opts: T.TextOptions }) {
} -function whatsAdjustable(VP: T.VPSelection): "both" | "king" | "servant" { +function whatsAdjustable(VP: T.VPSelectionComplete): "both" | "king" | "servant" { // TODO: intransitive dynamic compounds? return (VP.verb.isCompound === "dynamic" && VP.verb.transitivity === "transitive") ? (isPastTense(VP.verb.tense) ? "servant" : "king") diff --git a/src/components/vp-explorer/VPExplorer.tsx b/src/components/vp-explorer/VPExplorer.tsx index 85d38b0..8c51d65 100644 --- a/src/components/vp-explorer/VPExplorer.tsx +++ b/src/components/vp-explorer/VPExplorer.tsx @@ -1,6 +1,6 @@ import NPPicker from "../np-picker/NPPicker"; import VerbPicker from "./VerbPicker"; -import TensePicker from "./TensePicker"; +import TensePicker, { getRandomTense } from "./TensePicker"; import VPDisplay from "./VPDisplay"; import ButtonSelect from "../ButtonSelect"; import { renderVP } from "../../lib/phrase-building/index"; @@ -10,7 +10,7 @@ import { import * as T from "../../types"; import ChartDisplay from "./ChartDisplay"; import useStickyState from "../../lib/useStickyState"; -import { makeVerbSelection } from "./verb-selection"; +import { makeVPSelectionState } from "./verb-selection"; import { useEffect, useState } from "react"; import { randomSubjObj } from "../../library"; @@ -29,6 +29,8 @@ const servantEmoji = "🙇‍♂️"; // TODO: option to show 3 modes Phrases - Charts - Quiz // TODO: error handling on error with rendering etc +type MixState = "NPs" | "tenses" | "both"; + export function VPExplorer(props: { verb: T.VerbEntry, opts: T.TextOptions, @@ -41,35 +43,22 @@ export function VPExplorer(props: { getNounByTs: (ts: number) => T.NounEntry | undefined, getVerbByTs: (ts: number) => T.VerbEntry | undefined, })) { - console.log("passedVerb", props.verb); - const [subject, setSubject] = useStickyState(undefined, "subjectNPSelection"); - // not quite working with stickyState + const [vps, setVps] = useStickyState( + o => makeVPSelectionState(props.verb, o), + "vpsState1", + ); const [mode, setMode] = useStickyState<"charts" | "phrases" | "quiz">("phrases", "verbExplorerMode"); + const [mix, setMix] = useStickyState("NPs", "mixState1"); const [showAnswer, setShowAnswer] = useState(false); - // this isn't quite working - // const [verb, setVerb] = useStickyState( - // passedVerb - // ? (old) => makeVerbSelection(passedVerb, setSubject, old) - // : undefined, - // "verbExplorerVerb", - // ); - const [verb, setVerb] = useState( - makeVerbSelection(props.verb, setSubject) - ) useEffect(() => { - if (mode === "quiz") { - if (!verb) setMode("phrases"); - handleResetQuiz(); - } - // TODO: better system with all this - // eslint-disable-next-line - }, []); - useEffect(() => { - setVerb(o => makeVerbSelection(props.verb, setSubject, o)); - if (mode === "quiz") { - // TODO: Better - setMode("charts"); - } + setVps(o => { + if (mode === "quiz") { + return setRandomQuizState(mix)( + makeVPSelectionState(props.verb, o) + ); + } + return makeVPSelectionState(props.verb, o); + }); // eslint-disable-next-line }, [props.verb]); function handleChangeMode(m: "charts" | "phrases" | "quiz") { @@ -78,46 +67,42 @@ export function VPExplorer(props: { } setMode(m); } - function handleSetVerb(v: T.VerbSelection) { - if (v?.verb.entry.ts !== verb?.verb.entry.ts) { - handleResetQuiz(); - } - setVerb(v); - } function handleResetQuiz() { - if (!verb) { + if (!vps.verb) { alert("Choose a verb to quiz"); return; } - const { S, V } = setRandomQuizState(subject, verb); setShowAnswer(false); - setSubject(S); - setVerb(V); + setVps(setRandomQuizState(mix)); } function handleSubjectChange(subject: T.NPSelection | undefined, skipPronounConflictCheck?: boolean) { - if (!skipPronounConflictCheck && hasPronounConflict(subject, verb?.object)) { + if (!skipPronounConflictCheck && hasPronounConflict(subject, vps.verb?.object)) { alert("That combination of pronouns is not allowed"); return; } - setSubject(subject); + setVps(o => ({ ...o, subject })); } function handleObjectChange(object: T.NPSelection | undefined) { - if (!verb) return; - if ((verb.object === "none") || (typeof verb.object === "number")) return; + if (!vps.verb) return; + if ((vps.verb.object === "none") || (typeof vps.verb.object === "number")) return; // check for pronoun conflict - if (hasPronounConflict(subject, object)) { + if (hasPronounConflict(vps.subject, object)) { alert("That combination of pronouns is not allowed"); return; } - setVerb({ ...verb, object }); + setVps(o => ({ + ...o, + verb: { + ...o.verb, + object, + }, + })); } function handleSubjObjSwap() { - if (verb?.isCompound === "dynamic") return; - const output = switchSubjObj({ subject, verb }); - setSubject(output.subject); - setVerb(output.verb); + if (vps.verb?.isCompound === "dynamic") return; + setVps(switchSubjObj) } - const verbPhrase: T.VPSelection | undefined = verbPhraseComplete({ subject, verb }); + const verbPhrase: T.VPSelectionComplete | undefined = completeVPSelection(vps); const VPRendered = verbPhrase && renderVP(verbPhrase); return
handleSubjectChange(s, true)} - onChange={handleSetVerb} + vps={vps} + onChange={setVps} opts={props.opts} />
@@ -145,7 +127,20 @@ export function VPExplorer(props: { handleChange={handleChangeMode} />
- {(verb && (typeof verb.object === "object") && (verb.isCompound !== "dynamic") && (mode === "phrases")) && + {mode === "quiz" &&
+
Mix:
+ +
} + {(vps.verb && (typeof vps.verb.object === "object") && (vps.verb.isCompound !== "dynamic") && (mode === "phrases")) &&
- {verb && (verb.object !== "none") &&
+ {vps.verb && (vps.verb.object !== "none") &&
Object {showRole(VPRendered, "object")}
- {(typeof verb.object === "number") + {(typeof vps.verb.object === "number") ?
Unspoken 3rd Pers. Masc. Plur.
: }
- {(verb && (mode === "quiz")) &&
+ {(vps.verb && (mode === "quiz")) &&
} export default VPExplorer; +function completeVPSelection(vps: T.VPSelectionState): T.VPSelectionComplete | undefined { + if (vps.subject === undefined) return undefined + if (vps.verb.object === undefined) return undefined; + const verb = vps.verb; + return { + type: "VPSelectionComplete", + subject: vps.subject, + object: vps.verb.object, + verb, + } +} + function hasPronounConflict(subject: T.NPSelection | undefined, object: undefined | T.VerbObject): boolean { const subjPronoun = (subject && subject.type === "pronoun") ? subject : undefined; const objPronoun = (object && typeof object === "object" && object.type === "pronoun") ? object : undefined; @@ -231,18 +239,6 @@ function hasPronounConflict(subject: T.NPSelection | undefined, object: undefine return isInvalidSubjObjCombo(subjPronoun.person, objPronoun.person); } -function verbPhraseComplete({ subject, verb }: { subject: T.NPSelection | undefined, verb: T.VerbSelection }): T.VPSelection | undefined { - if (!subject) return undefined; - if (!verb) return undefined; - if (verb.object === undefined) return undefined; - return { - type: "VPSelection", - subject, - object: verb.object, - verb, - }; -} - function showRole(VP: T.VPRendered | undefined, member: "subject" | "object") { return VP ? @@ -251,8 +247,7 @@ function showRole(VP: T.VPRendered | undefined, member: "subject" | "object") { : ""; } -type SOClump = { subject: T.NPSelection | undefined, verb: T.VerbSelection }; -function switchSubjObj({ subject, verb }: SOClump): SOClump { +function switchSubjObj({ subject, verb }: T.VPSelectionState): T.VPSelectionState { if (!subject|| !verb || !verb.object || !(typeof verb.object === "object")) { return { subject, verb }; } @@ -265,39 +260,41 @@ function switchSubjObj({ subject, verb }: SOClump): SOClump { }; } -function setRandomQuizState(subject: T.NPSelection | undefined, verb: T.VerbSelection): { - S: T.NPSelection, - V: T.VerbSelection, -} { - const oldSubj = (subject?.type === "pronoun") - ? subject.person - : undefined; - const oldObj = (typeof verb?.object === "object" && verb.object.type === "pronoun") - ? verb.object.person - : undefined; - const { subj, obj } = randomSubjObj( - oldSubj !== undefined ? { subj: oldSubj, obj: oldObj } : undefined - ); - const randSubj: T.PronounSelection = subject?.type === "pronoun" ? { - ...subject, - person: subj, - } : { - type: "pronoun", - distance: "far", - person: subj, - }; - const randObj: T.PronounSelection = typeof verb?.object === "object" && verb.object.type === "pronoun" ? { - ...verb.object, - person: obj, - } : { - type: "pronoun", - distance: "far", - person: obj, - }; - return { - // TODO: Randomize the near/far ?? - S: randSubj, - V: { +function setRandomQuizState(mix: MixState) { + return ({ subject, verb }: T.VPSelectionState): T.VPSelectionState => { + if (mix === "tenses") { + return { + subject, + verb: randomizeTense(verb, true), + } + } + const oldSubj = (subject?.type === "pronoun") + ? subject.person + : undefined; + const oldObj = (typeof verb?.object === "object" && verb.object.type === "pronoun") + ? verb.object.person + : undefined; + const { subj, obj } = randomSubjObj( + oldSubj !== undefined ? { subj: oldSubj, obj: oldObj } : undefined + ); + const randSubj: T.PronounSelection = subject?.type === "pronoun" ? { + ...subject, + person: subj, + } : { + type: "pronoun", + distance: "far", + person: subj, + }; + const randObj: T.PronounSelection = typeof verb?.object === "object" && verb.object.type === "pronoun" ? { + ...verb.object, + person: obj, + } : { + type: "pronoun", + distance: "far", + person: obj, + }; + const s = randSubj; + const v: T.VerbSelection = { ...verb, object: ( (typeof verb.object === "object" && !(verb.object.type === "noun" && verb.object.dynamicComplement)) @@ -306,6 +303,22 @@ function setRandomQuizState(subject: T.NPSelection | undefined, verb: T.VerbSele ) ? randObj : verb.object, - }, - } + }; + return { + subject: s, + verb: mix === "both" ? randomizeTense(v, false) : v, + }; + }; +}; + +function randomizeTense(verb: T.VerbSelection, dontRepeatTense: boolean): T.VerbSelection { + return { + ...verb, + tense: getRandomTense( + // TODO: WHY ISN'T THE OVERLOADING ON THIS + // @ts-ignore + verb.tenseCategory, + dontRepeatTense ? verb.tense : undefined, + ), + }; } \ No newline at end of file diff --git a/src/components/vp-explorer/VerbPicker.tsx b/src/components/vp-explorer/VerbPicker.tsx index 1645dfc..cb4316d 100644 --- a/src/components/vp-explorer/VerbPicker.tsx +++ b/src/components/vp-explorer/VerbPicker.tsx @@ -3,93 +3,68 @@ import ButtonSelect from "../ButtonSelect"; import { RootsAndStems } from "../verb-info/VerbInfo"; import { getVerbInfo } from "../../lib/verb-info"; import Hider from "../Hider"; -import { makeVerbSelection } from "./verb-selection"; -import EntrySelect from "../EntrySelect"; import useStickyState from "../../lib/useStickyState"; // TODO: dark on past tense selecitons -function VerbPicker(props: ({ - verbs: T.VerbEntry[], -} | { - verbs: (s: string) => T.VerbEntry[], - getVerbByTs: (ts: number) => T.VerbEntry | undefined; -}) & { - verb: T.VerbSelection, - subject: T.NPSelection | undefined, - onChange: (p: T.VerbSelection) => void, - changeSubject: (p: T.NPSelection | undefined) => void, +function VerbPicker(props: { + vps: T.VPSelectionState, + onChange: (p: T.VPSelectionState) => void, opts: T.TextOptions, - verbLocked: boolean, }) { const [showRootsAndStems, setShowRootsAndStems] = useStickyState(false, "showRootsAndStems"); - const infoRaw = props.verb ? getVerbInfo(props.verb.verb.entry, props.verb.verb.complement) : undefined; - const info = (!infoRaw || !props.verb) + const infoRaw = props.vps.verb ? getVerbInfo(props.vps.verb.verb.entry, props.vps.verb.verb.complement) : undefined; + const info = (!infoRaw || !props.vps.verb) ? undefined : ("stative" in infoRaw) - ? infoRaw[props.verb.isCompound === "stative" ? "stative" : "dynamic"] + ? infoRaw[props.vps.verb.isCompound === "stative" ? "stative" : "dynamic"] : ("transitive" in infoRaw) - ? infoRaw[props.verb.transitivity === "grammatically transitive" ? "grammaticallyTransitive" : "transitive"] + ? infoRaw[props.vps.verb.transitivity === "grammatically transitive" ? "grammaticallyTransitive" : "transitive"] : infoRaw; if (info && ("stative" in info || "transitive" in info)) { return
ERROR: Verb version should be select first
; } - // const [filters, useFilters] = useState({ - // stative: true, - // dynamic: true, - // transitive: true, - // intransitive: true, - // grammaticallyTransitive: true, - // }); - function onVerbSelect(v: T.VerbEntry | undefined) { - // TODO: what to do when clearing - if (!v) { - return; - } - props.onChange(makeVerbSelection(v, props.changeSubject, props.verb)); - } function onVoiceSelect(value: "active" | "passive") { - if (props.verb && props.verb.changeVoice) { - if (value === "passive" && (typeof props.verb.object === "object")) { - props.changeSubject(props.verb.object); + if (props.vps.verb && props.vps.verb.changeVoice) { + if (value === "passive" && (typeof props.vps.verb.object === "object")) { + props.onChange({ + ...props.vps, + subject: props.vps.verb.object, + }) } if (value === "active") { - props.changeSubject(undefined); + props.onChange({ + ...props.vps, + subject: undefined, + }); } - props.onChange(props.verb.changeVoice(value, value === "active" ? props.subject : undefined)); + props.onChange({ + ...props.vps, + verb: props.vps.verb.changeVoice(value, value === "active" ? props.vps.subject : undefined), + }); } } function notInstransitive(t: "transitive" | "intransitive" | "grammatically transitive"): "transitive" | "grammatically transitive" { return t === "intransitive" ? "transitive" : t; } function handleChangeTransitivity(t: "transitive" | "grammatically transitive") { - if (props.verb && props.verb.changeTransitivity) { - props.onChange(props.verb.changeTransitivity(t)); + if (props.vps.verb && props.vps.verb.changeTransitivity) { + props.onChange({ + ...props.vps, + verb: props.vps.verb.changeTransitivity(t), + }); } } function handleChangeStatDyn(c: "stative" | "dynamic") { - if (props.verb && props.verb.changeStatDyn) { - props.onChange(props.verb.changeStatDyn(c)); + if (props.vps.verb && props.vps.verb.changeStatDyn) { + props.onChange({ + ...props.vps, + verb: props.vps.verb.changeStatDyn(c), + }); } } return
- {!props.verbLocked &&
-
Verb:
- -
} {info &&
}
- {props.verb && props.verb.changeTransitivity &&
+ {props.vps.verb && props.vps.verb.changeTransitivity &&
} - {props.verb && props.verb.changeVoice &&
+ {props.vps.verb && props.vps.verb.changeVoice &&
} - {props.verb && props.verb.changeStatDyn &&
+ {props.vps.verb && props.vps.verb.changeStatDyn &&
} diff --git a/src/components/vp-explorer/verb-selection.ts b/src/components/vp-explorer/verb-selection.ts index f94a106..5829c67 100644 --- a/src/components/vp-explorer/verb-selection.ts +++ b/src/components/vp-explorer/verb-selection.ts @@ -5,31 +5,34 @@ import * as T from "../../types"; import { getVerbInfo } from "../../lib/verb-info"; import { isPerfectTense } from "../../lib/phrase-building/vp-tools"; -export function makeVerbSelection(verb: T.VerbEntry, changeSubject: (s: T.NPSelection | undefined) => void, oldVerbSelection?: T.VerbSelection): T.VerbSelection { +export function makeVPSelectionState( + verb: T.VerbEntry, + os?: T.VPSelectionState, +): T.VPSelectionState { const info = getVerbInfo(verb.entry, verb.complement); - function getTransObjFromOldVerbSelection() { + const subject = (os?.verb.voice === "passive" && info.type === "dynamic compound") + ? makeNounSelection(info.objComplement.entry as T.NounEntry, true) + : (os?.subject || undefined); + function getTransObjFromos() { if ( - !oldVerbSelection || - oldVerbSelection.object === "none" || - typeof oldVerbSelection.object === "number" || - oldVerbSelection.isCompound === "dynamic" || - (oldVerbSelection.object?.type === "noun" && oldVerbSelection.object.dynamicComplement) + !os || + os.verb.object === "none" || + typeof os.verb.object === "number" || + os.verb.isCompound === "dynamic" || + (os.verb.object?.type === "noun" && os.verb.object.dynamicComplement) ) return undefined; - return oldVerbSelection.object; + return os.verb.object; } const transitivity: T.Transitivity = "grammaticallyTransitive" in info ? "transitive" : info.transitivity; const object = (transitivity === "grammatically transitive") ? T.Person.ThirdPlurMale - : (info.type === "dynamic compound" && oldVerbSelection?.voice !== "passive") + : (info.type === "dynamic compound" && os?.verb.voice !== "passive") ? makeNounSelection(info.objComplement.entry as T.NounEntry, true) - : (transitivity === "transitive" && oldVerbSelection?.voice !== "passive") - ? getTransObjFromOldVerbSelection() + : (transitivity === "transitive" && os?.verb.voice !== "passive") + ? getTransObjFromos() : "none"; - if (oldVerbSelection?.voice === "passive" && info.type === "dynamic compound") { - changeSubject(makeNounSelection(info.objComplement.entry as T.NounEntry, true)); - } const isCompound = ("stative" in info || info.type === "stative compound") ? "stative" : info.type === "dynamic compound" @@ -47,60 +50,63 @@ export function makeVerbSelection(verb: T.VerbEntry, changeSubject: (s: T.NPSele tenseCategory: "basic" | "modal", tense: T.VerbTense, } => { - if (!oldVerbSelection) { + if (!os) { return { tense: "presentVerb", tenseCategory: "basic" }; } - if (oldVerbSelection.tenseCategory === "modal") { - return { tenseCategory: "modal", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense }; + if (os.verb.tenseCategory === "modal") { + return { tenseCategory: "modal", tense: isPerfectTense(os.verb.tense) ? "presentVerb" : os.verb.tense }; } - if (oldVerbSelection.tenseCategory === "basic") { - return { tenseCategory: "basic", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense }; + if (os.verb.tenseCategory === "basic") { + return { tenseCategory: "basic", tense: isPerfectTense(os.verb.tense) ? "presentVerb" : os.verb.tense }; } - return { tenseCategory: "perfect", tense: isPerfectTense(oldVerbSelection.tense) ? oldVerbSelection.tense : "present perfect" }; + return { tenseCategory: "perfect", tense: isPerfectTense(os.verb.tense) ? os.verb.tense : "present perfect" }; })(); return { - type: "verb", - verb: verb, - dynAuxVerb, - ...tenseSelection, - object, - transitivity, - isCompound, - voice: transitivity === "transitive" - ? (oldVerbSelection?.voice || "active") - : "active", - negative: oldVerbSelection ? oldVerbSelection.negative : false, - ...("grammaticallyTransitive" in info) ? { - changeTransitivity: function(t) { - return { - ...this, - transitivity: t, - object: t === "grammatically transitive" ? T.Person.ThirdPlurMale : undefined, - }; - }, - } : {}, - ...("stative" in info) ? { - changeStatDyn: function(c) { - return { - ...this, - isCompound: c, - object: c === "dynamic" - ? makeNounSelection(info.dynamic.objComplement.entry as T.NounEntry, true) - : undefined, - dynAuxVerb: c === "dynamic" - ? { entry: info.dynamic.auxVerb } as T.VerbEntry - : undefined, - }; - } - } : {}, - ...(transitivity === "transitive") ? { - changeVoice: function(v, s) { - return { - ...this, - voice: v, - object: v === "active" ? s : "none", - }; - }, - } : {}, + subject, + verb: { + type: "verb", + verb: verb, + dynAuxVerb, + ...tenseSelection, + object, + transitivity, + isCompound, + voice: transitivity === "transitive" + ? (os?.verb.voice || "active") + : "active", + negative: os ? os.verb.negative : false, + ...("grammaticallyTransitive" in info) ? { + changeTransitivity: function(t) { + return { + ...this, + transitivity: t, + object: t === "grammatically transitive" ? T.Person.ThirdPlurMale : undefined, + }; + }, + } : {}, + ...("stative" in info) ? { + changeStatDyn: function(c) { + return { + ...this, + isCompound: c, + object: c === "dynamic" + ? makeNounSelection(info.dynamic.objComplement.entry as T.NounEntry, true) + : undefined, + dynAuxVerb: c === "dynamic" + ? { entry: info.dynamic.auxVerb } as T.VerbEntry + : undefined, + }; + } + } : {}, + ...(transitivity === "transitive") ? { + changeVoice: function(v, s) { + return { + ...this, + voice: v, + object: v === "active" ? s : "none", + }; + }, + } : {}, + }, }; } diff --git a/src/lib/phrase-building/render-vp.ts b/src/lib/phrase-building/render-vp.ts index 6142dc4..454ab3e 100644 --- a/src/lib/phrase-building/render-vp.ts +++ b/src/lib/phrase-building/render-vp.ts @@ -27,7 +27,7 @@ import { renderEnglishVPBase } from "./english-vp-rendering"; // TODO: ISSUE GETTING SPLIT HEAD NOT MATCHING WITH FUTURE VERBS -export function renderVP(VP: T.VPSelection): T.VPRendered { +export function renderVP(VP: T.VPSelectionComplete): T.VPRendered { // Sentence Rules Logic const isPast = isPastTense(VP.verb.tense); const isTransitive = VP.object !== "none"; diff --git a/src/library.ts b/src/library.ts index d3e7108..219bd46 100644 --- a/src/library.ts +++ b/src/library.ts @@ -15,7 +15,6 @@ import { import { getVerbInfo, } from "./lib/verb-info"; -import { makeVerbSelection } from "./components/vp-explorer/verb-selection"; import ConjugationViewer from "./components/ConjugationViewer"; import InflectionsTable from "./components/InflectionsTable"; import Pashto from "./components/Pashto"; @@ -164,7 +163,6 @@ export { capitalizeFirstLetter, psStringFromEntry, getLong, - makeVerbSelection, useStickyState, randomPerson, isInvalidSubjObjCombo, diff --git a/src/types.ts b/src/types.ts index 9e580de..2f500b5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -508,13 +508,6 @@ export type Words = { adverbs: AdverbEntry[], } -export type VPSelection = { - type: "VPSelection", - subject: NPSelection, - object: Exclude, - verb: Exclude, -}; - // TODO: make this Rendered with recursive Rendered<> export type VPRendered = { type: "VPRendered", @@ -543,6 +536,18 @@ export type NounNumber = "singular" | "plural"; export type PerfectTense = `${EquativeTense} perfect`; +export type VPSelectionState = { + subject: NPSelection | undefined, + verb: VerbSelection, +}; + +export type VPSelectionComplete = { + type: "VPSelectionComplete", + subject: NPSelection, + object: Exclude, + verb: Exclude, +}; + export type VerbSelection = { type: "verb", verb: VerbEntry,