From 174e34f069d5d577d3913e08bc6f8cc8bd492cd6 Mon Sep 17 00:00:00 2001 From: adueck Date: Tue, 26 Sep 2023 15:53:28 -0400 Subject: [PATCH] display editable VPs --- src/App.tsx | 2 +- src/components/src/vp-explorer/EditableVP.tsx | 91 +++++++++++++++++++ src/demo-components/ParserDemo.tsx | 69 ++++++++------ src/lib/src/phrase-building/vp-tools.ts | 36 +++++++- src/lib/src/type-predicates.ts | 21 +++-- src/types.ts | 2 +- 6 files changed, 179 insertions(+), 42 deletions(-) create mode 100644 src/components/src/vp-explorer/EditableVP.tsx diff --git a/src/App.tsx b/src/App.tsx index 7870661..749a2e1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -138,7 +138,7 @@ function App() { showing={showing === "parser"} handleChange={() => handleHiderClick("parser")} > - + diff --git a/src/components/src/vp-explorer/EditableVP.tsx b/src/components/src/vp-explorer/EditableVP.tsx new file mode 100644 index 0000000..6c7fc68 --- /dev/null +++ b/src/components/src/vp-explorer/EditableVP.tsx @@ -0,0 +1,91 @@ +import * as T from "../../../types"; +import { useEffect, useState } from "react"; +import VPDisplay from "./VPDisplay"; +import VPPicker from "./VPPicker"; +import { vpsReducer } from "../../../lib/src/phrase-building/vps-reducer"; + +export function EditIcon() { + return ; +} + +// TODO: Ability to show all variations + +function EditableVP({ + children, + opts, + formChoice, + noEdit, + length, + mode, + sub, + allVariations, + entryFeeder, +}: { + children: T.VPSelectionState; + opts: T.TextOptions; + formChoice?: boolean; + noEdit?: boolean; + length?: "long" | "short"; + mode?: "text" | "blocks"; + sub?: string | JSX.Element; + allVariations?: boolean; + entryFeeder: T.EntryFeeder; +}) { + const [editing, setEditing] = useState(false); + const [selectedLength, setSelectedLength] = useState<"long" | "short">( + length || "short" + ); + const [vps, setVps] = useState({ ...children }); + useEffect(() => { + setVps({ ...children }); + }, [children]); + function handleReset() { + // TODO: this is crazy, how does children get changed after calling setVps ??? + setVps(children); + setEditing(false); + } + function handleSetForm(form: T.FormVersion) { + setVps(vpsReducer(vps, { type: "set form", payload: form })); + } + return ( +
+ {!noEdit && ( +
{ + setEditing(true); + } + } + > + {!editing ? : } +
+ )} + {editing && ( + + )} + + {sub &&
{sub}
} +
+ ); +} + +export default EditableVP; diff --git a/src/demo-components/ParserDemo.tsx b/src/demo-components/ParserDemo.tsx index 5389d03..12f57f3 100644 --- a/src/demo-components/ParserDemo.tsx +++ b/src/demo-components/ParserDemo.tsx @@ -2,12 +2,9 @@ import { useState } from "react"; import * as T from "../types"; import { parsePhrase } from "../lib/src/parsing/parse-phrase"; import { tokenizer } from "../lib/src/parsing/tokenizer"; -import { - CompiledPTextDisplay, - NPDisplay, - compileVP, - renderVP, -} from "../components/library"; +import { NPDisplay } from "../components/library"; +import EditableVP from "../components/src/vp-explorer/EditableVP"; +import { uncompleteVPSelection } from "../lib/src/phrase-building/vp-tools"; const working = [ "limited demo vocab", @@ -46,7 +43,13 @@ const examples = [ "وبه مې وینې", ]; -function ParserDemo({ opts }: { opts: T.TextOptions }) { +function ParserDemo({ + opts, + entryFeeder, +}: { + opts: T.TextOptions; + entryFeeder: T.EntryFeeder; +}) { const [text, setText] = useState(""); const [result, setResult] = useState< ReturnType["success"] @@ -129,29 +132,37 @@ function ParserDemo({ opts }: { opts: T.TextOptions }) { "inflected" in res ? ( ) : "verb" in res ? ( - (() => { - try { - const rendered = renderVP(res); - const compiled = compileVP(rendered, res.form); - return ( -
- - {compiled.e && ( -
- {compiled.e.map((e, i) => ( -
{e}
- ))} -
- )} -
- ); - } catch (e) { - console.error(e); - console.log({ res }); - return
ERROR
; - } - })() + + {uncompleteVPSelection(res)} + ) : ( + // (() => { + // try { + // const rendered = renderVP(res); + // const compiled = compileVP(rendered, res.form); + // return ( + //
+ // + // {compiled.e && ( + //
+ // {compiled.e.map((e, i) => ( + //
{e}
+ // ))} + //
+ // )} + //
+ // ); + // } catch (e) { + // console.error(e); + // console.log({ res }); + // return
ERROR
; + // } + // })()
{JSON.stringify(res, null, "  ")}
diff --git a/src/lib/src/phrase-building/vp-tools.ts b/src/lib/src/phrase-building/vp-tools.ts index e7b355b..b65f16b 100644 --- a/src/lib/src/phrase-building/vp-tools.ts +++ b/src/lib/src/phrase-building/vp-tools.ts @@ -1,6 +1,10 @@ import * as T from "../../../types"; import { concatPsString, psRemove, psStringEquals } from "../p-text-helpers"; -import { isPerfectTense } from "../type-predicates"; +import { + isImperativeTense, + isPerfectTense, + isVerbTense, +} from "../type-predicates"; import * as grammarUnits from "../grammar-units"; import { isSecondPerson, randomNumber } from "../misc-helpers"; import { @@ -278,6 +282,36 @@ export function completeVPSelection( }; } +export function uncompleteVPSelection( + vps: T.VPSelectionComplete +): T.VPSelectionState { + const tense = vps.verb.tense; + const tenseCategory = isVerbTense(tense) + ? "basic" + : isPerfectTense(tense) + ? "perfect" + : isImperativeTense(tense) + ? "modal" + : "imperative"; + return { + ...vps, + verb: { + ...vps.verb, + verbTense: + tenseCategory === "basic" ? (tense as T.VerbTense) : "presentVerb", + perfectTense: + tenseCategory === "perfect" + ? (tense as T.PerfectTense) + : "presentPerfect", + imperativeTense: + tenseCategory === "imperative" + ? (tense as T.ImperativeTense) + : "imperfectiveImperative", + tenseCategory, + }, + }; +} + export function isThirdPerson(p: T.Person): boolean { return ( p === T.Person.ThirdSingMale || diff --git a/src/lib/src/type-predicates.ts b/src/lib/src/type-predicates.ts index 3c69cbc..1c1435b 100644 --- a/src/lib/src/type-predicates.ts +++ b/src/lib/src/type-predicates.ts @@ -3,6 +3,17 @@ import { pashtoConsonants } from "./pashto-consonants"; import { endsWith } from "./p-text-helpers"; import { countSyllables } from "./accent-helpers"; +const verbTenses: T.VerbTense[] = [ + "presentVerb", + "subjunctiveVerb", + "perfectiveFuture", + "imperfectiveFuture", + "perfectivePast", + "imperfectivePast", + "habitualPerfectivePast", + "habitualImperfectivePast", +]; + export function isTlulVerb(e: T.VerbEntry | T.VerbDictionaryEntry): boolean { const entry = "entry" in e ? e.entry : e; return ( @@ -276,16 +287,6 @@ export function isPerfectTense(tense: T.Tense): tense is T.PerfectTense { } export function isVerbTense(tense: T.Tense): tense is T.VerbTense { - const verbTenses: T.VerbTense[] = [ - "presentVerb", - "subjunctiveVerb", - "perfectiveFuture", - "imperfectiveFuture", - "perfectivePast", - "imperfectivePast", - "habitualPerfectivePast", - "habitualImperfectivePast", - ]; return verbTenses.some((x) => x === tense); } diff --git a/src/types.ts b/src/types.ts index ee80f26..9327976 100644 --- a/src/types.ts +++ b/src/types.ts @@ -787,7 +787,7 @@ export type VerbFormName = export type VerbSelectionComplete = Omit< VerbSelection, - "object" | "verbTense" | "perfectTense" | "imperativeTense" | "tenseCategory" + "verbTense" | "perfectTense" | "imperativeTense" | "tenseCategory" > & { tense: VerbFormName; };