reduce note debounce time + flush on unmount (#809)

This commit is contained in:
Brendan Allan 2023-05-11 05:13:48 +08:00 committed by GitHub
parent 3c1696f833
commit a3facb4598
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useEffect, useState } from 'react';
import { useDebouncedCallback } from 'use-debounce';
import { Object as SDObject, useLibraryMutation } from '@sd/client';
import { Divider, TextArea } from '@sd/ui';
@ -9,35 +9,19 @@ interface Props {
}
export default function Note(props: Props) {
// notes are cached in a store by their file id
// this is so we can ensure every note has been sent to Rust even
// when quickly navigating files, which cancels update function
const [note, setNote] = useState(props.data.note || '');
const setNote = useLibraryMutation('files.setNote');
const { mutate: fileSetNote } = useLibraryMutation('files.setNote');
const debouncedSetNote = useDebouncedCallback((note: string) => {
setNote.mutate({
id: props.data.id,
note
});
}, 500);
const debounce = useDebouncedCallback(
(note: string) =>
fileSetNote({
id: props.data.id,
note
}),
2000
);
// Force update when component unmounts
useEffect(() => () => debouncedSetNote.flush(), []);
// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedNote = useCallback(
(note: string) => debounce(note),
[props.data.id, fileSetNote]
);
// when input is updated, cache note
function handleNoteUpdate(e: React.ChangeEvent<HTMLTextAreaElement>) {
if (e.target.value !== note) {
setNote(e.target.value);
debouncedNote(e.target.value);
}
}
const [cachedNote, setCachedNote] = useState(props.data.note);
return (
<>
@ -46,9 +30,12 @@ export default function Note(props: Props) {
<MetaTitle>Note</MetaTitle>
<TextArea
className="mb-1 mt-2 !py-2 text-xs leading-snug"
value={note || ''}
onChange={handleNoteUpdate}
/>{' '}
value={cachedNote ?? ''}
onChange={(e) => {
setCachedNote(e.target.value);
debouncedSetNote(e.target.value);
}}
/>
</MetaContainer>
</>
);