Skip to content

Commit

Permalink
maxNumber editable
Browse files Browse the repository at this point in the history
  • Loading branch information
uxiun committed Nov 6, 2023
1 parent 993c0b4 commit c7306f3
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 254 deletions.
40 changes: 27 additions & 13 deletions pages/TextRewriter/entries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
inputtingEntryAtom,
newEntryAtom,
ngramIndexesForEntryAtom,
searchDelayAtom,
searchConfigAtom,
topFormEntryAtom,
uilanguageAtom,
} from "@/ts/atom"
import {
Expand All @@ -26,24 +27,27 @@ import {
FormControlLabel,
} from "@mui/material"
import EditIcon from "@mui/icons-material/Edit"
import LockIcon from "@mui/icons-material/Lock"
import { useAtom } from "jotai"
import React, { FC, ReactEventHandler, useCallback, useEffect, useMemo, useState } from "react"
import RecycleForm from "./recycleForm"
import { concernLength, ngramScoreMap } from "@/ts/ts/text"
import { caseUndefined, mapUnions, mapUnionsToAverage } from "@/ts/ts/map"
import { LimitN, SimilarForm, defaultSimilarForm } from "@/ts/type"
import { LimitN, SimilarForm } from "@/ts/type"
import { translationTree } from "@/ts/lang"
import { ketaDirty, ketaDirtyDisplay } from "@/ts/ts/number"
import { Controller, useForm, useWatch } from "react-hook-form"
import { useDebounce } from "@/ts/hook"
import SearchForm from "./searchForm"
import { spacecss } from "@/ts/css"
import { type } from "os"

const Entries: FC = () => {
const [atomSearchConfig] = useAtom(searchConfigAtom)
return (
<div className="lists">
<RecentEntries limit={2} />
<SimilarEntries maxShowNumber={10} />
<SimilarEntries maxShowNumber={atomSearchConfig.maxShowNumber} />
</div>
)
}
Expand Down Expand Up @@ -77,7 +81,6 @@ type SimilarEntriesProp = {
allowDiffMax?: number
}
const SimilarEntries: FC<SimilarEntriesProp> = prop => {
const [allentries, setAllEntries] = useAtom(allentriesAtom)
const [inputting] = useAtom(inputtingEntryAtom)
const [atomIndex] = useAtom(ngramIndexesForEntryAtom)
const [atomEntryIdDedupedMap] = useAtom(entryIdDedupedMapAtom)
Expand All @@ -99,7 +102,7 @@ const SimilarEntries: FC<SimilarEntriesProp> = prop => {
})
)
)(inputting[fromto].length, lengthmaps[fromto]),
[atomIndex]
[atomIndex, inputting, lengthmaps]
)

