diff --git a/src/renderer/src/components/Sheet/ScriptureTable.tsx b/src/renderer/src/components/Sheet/ScriptureTable.tsx index df6da6b3..aad98bfb 100644 --- a/src/renderer/src/components/Sheet/ScriptureTable.tsx +++ b/src/renderer/src/components/Sheet/ScriptureTable.tsx @@ -1039,54 +1039,60 @@ export function ScriptureTable(props: IProps) { interface MyWorkflow extends ISheet { [key: string]: any; } - const updateData = (changes: ICellChange[]) => { - waitForIt( - 'finish save or update', - () => !savingRef.current && !updateRef.current, - () => false, - 50 - ).then(() => { - setUpdate(true); - const newsht = [...sheetRef.current]; - changes.forEach((c) => { - const { ws, i } = getByIndex(newsht, c.row); - const myWf = ws as MyWorkflow | undefined; - const name = colNames[c.col]; - const isNumberCol = c.col === secNumCol || c.col === passNumCol; - - if (isNumberCol && !isValidNumber(c.value || '')) { - showMessage(s.nonNumber); - } else if (myWf && myWf[name as keyof MyWorkflow] !== c.value) { - const isSection = c.col < 2; - const sectionUpdated = isSection - ? currentDateTime() - : ws?.sectionUpdated; - const passageUpdated = isSection - ? ws?.passageUpdated - : currentDateTime(); - const value = name === 'book' ? findBook(c.value as string) : c.value; - const passageType = - name === 'reference' - ? passageTypeFromRef(c.value as string, flat) - : ws?.passageType; - - newsht[i] = { - ...ws, - [name as keyof MyWorkflow]: isNumberCol - ? parseInt(value ?? '') - : value, - sectionUpdated, - passageUpdated, - passageType, - } as ISheet; - } - }); - if (changes.length > 0) { - setSheet(newsht); - setChanged(true); + const applyCellChanges = (changes: ICellChange[]) => { + setUpdate(true); + const newsht = [...sheetRef.current]; + changes.forEach((c) => { + const { ws, i } = getByIndex(newsht, c.row); + const myWf = ws as MyWorkflow | undefined; + const name = colNames[c.col]; + const isNumberCol = c.col === secNumCol || c.col === passNumCol; + + if (isNumberCol && !isValidNumber(c.value || '')) { + showMessage(s.nonNumber); + } else if (myWf && myWf[name as keyof MyWorkflow] !== c.value) { + const isSection = c.col < 2; + const sectionUpdated = isSection + ? currentDateTime() + : ws?.sectionUpdated; + const passageUpdated = isSection + ? ws?.passageUpdated + : currentDateTime(); + const value = name === 'book' ? findBook(c.value as string) : c.value; + const passageType = + name === 'reference' + ? passageTypeFromRef(c.value as string, flat) + : ws?.passageType; + + newsht[i] = { + ...ws, + [name as keyof MyWorkflow]: isNumberCol + ? parseInt(value ?? '') + : value, + sectionUpdated, + passageUpdated, + passageType, + } as ISheet; } - setUpdate(false); }); + if (changes.length > 0) { + setSheet(newsht); + setChanged(true); + } + setUpdate(false); + }; + + const updateData = (changes: ICellChange[]) => { + if (savingRef.current || updateRef.current) { + waitForIt( + 'finish save or update', + () => !savingRef.current && !updateRef.current, + () => false, + 50 + ).then(() => applyCellChanges(changes)); + return; + } + applyCellChanges(changes); }; const updateTitleMedia = async (index: number, mediaId: string) => { diff --git a/src/renderer/src/components/Sheet/TitleEdit.tsx b/src/renderer/src/components/Sheet/TitleEdit.tsx index d775a589..4a2002c2 100644 --- a/src/renderer/src/components/Sheet/TitleEdit.tsx +++ b/src/renderer/src/components/Sheet/TitleEdit.tsx @@ -29,12 +29,7 @@ export function TitleEdit({ }: IProps) { const [planId] = useGlobal('plan'); //will be constant here const [memory] = useGlobal('memory'); - const [titlex, setTitle] = useState(title || ''); - const [titleMediafile, setTitleMediafile] = useState(''); - - useEffect(() => { - setTitle(title); - }, [title]); + const [titleMediafile, setTitleMediafile] = useState(mediaId || ''); useEffect(() => { setTitleMediafile(mediaId); @@ -42,7 +37,6 @@ export function TitleEdit({ const handleChangeTitle = (value: string) => { onTextChange(value); - setTitle(value); return ''; }; @@ -53,13 +47,13 @@ export function TitleEdit({ return ( <> - {readonly && !showpublish && ((<>{titlex}) as ReactElement)} + {readonly && !showpublish && ((<>{title}) as ReactElement)} {(!readonly || showpublish) && ( { + setCurTextx(text); + curTextRef.current = text; + }; useEffect(() => setHelperText(helper ?? ''), [helper]); useEffect(() => { @@ -216,9 +222,16 @@ export default function MediaTitle(props: IProps) { const recToolId = useMemo(() => toolId + 'rec', [toolId]); useEffect(() => { - setCurText(title ?? ''); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [title]); + if (prevTitleKeyRef.current !== titlekey) { + prevTitleKeyRef.current = titlekey; + isFocusedRef.current = false; + setCurText(title ?? ''); + return; + } + if (!isFocusedRef.current) { + setCurText(title ?? ''); + } + }, [title, titlekey]); useEffect(() => { langRef.current = language; @@ -240,9 +253,23 @@ export default function MediaTitle(props: IProps) { showMessage(t.recording); return; } - setCurText(e.target.value); - if (onTextChange && e.target.value !== title) { - const err = onTextChange(e.target.value); + const value = e.target.value.trim(); + setCurText(value); + if (onTextChange) { + const err = onTextChange(value); + setHelperText(err); + } + }; + + const handleFocus = () => { + isFocusedRef.current = true; + }; + + const handleBlur = () => { + isFocusedRef.current = false; + const value = curTextRef.current; + if (onTextChange && value !== (title ?? '')) { + const err = onTextChange(value); setHelperText(err); } }; @@ -375,6 +402,8 @@ export default function MediaTitle(props: IProps) { value={curText} onClick={language ? handleLangPick : undefined} onChange={handleTextChange} + onFocus={handleFocus} + onBlur={handleBlur} onKeyDown={handleKeyDown} helperText={helperText} size="small" @@ -401,6 +430,8 @@ export default function MediaTitle(props: IProps) { // eslint-disable-next-line react-hooks/exhaustive-deps [ curText, + title, + titlekey, recording, mediaId, canSaveRecording,