Skip to content

Commit

Permalink
debounce; css
Browse files Browse the repository at this point in the history
  • Loading branch information
spelll committed Sep 10, 2023
1 parent fc9dbf1 commit cc96cd1
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 93 deletions.
139 changes: 75 additions & 64 deletions pages/TextRewriter/entries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,33 @@ import {
inputtingEntryAtom,
newEntryAtom,
ngramIndexesForEntryAtom,
searchDelayAtom,
uilanguageAtom,
} from "@/ts/atom"
import { Box, Button, FormControl, IconButton, Input, TextField, Typography, Checkbox, FormControlLabel } from "@mui/material"
import EditIcon from '@mui/icons-material/Edit';
import {
Box,
Button,
FormControl,
IconButton,
Input,
TextField,
Typography,
Checkbox,
FormControlLabel,
} from "@mui/material"
import EditIcon from "@mui/icons-material/Edit"
import { useAtom } from "jotai"
import { FC, useMemo, useState } from "react"
import React, { FC, ReactEventHandler, 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 } from "@/ts/type"
import { LimitN, SimilarForm, defaultSimilarForm } from "@/ts/type"
import { translationTree } from "@/ts/lang"
import { ketaDirty, ketaDirtyDisplay } from "@/ts/ts/number";
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"

const Entries: FC = () => {
return (
Expand Down Expand Up @@ -69,21 +84,19 @@ const SimilarEntries: FC<SimilarEntriesProp> = prop => {
const [atomUIlanguage] = useAtom(uilanguageAtom)

const [showPoint, setShowPoint] = useState(false)

const lengthmaps = getLengthMap(atomEntryIdDedupedMap, atomDedupedMap)

const ngramScoreMap_concernLength =
(fromto: keyof FromToObj) =>
const ngramScoreMap_concernLength = (fromto: keyof FromToObj) =>
concernLength(
mapUnionsToAverage(
atomIndex[fromto].map(index => {
const ngramScored = ngramScoreMap(index)(inputting[fromto])
// console.log(`ngramScored${index.n}`, ngramScored)
return ngramScored

})
)
)
(inputting[fromto].length, lengthmaps[fromto])
)(inputting[fromto].length, lengthmaps[fromto])

const similarfrom = useMemo(() => {
// console.log("atom index", atomIndex)
Expand All @@ -98,65 +111,66 @@ const SimilarEntries: FC<SimilarEntriesProp> = prop => {

const similarCalc = {
from: similarfrom,
to: similarto
to: similarto,
}
const cssflexCenter = {
display: "flex"
,alignItems:"center"
display: "flex",
alignItems: "center",
}

const similarList = (fromto: keyof FromToObj) => function listfunc() {
return <Box>
<Typography
variant="h5"
>{fromto} </Typography>
<Box>
{similarCalc[fromto].map(([id, score]) => {
// console.log("atomEntryIdDedupedMap", atomEntryIdDedupedMap)
const fkey = getDedupKeyById(id, atomEntryIdDedupedMap)
return fkey === undefined ? (
<Box>cannot get id</Box>
) : (
<Box {...cssflexCenter}>
{showPoint? `${ketaDirtyDisplay("round", 5)(score)}`: ``}
{caseUndefined(atomDedupedMap.get(fkey ?? ""))(v => {
const e: Entry = { ...JSON.parse(fkey), to: v }
return <EachEntry entry={e} />
}, <Box>stringified key not found</Box>)}
</Box>
)
})}
</Box>
</Box>
}
const similarList = (fromto: keyof FromToObj) =>
function listfunc() {
return (
<Box>
<Typography variant="h5">{fromto} </Typography>
<Box>
{similarCalc[fromto].map(([id, score]) => {
// console.log("atomEntryIdDedupedMap", atomEntryIdDedupedMap)
const fkey = getDedupKeyById(id, atomEntryIdDedupedMap)
return fkey === undefined ? (
<Box>cannot get id</Box>
) : (
<Box {...cssflexCenter}>
{showPoint ? `${ketaDirtyDisplay("round", 5)(score)}` : ``}
{caseUndefined(atomDedupedMap.get(fkey ?? ""))(v => {
const e: Entry = { ...JSON.parse(fkey), to: v }
return <EachEntry entry={e} />
}, <Box>stringified key not found</Box>)}
</Box>
)
})}
</Box>
</Box>
)
}

return (
<Box>
<Box
{...cssflexCenter}
>
<Typography
variant="h4"
>
{translationTree.headerTitle.list.similar[atomUIlanguage]}
</Typography>
<FormControlLabel
control={
<Checkbox
checked={!!showPoint}
onChange={()=> setShowPoint(d => !d)}
value="showPoint"
sx={{
display: "flex",
...spacecss.similarForm,
}}>
<Box fontSize={"2em"}>{translationTree.headerTitle.list.similar[atomUIlanguage]}</Box>
<Box
sx={{
display: "flex",
paddingX: 2,
}}>
<FormControlLabel
control={
<Checkbox
checked={!!showPoint}
onChange={() => setShowPoint(d => !d)}
value="showPoint"
/>

}
label={translationTree.showPoint[atomUIlanguage]}
/>
</Box>
<Box>
{[
similarList("from")()
,similarList("to")()
]}
label={translationTree.showPoint[atomUIlanguage]}
/>
<SearchForm />
</Box>
</Box>
<Box>{[similarList("from")(), similarList("to")()]}</Box>
</Box>
)
}
Expand Down Expand Up @@ -208,16 +222,13 @@ const EachEntry: FC<PropEntry> = ({ entry }) => {
const [formVisible, setFormVisible] = useState(false)

return (
<Box
display={"flex"}
alignItems={"center"}
>
<Box display={"flex"} alignItems={"center"}>
<IconButton
size="small"
onClick={() => {
setFormVisible(s => !s)
}}>
<EditIcon fontSize="small"/>
<EditIcon fontSize="small" />
</IconButton>
{formVisible ? (
<RecycleForm hideMe={() => setFormVisible(false)} defaultValues={entry} />
Expand Down
63 changes: 35 additions & 28 deletions pages/TextRewriter/entryForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import validator from "validator";
import { Entry, TooltipOperationBools, allentriesAtom, dedupEntries, dedupedEntryMapAtom, defaultEntry, defaultTooltipOperationBools, entryAttributeReadable, entryIdDedupedMapAtom, get_by_entry, inputtingEntryAtom, keyvalueToEntry, matchingEntryAtom, newEntryAtom, nextEntryIdAtom, ngramIndexesForEntryAtom, ngramIndexingEntry, uilanguageAtom } from "@/ts/atom";
import { Entry, TooltipOperationBools, allentriesAtom, dedupEntries, dedupedEntryMapAtom, defaultEntry, defaultTooltipOperationBools, entryAttributeReadable, entryIdDedupedMapAtom, get_by_entry, inputtingEntryAtom, keyvalueToEntry, matchingEntryAtom, newEntryAtom, nextEntryIdAtom, ngramIndexesForEntryAtom, ngramIndexingEntry, searchDelayAtom, uilanguageAtom } from "@/ts/atom";
import { translationTree } from "@/ts/lang";
import { Box, Button, Checkbox, FormControlLabel, TextField, Tooltip } from "@mui/material";
import { useAtom } from "jotai";
Expand All @@ -8,6 +8,7 @@ import { Controller, useForm, useWatch } from "react-hook-form";
import Entries from "./entries";
import JSONoutput from "./output";
import { ngramIndexing, ngramSegmentify } from "@/ts/ts/text";
import { useDebounce } from "@/ts/hook";

const EntryForm: FC = () => {
const [message, setMessage] = useState<MessageBoxProps>({
Expand All @@ -23,40 +24,46 @@ const EntryForm: FC = () => {
const [atomIndex, setatomIndex] = useAtom(ngramIndexesForEntryAtom)
const [atomNextEntryId, setatomNextEntryId] = useAtom(nextEntryIdAtom)
const [atomEntryIdDedupedMap, setatomEntryIdDedupedMap] = useAtom(entryIdDedupedMapAtom)

const [atomSearchDelay] = useAtom(searchDelayAtom)


const [entriesForJSON, setEntriesForJSON] = useState(allentries)
type Form = Entry
const {control, handleSubmit, formState} = useForm<Form>({
defaultValues: defaultEntry
})
const useWatchValue = useWatch({control})
const realtimeUseWatchValue = useWatch({control})
const useWatchValue = useDebounce(atomSearchDelay, realtimeUseWatchValue)
const [dedupedEntryMap, setDedupedEntryMap] = useAtom(dedupedEntryMapAtom)
const [isCheckboxEnable, setIsCheckboxEnable] = useState(false);
type AddButtonContent = "add"|"update"
const [addButtonContent, setAddButtonContent] = useState<AddButtonContent>("add");
const [openTip, setOpenTip] = useState<TooltipOperationBools>(defaultTooltipOperationBools)

useEffect(()=>{
const newe: Entry = {
from: useWatchValue.from?? newForm.from,
to: useWatchValue.to?? newForm.to,
ic: useWatchValue.ic?? newForm.ic,
mw: useWatchValue.mw?? newForm.mw,
sc: useWatchValue.sc?? newForm.sc
}
setatomInputtingEntry(newe);
setIsCheckboxEnable(!!newe.from.match(/.*[a-zA-Z].*/))
const to = get_by_entry(dedupedEntryMap)(newe)
if (typeof to=="string") {
setMessage(s => ({...s, alreadyExist: translationTree.confirm.alreadyExist[lang]}))
setAddButtonContent("update")
setatomMatchingEntry({...newe, to})
} else {
setMessage(s => ({...s, alreadyExist: ""}))
setAddButtonContent("add")
setatomMatchingEntry(newe)
}
const debounce = setTimeout(()=>{

const newe: Entry = {
from: useWatchValue.from?? newForm.from,
to: useWatchValue.to?? newForm.to,
ic: useWatchValue.ic?? newForm.ic,
mw: useWatchValue.mw?? newForm.mw,
sc: useWatchValue.sc?? newForm.sc
}
setatomInputtingEntry(newe);
setIsCheckboxEnable(!!newe.from.match(/.*[a-zA-Z].*/))
const to = get_by_entry(dedupedEntryMap)(newe)
if (typeof to=="string") {
setMessage(s => ({...s, alreadyExist: translationTree.confirm.alreadyExist[lang]}))
setAddButtonContent("update")
setatomMatchingEntry({...newe, to})
} else {
setMessage(s => ({...s, alreadyExist: ""}))
setAddButtonContent("add")
setatomMatchingEntry(newe)
}
}, 100);
return ()=> clearTimeout(debounce)
}, [useWatchValue, allentries])
const addEntry = (f: Form) => {
const {to, ...fkey} = f
Expand Down Expand Up @@ -107,7 +114,7 @@ const EntryForm: FC = () => {
console.log("failed to delete")
setMessage(s => ({...s, operation: translationTree.tooltip.fail("delete")[lang]}))
}

const array = Array.from(dedupedEntryMap)
const map = new Map(array)
setDedupedEntryMap(map)
Expand All @@ -120,7 +127,7 @@ const EntryForm: FC = () => {
<FormControlLabel control={
<Controller
name={name}
control={control}
control={control}
render={({field})=>(
<Checkbox {...field}
checked={!!field.value}
Expand All @@ -134,7 +141,7 @@ const EntryForm: FC = () => {
)}

const handleClick =
// : MouseEventHandler<HTMLButtonElement> = e =>
// : MouseEventHandler<HTMLButtonElement> = e =>
(name: keyof TooltipOperationBools) => {
const entry: Entry = {
from: useWatchValue.from?? newForm.from,
Expand Down Expand Up @@ -204,14 +211,14 @@ const EntryForm: FC = () => {
<TextField {...field}
label={readableAttr("from")}
error={!!formState.errors.from}
helperText={formState.errors.from && formState.errors.from.message || !formState.isValid &&
helperText={formState.errors.from && formState.errors.from.message || !formState.isValid &&
translationTree.form.helperText.invalid[lang]}
/>
)}/>
<Controller
control={control}
name="to"

render={({field})=>(
<TextField {...field}
label={readableAttr("to")}
Expand Down
7 changes: 6 additions & 1 deletion pages/TextRewriter/recycleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import {
nextEntryIdAtom,
ngramIndexesForEntryAtom,
ngramIndexingEntry,
searchDelayAtom,
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"
Expand Down Expand Up @@ -46,18 +48,20 @@ const RecycleForm: FC<RecycleFormProp> = prop => {
const [atomIndex, setatomIndex] = useAtom(ngramIndexesForEntryAtom)
const [atomNextEntryId, setatomNextEntryId] = useAtom(nextEntryIdAtom)
const [atomEntryIdDedupedMap, setatomEntryIdDedupedMap] = useAtom(entryIdDedupedMapAtom)
const [atomSearchDelay] = useAtom(searchDelayAtom)

const [entriesForJSON, setEntriesForJSON] = useState(allentries)
type Form = Entry
const { control, handleSubmit, formState } = useForm<Form>({
defaultValues: prop.defaultValues,
})
const useWatchValue = useWatch({ control })
const realtimeUseWatchValue = useWatch({ control })
const [dedupedEntryMap, setDedupedEntryMap] = useAtom(dedupedEntryMapAtom)
const [isCheckboxEnable, setIsCheckboxEnable] = useState(false)
type AddButtonContent = "add" | "update"
const [addButtonContent, setAddButtonContent] = useState<AddButtonContent>("add")
const [openTip, setOpenTip] = useState<TooltipOperationBools>(defaultTooltipOperationBools)
const useWatchValue = useDebounce(atomSearchDelay, realtimeUseWatchValue)

useEffect(() => {
const newe: Entry = {
Expand All @@ -80,6 +84,7 @@ const RecycleForm: FC<RecycleFormProp> = prop => {
setatomMatchingEntry(newe)
}
}, [useWatchValue, allentries])

const addEntry = (f: Form) => {
// console.log("addEntry called")
// console.log("atomNextEntryId", atomNextEntryId)
Expand Down
Loading

0 comments on commit cc96cd1

Please sign in to comment.