fix: debounce saving task description/draft (#1187)
Co-authored-by: Johnny Almonte <johnny243@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useRef, useState } from 'react'
|
||||||
import useResizeObserver from '@react-hook/resize-observer'
|
import useResizeObserver from '@react-hook/resize-observer'
|
||||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
|
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
|
||||||
import type { AppDispatch, RootState } from './store'
|
import type { AppDispatch, RootState } from './store'
|
||||||
@@ -32,3 +32,13 @@ export const useResize = (ref: React.RefObject<HTMLElement>, effect: (target: HT
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useDebouncedCallback = (callback: () => void, waitMs: number = 500) => {
|
||||||
|
const timeout = useRef<any>()
|
||||||
|
|
||||||
|
clearTimeout(timeout.current)
|
||||||
|
|
||||||
|
timeout.current = setTimeout(() => {
|
||||||
|
callback()
|
||||||
|
}, waitMs)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ChangeEvent, createRef, KeyboardEvent, useState } from 'react'
|
|||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector } from '../../app/hooks'
|
import { useAppDispatch, useAppSelector, useDebouncedCallback } from '../../app/hooks'
|
||||||
import { GroupModel, taskAdded, tasksGroupDraft } from './tasks-slice'
|
import { GroupModel, taskAdded, tasksGroupDraft } from './tasks-slice'
|
||||||
|
|
||||||
import { TextInput } from '../../common/components'
|
import { TextInput } from '../../common/components'
|
||||||
@@ -37,9 +37,7 @@ const CreateTask: React.FC<CreateTaskProps> = ({ group }) => {
|
|||||||
const [taskDraft, setTaskDraft] = useState<string>(group.draft ?? '')
|
const [taskDraft, setTaskDraft] = useState<string>(group.draft ?? '')
|
||||||
|
|
||||||
function onTextChange(event: ChangeEvent<HTMLInputElement>) {
|
function onTextChange(event: ChangeEvent<HTMLInputElement>) {
|
||||||
const draft = event.target.value
|
setTaskDraft(event.target.value)
|
||||||
dispatch(tasksGroupDraft({ groupName, draft }))
|
|
||||||
setTaskDraft(draft)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyPress(event: KeyboardEvent<HTMLInputElement>) {
|
function handleKeyPress(event: KeyboardEvent<HTMLInputElement>) {
|
||||||
@@ -54,6 +52,12 @@ const CreateTask: React.FC<CreateTaskProps> = ({ group }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useDebouncedCallback(() => {
|
||||||
|
if (group.draft !== undefined && taskDraft !== group.draft) {
|
||||||
|
dispatch(tasksGroupDraft({ groupName, draft: taskDraft }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if (!canEdit) {
|
if (!canEdit) {
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import './TaskItem.scss'
|
|||||||
import { ChangeEvent, createRef, KeyboardEvent, useState } from 'react'
|
import { ChangeEvent, createRef, KeyboardEvent, useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector, useDidMount, useResize } from '../../app/hooks'
|
import { useAppDispatch, useAppSelector, useDebouncedCallback, useResize } from '../../app/hooks'
|
||||||
import { taskDeleted, TaskModel, taskModified, taskToggled } from './tasks-slice'
|
import { taskDeleted, TaskModel, taskModified, taskToggled } from './tasks-slice'
|
||||||
|
|
||||||
import { CheckBoxInput, TextAreaInput } from '../../common/components'
|
import { CheckBoxInput, TextAreaInput } from '../../common/components'
|
||||||
@@ -116,18 +116,11 @@ const TaskItem: React.FC<TaskItemProps> = ({ task, groupName, innerRef, ...props
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
useDebouncedCallback(() => {
|
||||||
* Save the task after the user has stopped typing.
|
if (description !== task.description) {
|
||||||
*/
|
dispatch(taskModified({ task: { id: task.id, description }, groupName }))
|
||||||
useDidMount(() => {
|
}
|
||||||
const timeoutId = setTimeout(() => {
|
})
|
||||||
if (description !== task.description) {
|
|
||||||
dispatch(taskModified({ task: { id: task.id, description }, groupName }))
|
|
||||||
}
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
return () => clearTimeout(timeoutId)
|
|
||||||
}, [description, groupName])
|
|
||||||
|
|
||||||
useResize(textAreaRef, resizeTextArea)
|
useResize(textAreaRef, resizeTextArea)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user