const similarfrom = useMemo(() => {
Expand Down Expand Up @@ -128,17 +131,18 @@ const SimilarEntries: FC<SimilarEntriesProp> = prop => {
<Box>
<Typography variant="h5">{entryAttributeReadable(atomUIlanguage)(fromto)} </Typography>
<Box>
{similarCalc[fromto].map(([id, score]) => {
{similarCalc[fromto].map(([id, score], i) => {
// console.log("atomEntryIdDedupedMap", atomEntryIdDedupedMap)
const fkey = getDedupKeyById(id, atomEntryIdDedupedMap)
return fkey === undefined ? (
<Box>cannot get id</Box>
<Box>{`${i}. `} cannot get id</Box>
) : (
<Box {...cssflexCenter}>
<Box {...cssflexCenter} key={id}>
{`${i}. `}
{showPoint ? `${ketaDirtyDisplay("round", 5)(score)}` : ``}
{caseUndefined(atomDedupedMap.get(fkey ?? ""))(v => {
const e: Entry = { ...JSON.parse(fkey), to: v }
return <EachEntry entry={e} />
return <EachEntry frozenAttr={[fromto]} entry={e} />
}, <Box>stringified key not found</Box>)}
</Box>
)
Expand Down Expand Up @@ -224,20 +228,30 @@ const EntryView: FC<PropEntry> = ({ entry }) => {
type PropEntry = {
entry: Entry
}
const EachEntry: FC<PropEntry> = ({ entry }) => {
const [formVisible, setFormVisible] = useState(false)
type PropFrozen = {
entry: Entry
frozenAttr: [keyof Entry]
}

const EachEntry: FC<PropFrozen> = ({ entry, frozenAttr }) => {
const [formVisible, setFormVisible] = useState(false)
const [atomTopFormEntry] = useAtom(topFormEntryAtom)
const [atomInputtingEntry, setatomInputtingEntry] = useAtom(inputtingEntryAtom)
const hideMe = () => {
setFormVisible(false)
setatomInputtingEntry(atomTopFormEntry)
}
return (
<Box display={"flex"} alignItems={"center"}>
<IconButton
size="small"
onClick={() => {
setFormVisible(s => !s)
}}>
<EditIcon fontSize="small" />
{formVisible ? <LockIcon fontSize="small" /> : <EditIcon fontSize="small" />}
</IconButton>
{formVisible ? (
<RecycleForm hideMe={() => setFormVisible(false)} defaultValues={entry} />
<RecycleForm frozenAttr={frozenAttr} defaultValues={entry} />
) : (
<EntryView entry={entry} />
)}
Expand Down
10 changes: 7 additions & 3 deletions pages/TextRewriter/entryForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
nextEntryIdAtom,
ngramIndexesForEntryAtom,
ngramIndexingEntry,
searchDelayAtom,
searchConfigAtom,
topFormEntryAtom,
uilanguageAtom,
} from "@/ts/atom"
import { translationTree } from "@/ts/lang"
Expand All @@ -41,18 +42,19 @@ const EntryForm: FC = () => {
const [allentries, setAllEntries] = useAtom(allentriesAtom)
const [atomMatchingEntry, setatomMatchingEntry] = useAtom(matchingEntryAtom)
const [atomInputtingEntry, setatomInputtingEntry] = useAtom(inputtingEntryAtom)
const [atomTopFormEntry, setAtomTopFormEntry] = useAtom(topFormEntryAtom)
const [atomIndex, setatomIndex] = useAtom(ngramIndexesForEntryAtom)
const [atomNextEntryId, setatomNextEntryId] = useAtom(nextEntryIdAtom)
const [atomEntryIdDedupedMap, setatomEntryIdDedupedMap] = useAtom(entryIdDedupedMapAtom)
const [atomSearchDelay] = useAtom(searchDelayAtom)
const [atomSearchConfig] = useAtom(searchConfigAtom)

const [entriesForJSON, setEntriesForJSON] = useState(allentries)
type Form = Entry
const { control, handleSubmit, formState } = useForm<Form>({
defaultValues: defaultEntry,
})
const realtimeUseWatchValue = useWatch({ control })
const useWatchValue = useDebounce(atomSearchDelay, realtimeUseWatchValue)
const useWatchValue = useDebounce(atomSearchConfig.delay, realtimeUseWatchValue)
const [dedupedEntryMap, setDedupedEntryMap] = useAtom(dedupedEntryMapAtom)
const [isCheckboxEnable, setIsCheckboxEnable] = useState(false)
type AddButtonContent = "add" | "update"
Expand All @@ -69,6 +71,7 @@ const EntryForm: FC = () => {
sc: useWatchValue.sc ?? newForm.sc,
}
setatomInputtingEntry(newe)
setAtomTopFormEntry(newe)
setIsCheckboxEnable(!!newe.from.match(/.*[a-zA-Z].*/))
const to = get_by_entry(dedupedEntryMap)(newe)
if (typeof to == "string") {
Expand All @@ -90,6 +93,7 @@ const EntryForm: FC = () => {
newForm,
setatomInputtingEntry,
setatomMatchingEntry,
setAtomTopFormEntry,
])
const addEntry = (f: Form) => {
const { to, ...fkey } = f
Expand Down
1 change: 0 additions & 1 deletion pages/TextRewriter/info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ type LangForm = {
const InfoComponent: FC = () => {
const [show, setShow] = useState(true)
const [lang, setLang] = useAtom(uilanguageAtom)
console.info("InfoComponent(), lang=", lang)
const { control, handleSubmit, formState, getValues } = useForm<LangForm>({
defaultValues: { lang },
})
Expand Down
30 changes: 25 additions & 5 deletions pages/TextRewriter/recycleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,23 @@ import {
nextEntryIdAtom,
ngramIndexesForEntryAtom,
ngramIndexingEntry,
searchDelayAtom,
searchConfigAtom,
topFormEntryAtom,
uilanguageAtom,
updateIndexList,
} from "@/ts/atom"
import { useDebounce } from "@/ts/hook"
import { translationTree } from "@/ts/lang"
import { list_modify } from "@/ts/ts/list"
import { caseUndefined } from "@/ts/ts/map"
import { ngramIndexing, ngramSegmentify } from "@/ts/ts/text"
import { isEmptyOrWhitespaces, ngramIndexing, ngramSegmentify } from "@/ts/ts/text"
import { Box, Button, Checkbox, FormControlLabel, TextField, Tooltip } from "@mui/material"
import { useAtom } from "jotai"
import { FC, useEffect, useState } from "react"
import { Controller, useForm, useWatch } from "react-hook-form"

type RecycleFormProp = {
frozenAttr: [keyof Entry]
defaultValues: Entry
hideMe?: () => void
}
Expand All @@ -45,10 +47,11 @@ const RecycleForm: FC<RecycleFormProp> = prop => {
const [allentries, setAllEntries] = useAtom(allentriesAtom)
const [atomMatchingEntry, setatomMatchingEntry] = useAtom(matchingEntryAtom)
const [atomInputtingEntry, setatomInputtingEntry] = useAtom(inputtingEntryAtom)
const [atomTopFormEntry, setAtomTopFormEntry] = useAtom(topFormEntryAtom)
const [atomIndex, setatomIndex] = useAtom(ngramIndexesForEntryAtom)
const [atomNextEntryId, setatomNextEntryId] = useAtom(nextEntryIdAtom)
const [atomEntryIdDedupedMap, setatomEntryIdDedupedMap] = useAtom(entryIdDedupedMapAtom)
const [atomSearchDelay] = useAtom(searchDelayAtom)
const [atomSearchConfig] = useAtom(searchConfigAtom)

const [entriesForJSON, setEntriesForJSON] = useState(allentries)
type Form = Entry
Expand All @@ -61,7 +64,7 @@ const RecycleForm: FC<RecycleFormProp> = prop => {
type AddButtonContent = "add" | "update"
const [addButtonContent, setAddButtonContent] = useState<AddButtonContent>("add")
const [openTip, setOpenTip] = useState<TooltipOperationBools>(defaultTooltipOperationBools)
const useWatchValue = useDebounce(atomSearchDelay, realtimeUseWatchValue)
const useWatchValue = useDebounce(atomSearchConfig.delay, realtimeUseWatchValue)

useEffect(() => {
const newe: Entry = {
Expand All @@ -71,7 +74,21 @@ const RecycleForm: FC<RecycleFormProp> = prop => {
mw: useWatchValue.mw ?? newForm.mw,
sc: useWatchValue.sc ?? newForm.sc,
}
setatomInputtingEntry(newe)
const nas = [...Object.entries(newForm)].map(([attr, v]) => {
const a = attr as keyof Entry
return [
a,
prop.frozenAttr.includes(a) ? atomInputtingEntry[a] : useWatchValue[a] ?? newForm[a],
]
})
let frozen: Entry = Object.fromEntries(nas)
const fromto = ["from", "to"] as const
fromto.forEach(s => {
if (!prop.frozenAttr.includes(s) && isEmptyOrWhitespaces(frozen[s])) {
frozen[s] = atomTopFormEntry[s]
}
})
setatomInputtingEntry(frozen)
setIsCheckboxEnable(!!newe.from.match(/.*[a-zA-Z].*/))
const to = get_by_entry(dedupedEntryMap)(newe)
if (typeof to == "string") {
Expand All @@ -91,6 +108,9 @@ const RecycleForm: FC<RecycleFormProp> = prop => {
newForm,
setatomInputtingEntry,
setatomMatchingEntry,
atomTopFormEntry,
prop.frozenAttr,
atomInputtingEntry,
])

const addEntry = (f: Form) => {
Expand Down
61 changes: 48 additions & 13 deletions pages/TextRewriter/searchForm.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
import { searchDelayAtom, uilanguageAtom } from "@/ts/atom"
import { SearchConfig, defaultSearchConfig, searchConfigAtom, uilanguageAtom } from "@/ts/atom"
import { useDebounce } from "@/ts/hook"
import { translationTree } from "@/ts/lang"
import { SimilarForm, defaultSimilarForm } from "@/ts/type"
import { fallback } from "@/ts/ts/map"
import { Box, TextField } from "@mui/material"
import { useAtom } from "jotai"
import { FC, useEffect, useState } from "react"
import { Controller, useForm, useWatch } from "react-hook-form"

const SearchForm: FC = () => {
const [atomSearchDelay, setAtomSearchDelay] = useAtom(searchDelayAtom)
const [atomSearchConfig, setAtomSearchConfig] = useAtom(searchConfigAtom)
const [atomUIlanguage] = useAtom(uilanguageAtom)

const { control, register } = useForm<SimilarForm>({
defaultValues: defaultSimilarForm,
const { control, register } = useForm<SearchConfig>({
defaultValues: defaultSearchConfig,
})
const useWatchValue = useWatch({ control })
const [focusing, setFocusing] = useState(false)
const useWatchValue = useDebounce(300, useWatch({ control }))
const defaultFocusState = {
delay: false,
maxShowNumber: false,
}
const [focusing, setFocusing] = useState(defaultFocusState)

useEffect(() => {
setAtomSearchDelay(useWatchValue.delay ?? defaultSimilarForm.delay)
}, [useWatchValue, setAtomSearchDelay])
const m = useWatchValue.maxShowNumber ?? defaultSearchConfig.maxShowNumber
setAtomSearchConfig({
...atomSearchConfig,
delay: useWatchValue.delay ?? defaultSearchConfig.delay,
maxShowNumber: m,
// fallback(n => n < 0, 0)(m),
})
}, [useWatchValue, setAtomSearchConfig, atomSearchConfig])

const width = 120
return (
<Box>
<Controller
Expand All @@ -31,11 +42,35 @@ const SearchForm: FC = () => {
{...field}
type="number"
size="small"
label={translationTree.searchDelay.label[atomUIlanguage]}
sx={{ width }}
label={translationTree.searchConfig.searchDelay.label[atomUIlanguage] + " [ms]"}
ref={register("delay").ref}
onFocus={() => setFocusing(f => !f)}
onBlur={() => setFocusing(f => !f)}
helperText={focusing && translationTree.searchDelay.help[atomUIlanguage]}
onFocus={() => setFocusing(f => ({ ...f, delay: !f.delay }))}
onBlur={() => setFocusing(f => ({ ...f, delay: !f.delay }))}
helperText={
focusing.delay && translationTree.searchConfig.searchDelay.help[atomUIlanguage]
}
/>
)}
/>
<Controller
control={control}
name="maxShowNumber"
rules={{
min: 0,
}}
render={({ field, fieldState }) => (
<TextField
{...field}
type="number"
size="small"
sx={{ width }}
label={translationTree.searchConfig.maxNumberlabel[atomUIlanguage]}
onFocus={() => setFocusing(f => ({ ...f, maxShowNumber: !f.maxShowNumber }))}
onBlur={() => setFocusing(f => ({ ...f, maxShowNumber: !f.maxShowNumber }))}
helperText={
focusing.maxShowNumber && translationTree.searchConfig.maxNumberlabel[atomUIlanguage]
}
/>
)}
/>
Expand Down
12 changes: 10 additions & 2 deletions ts/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ export type Entry = {
export const langs = ["ja", "en"] as const
export type Lang = (typeof langs)[number]
export const defaultLanguage = "ja"
export const defaultSearchDelay = 700
export const searchDelayAtom = atom(defaultSearchDelay)
export const defaultSearchConfig: SearchConfig = {
delay: 700,
maxShowNumber: 10,
}
export type SearchConfig = {
delay: number
maxShowNumber: number
}
export const searchConfigAtom = atom(defaultSearchConfig)
const entryAttributeTranslations: Record<keyof Entry, Record<Lang, string>> = {
from: {
en: "from",
Expand Down Expand Up @@ -90,6 +97,7 @@ export const defaultEntry: Entry = {
}
export type EntryBoolKey = "ic" | "mw" | "sc"
export const inputtingEntryAtom = atom<Entry>(defaultEntry)
export const topFormEntryAtom = atom<Entry>(defaultEntry)
export const matchingEntryAtom = atom<Entry>(defaultEntry)
export const newEntryAtom = atom<Entry>(defaultEntry)
export const dedupedEntryMapAtom = atom<Map<string, string>>(new Map())
Expand Down
20 changes: 13 additions & 7 deletions ts/lang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,20 @@ export const translationTree = {
en: "show match point",
ja: "一致度表示",
},
searchDelay: {
label: {
en: "search delay",
ja: "検索遅延",
searchConfig: {
searchDelay: {
label: {
en: "search delay",
ja: "検索遅延",
},
help: {
en: "increase this if input lagged",
ja: "入力がもたつくなら数値を大きく",
},
},
help: {
en: "increase this if input lagged",
ja: "入力がもたつくなら数値を大きく",
maxNumberlabel: {
en: "max number for search results",
ja: "検索結果の最大表示数",
},
},
output: {
Expand Down
Loading

0 comments on commit c7306f3

Please sign in to comment.