mirror of
https://github.com/stackblitz/bolt.new
synced 2025-02-06 04:48:04 +00:00
Add ability to return to older chat message state
This commit is contained in:
parent
b7d609d315
commit
a0ae79a993
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import { classNames } from '~/utils/classNames';
|
import { classNames } from '~/utils/classNames';
|
||||||
import { AssistantMessage } from './AssistantMessage';
|
import { AssistantMessage } from './AssistantMessage';
|
||||||
import { UserMessage } from './UserMessage';
|
import { UserMessage } from './UserMessage';
|
||||||
|
import { useLocation, useNavigate } from '@remix-run/react';
|
||||||
|
|
||||||
interface MessagesProps {
|
interface MessagesProps {
|
||||||
id?: string;
|
id?: string;
|
||||||
@ -13,12 +14,21 @@ interface MessagesProps {
|
|||||||
|
|
||||||
export const Messages = React.forwardRef<HTMLDivElement, MessagesProps>((props: MessagesProps, ref) => {
|
export const Messages = React.forwardRef<HTMLDivElement, MessagesProps>((props: MessagesProps, ref) => {
|
||||||
const { id, isStreaming = false, messages = [] } = props;
|
const { id, isStreaming = false, messages = [] } = props;
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleRewind = (messageId: string) => {
|
||||||
|
const searchParams = new URLSearchParams(location.search);
|
||||||
|
searchParams.set('rewindId', messageId);
|
||||||
|
window.location.search = searchParams.toString();
|
||||||
|
//navigate(`${location.pathname}?${searchParams.toString()}`);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id={id} ref={ref} className={props.className}>
|
<div id={id} ref={ref} className={props.className}>
|
||||||
{messages.length > 0
|
{messages.length > 0
|
||||||
? messages.map((message, index) => {
|
? messages.map((message, index) => {
|
||||||
const { role, content } = message;
|
const { role, content, id: messageId } = message;
|
||||||
const isUserMessage = role === 'user';
|
const isUserMessage = role === 'user';
|
||||||
const isFirst = index === 0;
|
const isFirst = index === 0;
|
||||||
const isLast = index === messages.length - 1;
|
const isLast = index === messages.length - 1;
|
||||||
@ -41,6 +51,15 @@ export const Messages = React.forwardRef<HTMLDivElement, MessagesProps>((props:
|
|||||||
<div className="grid grid-col-1 w-full">
|
<div className="grid grid-col-1 w-full">
|
||||||
{isUserMessage ? <UserMessage content={content} /> : <AssistantMessage content={content} />}
|
{isUserMessage ? <UserMessage content={content} /> : <AssistantMessage content={content} />}
|
||||||
</div>
|
</div>
|
||||||
|
{messageId && (
|
||||||
|
<button
|
||||||
|
onClick={() => handleRewind(messageId)}
|
||||||
|
className="self-start p-2 text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary"
|
||||||
|
title="Rewind to this message"
|
||||||
|
>
|
||||||
|
<div className="i-ph:arrow-counter-clockwise text-xl"></div>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useLoaderData, useNavigate } from '@remix-run/react';
|
import { useLoaderData, useNavigate, useSearchParams } from '@remix-run/react';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { atom } from 'nanostores';
|
import { atom } from 'nanostores';
|
||||||
import type { Message } from 'ai';
|
import type { Message } from 'ai';
|
||||||
@ -24,6 +24,7 @@ export const description = atom<string | undefined>(undefined);
|
|||||||
export function useChatHistory() {
|
export function useChatHistory() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { id: mixedId } = useLoaderData<{ id?: string }>();
|
const { id: mixedId } = useLoaderData<{ id?: string }>();
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
|
||||||
const [initialMessages, setInitialMessages] = useState<Message[]>([]);
|
const [initialMessages, setInitialMessages] = useState<Message[]>([]);
|
||||||
const [ready, setReady] = useState<boolean>(false);
|
const [ready, setReady] = useState<boolean>(false);
|
||||||
@ -44,7 +45,13 @@ export function useChatHistory() {
|
|||||||
getMessages(db, mixedId)
|
getMessages(db, mixedId)
|
||||||
.then((storedMessages) => {
|
.then((storedMessages) => {
|
||||||
if (storedMessages && storedMessages.messages.length > 0) {
|
if (storedMessages && storedMessages.messages.length > 0) {
|
||||||
setInitialMessages(storedMessages.messages);
|
const rewindId = searchParams.get('rewindId');
|
||||||
|
const filteredMessages = rewindId
|
||||||
|
? storedMessages.messages.slice(0,
|
||||||
|
storedMessages.messages.findIndex(m => m.id === rewindId) + 1)
|
||||||
|
: storedMessages.messages;
|
||||||
|
|
||||||
|
setInitialMessages(filteredMessages);
|
||||||
setUrlId(storedMessages.urlId);
|
setUrlId(storedMessages.urlId);
|
||||||
description.set(storedMessages.description);
|
description.set(storedMessages.description);
|
||||||
chatId.set(storedMessages.id);
|
chatId.set(storedMessages.id);
|
||||||
|
Loading…
Reference in New Issue
Block a user