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";
|
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;
|
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"}>
|
|
|
|
<BotIcon></BotIcon>
|
|
|
|
</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}
|
|
|
|
time={item.lastUpdate}
|
|
|
|
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}
|
2023-04-05 17:34:46 +00:00
|
|
|
/>
|
|
|
|
))}
|
|
|
|
{provided.placeholder}
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</Droppable>
|
|
|
|
</DragDropContext>
|
2023-04-02 15:05:54 +00:00
|
|
|
);
|
|
|
|
}
|