* init version * fix auto scroll * bring back copy btn * bring back thought process * add lint and format check on CI * remove lang from html tag * allow multiple generations at the same time * lint and format combined * fix unused var * improve MarkdownDisplay * fix more latex * fix code block cannot be selected while generating
95 lines
3.1 KiB
TypeScript
95 lines
3.1 KiB
TypeScript
import { useEffect, useMemo, useState } from 'react';
|
|
import { classNames } from '../utils/misc';
|
|
import { Conversation } from '../utils/types';
|
|
import StorageUtils from '../utils/storage';
|
|
import { useNavigate, useParams } from 'react-router';
|
|
|
|
export default function Sidebar() {
|
|
const params = useParams();
|
|
const navigate = useNavigate();
|
|
const currConv = useMemo(
|
|
() => StorageUtils.getOneConversation(params.convId ?? ''),
|
|
[params.convId]
|
|
);
|
|
|
|
const [conversations, setConversations] = useState<Conversation[]>([]);
|
|
|
|
useEffect(() => {
|
|
const handleConversationChange = () => {
|
|
setConversations(StorageUtils.getAllConversations());
|
|
};
|
|
StorageUtils.onConversationChanged(handleConversationChange);
|
|
handleConversationChange();
|
|
return () => {
|
|
StorageUtils.offConversationChanged(handleConversationChange);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
<input
|
|
id="toggle-drawer"
|
|
type="checkbox"
|
|
className="drawer-toggle"
|
|
defaultChecked
|
|
/>
|
|
|
|
<div className="drawer-side h-screen lg:h-screen z-50 lg:max-w-64">
|
|
<label
|
|
htmlFor="toggle-drawer"
|
|
aria-label="close sidebar"
|
|
className="drawer-overlay"
|
|
></label>
|
|
<div className="flex flex-col bg-base-200 min-h-full max-w-64 py-4 px-4">
|
|
<div className="flex flex-row items-center justify-between mb-4 mt-4">
|
|
<h2 className="font-bold ml-4">Conversations</h2>
|
|
|
|
{/* close sidebar button */}
|
|
<label htmlFor="toggle-drawer" className="btn btn-ghost lg:hidden">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="16"
|
|
height="16"
|
|
fill="currentColor"
|
|
className="bi bi-arrow-bar-left"
|
|
viewBox="0 0 16 16"
|
|
>
|
|
<path
|
|
fillRule="evenodd"
|
|
d="M12.5 15a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5M10 8a.5.5 0 0 1-.5.5H3.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L3.707 7.5H9.5a.5.5 0 0 1 .5.5"
|
|
/>
|
|
</svg>
|
|
</label>
|
|
</div>
|
|
|
|
{/* list of conversations */}
|
|
<div
|
|
className={classNames({
|
|
'btn btn-ghost justify-start': true,
|
|
'btn-active': !currConv,
|
|
})}
|
|
onClick={() => navigate('/')}
|
|
>
|
|
+ New conversation
|
|
</div>
|
|
{conversations.map((conv) => (
|
|
<div
|
|
key={conv.id}
|
|
className={classNames({
|
|
'btn btn-ghost justify-start font-normal': true,
|
|
'btn-active': conv.id === currConv?.id,
|
|
})}
|
|
onClick={() => navigate(`/chat/${conv.id}`)}
|
|
dir="auto"
|
|
>
|
|
<span className="truncate">{conv.messages[0].content}</span>
|
|
</div>
|
|
))}
|
|
<div className="text-center text-xs opacity-40 mt-auto mx-4">
|
|
Conversations are saved to browser's localStorage
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|