mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 09:50:15 +01:00
✍️ feat: Automatic Save and Restore for Chat (#2942)
* feat: added "Save draft locally" to Message settings * feat: add hook to save chat input as draft every second * fix: use filepath if the file does not have a preview prop * fix: not to delete temporary files when navigating to a new chat * chore: translations * chore: import order * chore: import order --------- Co-authored-by: Danny Avila <danacordially@gmail.com> Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
e9bbf39618
commit
29e71e98ad
22 changed files with 345 additions and 5 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { useForm } from 'react-hook-form';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { memo, useCallback, useRef, useMemo } from 'react';
|
||||
import { memo, useCallback, useRef, useMemo, useState, useEffect } from 'react';
|
||||
import {
|
||||
supportsFiles,
|
||||
mergeFileConfig,
|
||||
|
|
@ -8,6 +8,7 @@ import {
|
|||
fileConfig as defaultFileConfig,
|
||||
} from 'librechat-data-provider';
|
||||
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
||||
import { useAutoSave } from '~/hooks/Input/useAutoSave';
|
||||
import { useRequiresKey, useTextarea } from '~/hooks';
|
||||
import { TextareaAutosize } from '~/components/ui';
|
||||
import { useGetFileConfig } from '~/data-provider';
|
||||
|
|
@ -56,6 +57,14 @@ const ChatForm = ({ index = 0 }) => {
|
|||
handleStopGenerating,
|
||||
} = useChatContext();
|
||||
|
||||
const { clearDraft } = useAutoSave({
|
||||
conversationId: useMemo(() => conversation?.conversationId, [conversation]),
|
||||
textAreaRef,
|
||||
setValue: methods.setValue,
|
||||
files,
|
||||
setFiles,
|
||||
});
|
||||
|
||||
const assistantMap = useAssistantsMapContext();
|
||||
|
||||
const submitMessage = useCallback(
|
||||
|
|
@ -65,8 +74,9 @@ const ChatForm = ({ index = 0 }) => {
|
|||
}
|
||||
ask({ text: data.text });
|
||||
methods.reset();
|
||||
clearDraft();
|
||||
},
|
||||
[ask, methods],
|
||||
[ask, methods, clearDraft],
|
||||
);
|
||||
|
||||
const { endpoint: _endpoint, endpointType } = conversation ?? { endpoint: null };
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ export default function FileRow({
|
|||
return (
|
||||
<Image
|
||||
key={index}
|
||||
url={file.preview}
|
||||
url={file.preview || file.filepath}
|
||||
onDelete={handleDelete}
|
||||
progress={file.progress}
|
||||
source={file.source}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { SettingsTabValues } from 'librechat-data-provider';
|
|||
import SendMessageKeyEnter from './EnterToSend';
|
||||
import ShowCodeSwitch from './ShowCodeSwitch';
|
||||
import { ForkSettings } from './ForkSettings';
|
||||
import SaveDraft from './SaveDraft';
|
||||
|
||||
function Messages() {
|
||||
return (
|
||||
|
|
@ -15,6 +16,9 @@ function Messages() {
|
|||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-600">
|
||||
<ShowCodeSwitch />
|
||||
</div>
|
||||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-600">
|
||||
<SaveDraft />
|
||||
</div>
|
||||
<ForkSettings />
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
import { useRecoilState } from 'recoil';
|
||||
import { Switch } from '~/components/ui/Switch';
|
||||
import useLocalize from '~/hooks/useLocalize';
|
||||
import store from '~/store';
|
||||
|
||||
export default function SaveDraft({
|
||||
onCheckedChange,
|
||||
}: {
|
||||
onCheckedChange?: (value: boolean) => void;
|
||||
}) {
|
||||
const [saveDrafts, setSaveDrafts] = useRecoilState<boolean>(store.saveDrafts);
|
||||
const localize = useLocalize();
|
||||
|
||||
const handleCheckedChange = (value: boolean) => {
|
||||
setSaveDrafts(value);
|
||||
if (onCheckedChange) {
|
||||
onCheckedChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between">
|
||||
<div>{localize('com_nav_save_drafts')}</div>
|
||||
<Switch
|
||||
id="saveDrafts"
|
||||
checked={saveDrafts}
|
||||
onCheckedChange={handleCheckedChange}
|
||||
className="ml-4 mt-2"
|
||||
data-testid="saveDrafts"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue