From d2e4134d1f546042fdf0a3181c1cc85a387ad0ab Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Thu, 3 Apr 2025 16:11:24 -0400 Subject: [PATCH] refactor: Enhance auto-save functionality with debounced restore methods --- client/src/hooks/Input/useAutoSave.ts | 43 +++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/client/src/hooks/Input/useAutoSave.ts b/client/src/hooks/Input/useAutoSave.ts index 6b7be2437d..2a5b2790af 100644 --- a/client/src/hooks/Input/useAutoSave.ts +++ b/client/src/hooks/Input/useAutoSave.ts @@ -1,6 +1,6 @@ import debounce from 'lodash/debounce'; import { SetterOrUpdater, useRecoilValue } from 'recoil'; -import { useState, useEffect, useMemo, useCallback } from 'react'; +import { useState, useEffect, useMemo, useCallback, useRef } from 'react'; import { LocalStorageKeys, TFile } from 'librechat-data-provider'; import type { ExtendedFile } from '~/common'; import { useChatFormContext } from '~/Providers'; @@ -52,7 +52,7 @@ export const useAutoSave = ({ } }; - const restoreFiles = useCallback( + const restoreFilesRaw = useCallback( (id: string) => { const filesDraft = JSON.parse( (localStorage.getItem(`${LocalStorageKeys.FILES_DRAFT}${id}`) ?? '') || '[]', @@ -92,7 +92,7 @@ export const useAutoSave = ({ [fileList, setFiles], ); - const restoreText = useCallback( + const restoreTextRaw = useCallback( (id: string) => { const savedDraft = (localStorage.getItem(`${LocalStorageKeys.TEXT_DRAFT}${id}`) ?? '') || ''; setValue('text', decodeBase64(savedDraft)); @@ -100,6 +100,32 @@ export const useAutoSave = ({ [setValue], ); + const restoreFilesRef = useRef( + debounce((id: string) => { + restoreFilesRaw(id); + }, 500), + ); + + const restoreTextRef = useRef( + debounce((id: string) => { + restoreTextRaw(id); + }, 500), + ); + + const restoreFiles = useCallback( + (id: string) => { + restoreFilesRef.current(id); + }, + [restoreFilesRef], + ); + + const restoreText = useCallback( + (id: string) => { + restoreTextRef.current(id); + }, + [restoreTextRef], + ); + const saveText = useCallback( (id: string) => { if (!textAreaRef?.current) { @@ -150,6 +176,16 @@ export const useAutoSave = ({ }; }, [conversationId, saveDrafts, textAreaRef]); + // Clean up debounced functions on unmount + useEffect(() => { + const filesRefCurrent = restoreFilesRef.current; + const textRefCurrent = restoreTextRef.current; + return () => { + filesRefCurrent.cancel(); + textRefCurrent.cancel(); + }; + }, []); + useEffect(() => { // This useEffect is responsible for saving the current conversation's draft and // restoring the new conversation's draft when switching between conversations. @@ -171,6 +207,7 @@ export const useAutoSave = ({ saveText(currentConversationId); } + // Call the debounced restore functions restoreText(conversationId); restoreFiles(conversationId); } catch (e) {