From 759df4811e3819c714c9fa8c58fc97ac2e537c78 Mon Sep 17 00:00:00 2001 From: lingdocs <71590811+lingdocs@users.noreply.github.com> Date: Fri, 8 Apr 2022 11:54:47 +0500 Subject: [PATCH] refactoring to allow for dictionary lookup in phrase builder --- src/components/EntrySelect.tsx | 2 +- src/components/np-picker/NPNounPicker.tsx | 181 ++++++++++-------- .../np-picker/NPParticiplePicker.tsx | 25 ++- src/components/np-picker/NPPicker.tsx | 67 ++++--- .../phrase-builder/PhraseBuilder.tsx | 30 ++- src/content/practice-tools/phrase-builder.mdx | 10 +- 6 files changed, 195 insertions(+), 120 deletions(-) diff --git a/src/components/EntrySelect.tsx b/src/components/EntrySelect.tsx index 8e4548b..43ad568 100644 --- a/src/components/EntrySelect.tsx +++ b/src/components/EntrySelect.tsx @@ -13,7 +13,7 @@ function EntrySelect(props: ({ entries: E[] } | { searchF: (search: string) => E[], - getByTs: (ts: number) => E, + getByTs: (ts: number) => E | undefined, }) & { value: E | undefined, onChange: (value: E | undefined) => void, diff --git a/src/components/np-picker/NPNounPicker.tsx b/src/components/np-picker/NPNounPicker.tsx index fc00224..6decfdf 100644 --- a/src/components/np-picker/NPNounPicker.tsx +++ b/src/components/np-picker/NPNounPicker.tsx @@ -6,83 +6,93 @@ import { InlinePs, Types as T, } from "@lingdocs/pashto-inflector"; -import { useState } from "react"; -import { isFemNounEntry, isPattern1Entry, isPattern2Entry, isPattern3Entry, isPattern4Entry, isPattern5Entry, isPattern6FemEntry } from "../../lib/type-predicates"; +// import { useState } from "react"; +// import { isFemNounEntry, isPattern1Entry, isPattern2Entry, isPattern3Entry, isPattern4Entry, isPattern5Entry, isPattern6FemEntry } from "../../lib/type-predicates"; import EntrySelect from "../EntrySelect"; -const filterOptions = [ - { - label: "1", - value: "1", - }, - { - label: "2", - value: "2", - }, - { - label: "3", - value: "3", - }, - { - label: "4", - value: "4", - }, - { - label: "5", - value: "5", - }, - { - label: "6", - value: "6", - }, -]; +// const filterOptions = [ +// { +// label: "1", +// value: "1", +// }, +// { +// label: "2", +// value: "2", +// }, +// { +// label: "3", +// value: "3", +// }, +// { +// label: "4", +// value: "4", +// }, +// { +// label: "5", +// value: "5", +// }, +// { +// label: "6", +// value: "6", +// }, +// ]; -type FilterPattern = "1" | "2" | "3" | "4" | "5" | "6"; +// type FilterPattern = "1" | "2" | "3" | "4" | "5" | "6"; -function nounFilter(p: FilterPattern | undefined) { - return p === undefined - ? () => true - : (p === "1") - ? isPattern1Entry - : (p === "2") - ? isPattern2Entry - : (p === "3") - ? isPattern3Entry - : (p === "4") - ? isPattern4Entry - : (p === "5") - ? isPattern5Entry - : (p === "6") - ? (n: NounEntry) => (isFemNounEntry(n) && isPattern6FemEntry(n)) - : () => true; -} +// function nounFilter(p: FilterPattern | undefined) { +// return p === undefined +// ? () => true +// : (p === "1") +// ? isPattern1Entry +// : (p === "2") +// ? isPattern2Entry +// : (p === "3") +// ? isPattern3Entry +// : (p === "4") +// ? isPattern4Entry +// : (p === "5") +// ? isPattern5Entry +// : (p === "6") +// ? (n: NounEntry) => (isFemNounEntry(n) && isPattern6FemEntry(n)) +// : () => true; +// } -function NPNounPicker({ onChange, noun, nouns, clearButton, opts }: { nouns: NounEntry[], noun: NounSelection | undefined, onChange: (p: NounSelection | undefined) => void, clearButton?: JSX.Element, opts: T.TextOptions }) { - const [patternFilter, setPatternFilter] = useState(undefined); - const [showFilter, setShowFilter] = useState(false) - const nounsFiltered = nouns - .filter(nounFilter(patternFilter)) - .sort((a, b) => (a.p.localeCompare(b.p, "af-PS"))); +function NPNounPicker(props: ({ + nouns: NounEntry[], +} | { + nouns: (s: string) => NounEntry[], + getNounByTs: (ts: number) => NounEntry | undefined; +}) & { + noun: NounSelection | undefined, + onChange: (p: NounSelection | undefined) => void, + clearButton?: JSX.Element, + opts: T.TextOptions, +}) { + // const [patternFilter, setPatternFilter] = useState(undefined); + // const [showFilter, setShowFilter] = useState(false) + // const nounsFiltered = props.nouns + // .filter(nounFilter(patternFilter)) + // .sort((a, b) => (a.p.localeCompare(b.p, "af-PS"))); function onEntrySelect(entry: NounEntry | undefined) { if (!entry) { - return onChange(undefined); + return props.onChange(undefined); } - onChange(makeNounSelection(entry)); - } - function handleFilterClose() { - setPatternFilter(undefined); - setShowFilter(false); + props.onChange(makeNounSelection(entry)); } + // function handleFilterClose() { + // setPatternFilter(undefined); + // setShowFilter(false); + // } return
-
- {clearButton} - {(!showFilter && !(noun?.dynamicComplement)) &&
+
+ {props.clearButton} + {/* {(!showFilter && !(noun?.dynamicComplement)) &&
-
} +
} */}
- {showFilter &&
+ {/* {showFilter &&
Filter by inflection pattern
X
@@ -94,54 +104,59 @@ function NPNounPicker({ onChange, noun, nouns, clearButton, opts }: { nouns: Nou // @ts-ignore handleChange={setPatternFilter} /> -
} - {!(noun && noun.dynamicComplement) ?
+
} */} + {!(props.noun && props.noun.dynamicComplement) ?
:
- {noun &&
+ {props.noun &&
Included in Dyn. Compound:
- - {{ p: noun.entry.p, f: noun.entry.f }} + + {{ p: props.noun.entry.p, f: props.noun.entry.f }} -
{noun.entry.e}
+
{props.noun.entry.e}
}
} - {noun &&
+ {props.noun &&
- {noun.changeGender ? { - if (!noun.changeGender) return; - onChange(noun.changeGender(g)); + if (!props.noun || !props.noun.changeGender) return; + props.onChange(props.noun.changeGender(g)); }} - /> : noun.gender === "masc" ? "Masc." : "Fem."} + /> : props.noun.gender === "masc" ? "Masc." : "Fem."}
- {noun.changeNumber ? { - if (!noun.changeNumber) return; - onChange(noun.changeNumber(n)); + if (!props.noun || !props.noun.changeNumber) return; + props.onChange(props.noun.changeNumber(n)); }} - /> : noun.number === "singular" ? "Sing." : "Plur."} + /> : props.noun.number === "singular" ? "Sing." : "Plur."}
}
; diff --git a/src/components/np-picker/NPParticiplePicker.tsx b/src/components/np-picker/NPParticiplePicker.tsx index 0e75f82..465ad5f 100644 --- a/src/components/np-picker/NPParticiplePicker.tsx +++ b/src/components/np-picker/NPParticiplePicker.tsx @@ -10,8 +10,12 @@ function makeParticipleSelection(verb: VerbEntry): ParticipleSelection { }; } -function NPParticiplePicker({ onChange, participle, verbs, clearButton, opts }: { +function NPParticiplePicker(props: ({ verbs: VerbEntry[], +} | { + verbs: (s: string) => VerbEntry[], + getVerbByTs: (ts: number) => VerbEntry | undefined; +}) & { participle: ParticipleSelection | undefined, onChange: (p: ParticipleSelection | undefined) => void, clearButton: JSX.Element, @@ -19,21 +23,26 @@ function NPParticiplePicker({ onChange, participle, verbs, clearButton, opts }: }) { function onEntrySelect(entry: VerbEntry | undefined) { if (!entry) { - onChange(undefined); + props.onChange(undefined); return; } - onChange(makeParticipleSelection(entry)); + props.onChange(makeParticipleSelection(entry)); } return
- {clearButton} + {props.clearButton} - {participle &&
+ {props.participle &&
Masc.
Plur.
} diff --git a/src/components/np-picker/NPPicker.tsx b/src/components/np-picker/NPPicker.tsx index 8be01e1..0913894 100644 --- a/src/components/np-picker/NPPicker.tsx +++ b/src/components/np-picker/NPPicker.tsx @@ -5,7 +5,6 @@ import ParticiplePicker from "./NPParticiplePicker"; // import { ButtonSelect } from "@lingdocs/pashto-inflector"; import { randomPerson } from "../../lib/np-tools"; import { useState, useEffect } from "react"; -import { nouns, verbs } from "../../words/words"; import { Types as T, } from "@lingdocs/pashto-inflector"; @@ -13,38 +12,46 @@ import { const npTypes: NPType[] = ["pronoun", "noun", "participle"]; -function NPPicker({ np, onChange, counterPart, asObject, opts }: { +function NPPicker(props: { onChange: (nps: NPSelection | undefined) => void, np: NPSelection | undefined, counterPart: NPSelection | VerbObject | undefined, asObject?: boolean, opts: T.TextOptions, -}) { - const [npType, setNpType] = useState(np ? np.type : undefined); +} & ({ + nouns: (s: string) => NounEntry[], + verbs: (s: string) => VerbEntry[], + getNounByTs: (ts: number) => NounEntry | undefined, + getVerbByTs: (ts: number) => VerbEntry | undefined, +} | { + nouns: NounEntry[], + verbs: VerbEntry[], +})) { + const [npType, setNpType] = useState(props.np ? props.np.type : undefined); useEffect(() => { - setNpType(np ? np.type : undefined); - }, [np]); + setNpType(props.np ? props.np.type : undefined); + }, [props.np]); function handleClear() { - if (np && np.type === "noun" && np.dynamicComplement) return; + if (props.np && props.np.type === "noun" && props.np.dynamicComplement) return; setNpType(undefined); - onChange(undefined); + props.onChange(undefined); } function handleNPTypeChange(ntp: NPType) { if (ntp === "pronoun") { - const person = randomPerson({ counterPart }); + const person = randomPerson({ counterPart: props.counterPart }); const pronoun: PronounSelection = { type: "pronoun", person, distance: "far", }; setNpType(ntp); - onChange(pronoun); + props.onChange(pronoun); } else { - onChange(undefined); + props.onChange(undefined); setNpType(ntp); } } - const isDynamicComplement = np && np.type === "noun" && np.dynamicComplement; + const isDynamicComplement = props.np && props.np.type === "noun" && props.np.dynamicComplement; const clearButton = ; return
{!npType &&
@@ -62,29 +69,39 @@ function NPPicker({ np, onChange, counterPart, asObject, opts }: {
)}
} - {(npType === "pronoun" && np?.type === "pronoun") + {(npType === "pronoun" && props.np?.type === "pronoun") ? : npType === "noun" ? : npType === "participle" ? : null } diff --git a/src/components/phrase-builder/PhraseBuilder.tsx b/src/components/phrase-builder/PhraseBuilder.tsx index c4a4388..711dd25 100644 --- a/src/components/phrase-builder/PhraseBuilder.tsx +++ b/src/components/phrase-builder/PhraseBuilder.tsx @@ -33,8 +33,16 @@ const servantEmoji = "🙇‍♂️"; // TODO: error handling on error with rendering etc export function PhraseBuilder(props: { verb?: VerbEntry, - opts?: T.TextOptions, -}) { + opts: T.TextOptions, +} & ({ + nouns: NounEntry[], + verbs: VerbEntry[], +} | { + nouns: (s: string) => NounEntry[], + verbs: (s: string) => VerbEntry[], + getNounByTs: (ts: number) => NounEntry | undefined, + getVerbByTs: (ts: number) => VerbEntry | undefined, +})) { const [subject, setSubject] = useStickyState(undefined, "subjectNPSelection"); const [mode, setMode] = useStickyState<"charts" | "phrases">("phrases", "verbExplorerMode"); const passedVerb = props.verb; @@ -101,6 +109,15 @@ export function PhraseBuilder(props: {
Subject {showRole(VPRendered, "subject")}
Unspoken 3rd Pers. Masc. Plur.
: \ No newline at end of file + \ No newline at end of file