1
0
Fork 0

format everything as decimals for ease of input

This commit is contained in:
Enoch Riese 2022-06-16 16:54:08 -05:00
parent 9c271b0d2f
commit 7a34bc0629
2 changed files with 31 additions and 32 deletions

View file

@ -1,8 +1,8 @@
import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react' import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react'
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import { isDegreeMeasurement } from '../../../config/measurements' import { isDegreeMeasurement } from '../../../config/measurements'
import measurementAsMm from 'pkgs/utils/measurementAsMm' import measurementAsMm from 'pkgs/utils/src/measurementAsMm'
import formatMm from 'pkgs/utils/formatMm' import formatMm from 'pkgs/utils/src/formatMm'
/* /*
* This is a single input for a measurements * This is a single input for a measurements
@ -16,7 +16,9 @@ const MeasurementInput = ({ m, gist, app, updateMeasurements }) => {
const { t } = useTranslation(['app', 'measurements']) const { t } = useTranslation(['app', 'measurements'])
const prefix = (app.site === 'org') ? '' : 'https://freesewing.org' const prefix = (app.site === 'org') ? '' : 'https://freesewing.org'
const title = t(`measurements:${m}`) const title = t(`measurements:${m}`)
const isDegree = isDegreeMeasurement(m)
const isDegree = isDegreeMeasurement(m);
const factor = useMemo(() => (isDegree ? 1 : (gist.units == 'imperial' ? 25.4 : 10)), [gist.units])
const isValValid = val => (typeof val === 'undefined' || val === '') const isValValid = val => (typeof val === 'undefined' || val === '')
? null ? null
@ -25,52 +27,45 @@ const MeasurementInput = ({ m, gist, app, updateMeasurements }) => {
? isValValid(val) ? isValValid(val)
: isValValid(newVal) : isValValid(newVal)
const [val, setVal] = useState(formatMm(gist?.measurements?.[m], gist.units, false) || '') const [val, setVal] = useState(gist?.measurements?.[m] / factor || '')
// keep a single reference to a debounce timer // keep a single reference to a debounce timer
const debounceTimeout = useRef(null); const debounceTimeout = useRef(null);
// this callback will track to current gist values
const cb = useCallback((evt) => {
let evtVal = evt.target.value;
// cleat the timeout reference
debounceTimeout.current = null;
let useVal = isDegree ? evtVal : measurementAsMm(evtVal, gist.units);
const ok = isValid(useVal)
// only set to the gist if it's valid
if (ok) {
updateMeasurements(useVal, m)
}
}, [gist]);
// onChange // onChange
const update = (evt) => { const update = useCallback((evt) => {
evt.stopPropagation(); evt.stopPropagation();
let evtVal = evt.target.value; let evtVal = evt.target.value;
// set Val immediately so that the input reflects it // set Val immediately so that the input reflects it
setVal(evtVal) setVal(evtVal)
// debounce the rest of the callback let useVal = isDegree ? evtVal : measurementAsMm(evtVal, gist.units);
if (debounceTimeout.current !== null) { clearTimeout(debounceTimeout.current); const ok = isValid(useVal)
// only set to the gist if it's valid
if (ok) {
// debounce in case it's still changing
if (debounceTimeout.current !== null) { clearTimeout(debounceTimeout.current); }
debounceTimeout.current = setTimeout(() => {
// clear the timeout reference
debounceTimeout.current = null;
updateMeasurements(useVal, m)
}, 500);
} }
debounceTimeout.current = setTimeout(() => { }, [gist.units])
cb(evt)
}, 500);
}
// use this for better update efficiency // use this for better update efficiency
const memoVal = useMemo(() => gist?.measurements[m], [gist]) const memoVal = useMemo(() => gist?.measurements[m], [gist])
// track validity against the value and the units // track validity against the value and the units
const valid = useMemo(() => isValid(measurementAsMm(val, gist.units)), [val, gist.units]) const valid = useMemo(() => isValid(isDegree ? val : measurementAsMm(val, gist.units)), [val, gist.units])
// hook to update the value when the gist changes // hook to update the value or format when the gist changes
useEffect(() => { useEffect(() => {
if (memoVal) { // set the value to the proper value and format
let gistVal = isDegree ? memoVal : formatMm(memoVal, gist.units, false); if (memoVal) {
setVal(gistVal) let gistVal = +(memoVal / factor).toFixed(2);
} setVal(gistVal)
}, [memoVal, gist.units]) }
}, [memoVal, factor])
// cleanup // cleanup
useEffect(() => clearTimeout(debounceTimeout.current), []) useEffect(() => clearTimeout(debounceTimeout.current), [])

View file

@ -1,6 +1,10 @@
const measurementAsMm = (value, units = "metric") => { const measurementAsMm = (value, units = "metric") => {
if (typeof value === "number") if (typeof value === "number")
return value * (units === "imperial" ? 25.4 : 10); return value * (units === "imperial" ? 25.4 : 10);
if (value.endsWith('.'))
return false;
if (units === "metric") { if (units === "metric") {
value = Number(value); value = Number(value);
if (isNaN(value)) return false; if (isNaN(value)) return false;