mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-20 02:10:15 +01:00
🏄♂️ fix: Handle SSE Stream Edge Case (#8556)
* refactor: Move draft-related utilities to a new `drafts.ts` file * refactor: auto-save draft logic to use new get/set functions * fix: Ensure `getDraft` properly decodes stored draft values * fix: Handle edge case where stream is cancelled before any response, which creates a blank page
This commit is contained in:
parent
f70e0cf849
commit
4c754c1190
4 changed files with 87 additions and 56 deletions
|
|
@ -4,36 +4,11 @@ import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
|
|||
import { LocalStorageKeys, Constants } from 'librechat-data-provider';
|
||||
import type { TFile } from 'librechat-data-provider';
|
||||
import type { ExtendedFile } from '~/common';
|
||||
import { clearDraft, getDraft, setDraft } from '~/utils';
|
||||
import { useChatFormContext } from '~/Providers';
|
||||
import { useGetFiles } from '~/data-provider';
|
||||
import store from '~/store';
|
||||
|
||||
const clearDraft = debounce((id?: string | null) => {
|
||||
localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${id ?? ''}`);
|
||||
}, 2500);
|
||||
|
||||
const encodeBase64 = (plainText: string): string => {
|
||||
try {
|
||||
const textBytes = new TextEncoder().encode(plainText);
|
||||
return btoa(String.fromCharCode(...textBytes));
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const decodeBase64 = (base64String: string): string => {
|
||||
try {
|
||||
const bytes = atob(base64String);
|
||||
const uint8Array = new Uint8Array(bytes.length);
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
uint8Array[i] = bytes.charCodeAt(i);
|
||||
}
|
||||
return new TextDecoder().decode(uint8Array);
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
export const useAutoSave = ({
|
||||
isSubmitting,
|
||||
conversationId: _conversationId,
|
||||
|
|
@ -98,8 +73,11 @@ export const useAutoSave = ({
|
|||
|
||||
const restoreText = useCallback(
|
||||
(id: string) => {
|
||||
const savedDraft = (localStorage.getItem(`${LocalStorageKeys.TEXT_DRAFT}${id}`) ?? '') || '';
|
||||
setValue('text', decodeBase64(savedDraft));
|
||||
const savedDraft = getDraft(id);
|
||||
if (!savedDraft) {
|
||||
return;
|
||||
}
|
||||
setValue('text', savedDraft);
|
||||
},
|
||||
[setValue],
|
||||
);
|
||||
|
|
@ -113,10 +91,7 @@ export const useAutoSave = ({
|
|||
if (textAreaRef.current.value === '' || textAreaRef.current.value.length === 1) {
|
||||
clearDraft(id);
|
||||
} else {
|
||||
localStorage.setItem(
|
||||
`${LocalStorageKeys.TEXT_DRAFT}${id}`,
|
||||
encodeBase64(textAreaRef.current.value),
|
||||
);
|
||||
setDraft({ id, value: textAreaRef.current.value });
|
||||
}
|
||||
},
|
||||
[textAreaRef],
|
||||
|
|
@ -130,16 +105,7 @@ export const useAutoSave = ({
|
|||
return;
|
||||
}
|
||||
|
||||
const handleInput = debounce((value: string) => {
|
||||
if (value && value.length > 1) {
|
||||
localStorage.setItem(
|
||||
`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`,
|
||||
encodeBase64(value),
|
||||
);
|
||||
} else {
|
||||
localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`);
|
||||
}
|
||||
}, 750);
|
||||
const handleInput = debounce((value: string) => setDraft({ id: conversationId, value }), 750);
|
||||
|
||||
const eventListener = (e: Event) => {
|
||||
const target = e.target as HTMLTextAreaElement;
|
||||
|
|
@ -194,10 +160,7 @@ export const useAutoSave = ({
|
|||
if (pendingDraft) {
|
||||
localStorage.setItem(`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`, pendingDraft);
|
||||
} else if (textAreaRef?.current?.value) {
|
||||
localStorage.setItem(
|
||||
`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`,
|
||||
encodeBase64(textAreaRef.current.value),
|
||||
);
|
||||
setDraft({ id: conversationId, value: textAreaRef.current.value });
|
||||
}
|
||||
const pendingFileDraft = localStorage.getItem(
|
||||
`${LocalStorageKeys.FILES_DRAFT}${Constants.PENDING_CONVO}`,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue