ChatGPT-Next-Web/app/components/chat-list.tsx

145 lines
4.0 KiB
TypeScript
Raw Normal View History

2023-04-02 15:05:54 +00:00
import DeleteIcon from "../icons/delete.svg";
2023-04-21 16:35:50 +00:00
import BotIcon from "../icons/bot.svg";
2023-04-02 15:05:54 +00:00
import styles from "./home.module.scss";
import {
2023-04-05 17:34:46 +00:00
DragDropContext,
Droppable,
Draggable,
OnDragEndResponder,
} from "@hello-pangea/dnd";
import { useChatStore } from "../store";
2023-04-02 15:05:54 +00:00
import Locale from "../locales";
2023-04-20 17:12:39 +00:00
import { Link, useNavigate } from "react-router-dom";
import { Path } from "../constant";
import { MaskAvatar } from "./mask";
import { Mask } from "../store/mask";
2023-04-02 15:05:54 +00:00
export function ChatItem(props: {
onClick?: () => void;
onDelete?: () => void;
title: string;
count: number;
time: string;
selected: boolean;
2023-04-05 17:34:46 +00:00
id: number;
index: number;
2023-04-20 18:52:53 +00:00
narrow?: boolean;
mask: Mask;
2023-04-02 15:05:54 +00:00
}) {
return (
2023-04-05 17:34:46 +00:00
<Draggable draggableId={`${props.id}`} index={props.index}>
{(provided) => (
<div
className={`${styles["chat-item"]} ${
props.selected && styles["chat-item-selected"]
}`}
onClick={props.onClick}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
2023-04-21 16:35:50 +00:00
title={`${props.title}\n${Locale.ChatItem.ChatItemCount(
props.count,
)}`}
2023-04-05 17:34:46 +00:00
>
2023-04-20 18:52:53 +00:00
{props.narrow ? (
2023-04-21 16:35:50 +00:00
<div className={styles["chat-item-narrow"]}>
<div className={styles["chat-item-avatar"] + " no-dark"}>
<MaskAvatar mask={props.mask} />
2023-04-21 16:35:50 +00:00
</div>
<div className={styles["chat-item-narrow-count"]}>
{props.count}
</div>
</div>
2023-04-20 18:52:53 +00:00
) : (
<>
<div className={styles["chat-item-title"]}>{props.title}</div>
<div className={styles["chat-item-info"]}>
<div className={styles["chat-item-count"]}>
{Locale.ChatItem.ChatItemCount(props.count)}
</div>
2023-04-25 18:02:46 +00:00
<div className={styles["chat-item-date"]}>
{new Date(props.time).toLocaleString()}
</div>
2023-04-20 18:52:53 +00:00
</div>
</>
)}
2023-04-05 17:34:46 +00:00
<div className={styles["chat-item-delete"]} onClick={props.onDelete}>
<DeleteIcon />
</div>
2023-04-02 15:05:54 +00:00
</div>
2023-04-05 17:34:46 +00:00
)}
</Draggable>
2023-04-02 15:05:54 +00:00
);
}
2023-04-20 18:52:53 +00:00
export function ChatList(props: { narrow?: boolean }) {
2023-04-05 17:34:46 +00:00
const [sessions, selectedIndex, selectSession, removeSession, moveSession] =
useChatStore((state) => [
2023-04-02 15:05:54 +00:00
state.sessions,
state.currentSessionIndex,
state.selectSession,
state.removeSession,
2023-04-05 17:34:46 +00:00
state.moveSession,
]);
2023-04-06 16:14:27 +00:00
const chatStore = useChatStore();
2023-04-20 17:12:39 +00:00
const navigate = useNavigate();
2023-04-05 17:34:46 +00:00
const onDragEnd: OnDragEndResponder = (result) => {
const { destination, source } = result;
if (!destination) {
return;
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
moveSession(source.index, destination.index);
};
2023-04-02 15:05:54 +00:00
return (
2023-04-05 17:34:46 +00:00
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="chat-list">
{(provided) => (
<div
className={styles["chat-list"]}
ref={provided.innerRef}
{...provided.droppableProps}
>
{sessions.map((item, i) => (
<ChatItem
title={item.topic}
2023-04-25 18:05:35 +00:00
time={new Date(item.lastUpdate).toLocaleString()}
2023-04-05 17:34:46 +00:00
count={item.messages.length}
key={item.id}
id={item.id}
index={i}
selected={i === selectedIndex}
2023-04-20 17:12:39 +00:00
onClick={() => {
navigate(Path.Chat);
selectSession(i);
}}
2023-04-20 18:52:53 +00:00
onDelete={() => {
if (!props.narrow || confirm(Locale.Home.DeleteChat)) {
chatStore.deleteSession(i);
}
}}
narrow={props.narrow}
mask={item.mask}
2023-04-05 17:34:46 +00:00
/>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
2023-04-02 15:05:54 +00:00
);
}