完善会话默认选中的逻辑

fix: #1130

删除会话后,默认选中的逻辑:
如果删除的会话是当前选中的会话,将下一个会话作为默认选中。
如果删除的会话不是当前选中的会话,保持当前会话的选中状态。

撤销删除后,默认选中的逻辑:
如果删除的会话删除前是选中状态,恢复会话的同时恢复选中的状态。
如果删除的会话删除前不是选中的状态,则恢复会话后,保持当前选中的会话窗口的选中状态不变。
This commit is contained in:
jinmiaoluo
2023-04-28 12:16:14 +08:00
parent 6419ce345f
commit 187a93a67f
3 changed files with 53 additions and 21 deletions

View File

@@ -16,6 +16,7 @@ import { Link, useNavigate } from "react-router-dom";
import { Path } from "../constant"; import { Path } from "../constant";
import { MaskAvatar } from "./mask"; import { MaskAvatar } from "./mask";
import { Mask } from "../store/mask"; import { Mask } from "../store/mask";
import { MouseEvent } from "react";
export function ChatItem(props: { export function ChatItem(props: {
onClick?: () => void; onClick?: () => void;
@@ -29,6 +30,14 @@ export function ChatItem(props: {
narrow?: boolean; narrow?: boolean;
mask: Mask; mask: Mask;
}) { }) {
const handleDeleteClick = (event: MouseEvent) => {
// Avoid triggering the onClick event of the parent component.
event.stopPropagation();
if (props.onDelete) {
props.onDelete();
}
};
return ( return (
<Draggable draggableId={`${props.id}`} index={props.index}> <Draggable draggableId={`${props.id}`} index={props.index}>
{(provided) => ( {(provided) => (
@@ -67,7 +76,10 @@ export function ChatItem(props: {
</> </>
)} )}
<div className={styles["chat-item-delete"]} onClick={props.onDelete}> <div
className={styles["chat-item-delete"]}
onClick={handleDeleteClick}
>
<DeleteIcon /> <DeleteIcon />
</div> </div>
</div> </div>

View File

@@ -81,8 +81,13 @@ function useDragSideBar() {
} }
export function SideBar(props: { className?: string }) { export function SideBar(props: { className?: string }) {
const chatStore = useChatStore(); const [newSession, deleteSession, currentSessionIndex] = useChatStore(
(state) => [
state.newSession,
state.deleteSession,
state.currentSessionIndex,
],
);
// drag side bar // drag side bar
const { onDragMouseDown, shouldNarrow } = useDragSideBar(); const { onDragMouseDown, shouldNarrow } = useDragSideBar();
const navigate = useNavigate(); const navigate = useNavigate();
@@ -138,7 +143,9 @@ export function SideBar(props: { className?: string }) {
<div className={styles["sidebar-action"] + " " + styles.mobile}> <div className={styles["sidebar-action"] + " " + styles.mobile}>
<IconButton <IconButton
icon={<CloseIcon />} icon={<CloseIcon />}
onClick={chatStore.deleteSession} onClick={() => {
deleteSession(currentSessionIndex);
}}
/> />
</div> </div>
<div className={styles["sidebar-action"]}> <div className={styles["sidebar-action"]}>
@@ -158,7 +165,7 @@ export function SideBar(props: { className?: string }) {
text={shouldNarrow ? undefined : Locale.Home.NewChat} text={shouldNarrow ? undefined : Locale.Home.NewChat}
onClick={() => { onClick={() => {
if (config.dontShowMaskSplashScreen) { if (config.dontShowMaskSplashScreen) {
chatStore.newSession(); newSession();
} else { } else {
navigate(Path.NewChat); navigate(Path.NewChat);
} }

View File

@@ -87,7 +87,7 @@ interface ChatStore {
moveSession: (from: number, to: number) => void; moveSession: (from: number, to: number) => void;
selectSession: (index: number) => void; selectSession: (index: number) => void;
newSession: (mask?: Mask) => void; newSession: (mask?: Mask) => void;
deleteSession: (index?: number) => void; deleteSession: (index: number) => void;
currentSession: () => ChatSession; currentSession: () => ChatSession;
onNewMessage: (message: Message) => void; onNewMessage: (message: Message) => void;
onUserInput: (content: string) => Promise<void>; onUserInput: (content: string) => Promise<void>;
@@ -131,9 +131,9 @@ export const useChatStore = create<ChatStore>()(
}, },
removeSession(index: number) { removeSession(index: number) {
set((state) => { set(() => {
let nextIndex = state.currentSessionIndex; let selectedIndex = get().currentSessionIndex;
const sessions = state.sessions; const sessions = get().sessions;
if (sessions.length === 1) { if (sessions.length === 1) {
return { return {
@@ -142,14 +142,23 @@ export const useChatStore = create<ChatStore>()(
}; };
} }
sessions.splice(index, 1); // When one of the following conditions are met, the selected Index is reduced by one:
//
if (nextIndex === index) { // 1. The selected Index is greater than the current deleted Index
nextIndex -= 1; // 2. The selected Index is equal with the current deleted index, and the current deleted index is the last one
//
// In other cases, the selected Index remains unchanged
if (
selectedIndex > index ||
(selectedIndex === index && selectedIndex === sessions.length - 1)
) {
selectedIndex -= 1;
} }
sessions.splice(index, 1);
return { return {
currentSessionIndex: nextIndex, currentSessionIndex: selectedIndex,
sessions, sessions,
}; };
}); });
@@ -197,9 +206,12 @@ export const useChatStore = create<ChatStore>()(
})); }));
}, },
deleteSession(i?: number) { deleteSession(index: number) {
const deletedSession = get().currentSession(); const deletedSession = get().sessions[index];
const index = i ?? get().currentSessionIndex;
// On the desktop, the deleted session index may not be the current session index
const seletedSessionIndex = get().currentSessionIndex;
const isLastSession = get().sessions.length === 1; const isLastSession = get().sessions.length === 1;
if (!isMobileScreen() || confirm(Locale.Home.DeleteChat)) { if (!isMobileScreen() || confirm(Locale.Home.DeleteChat)) {
get().removeSession(index); get().removeSession(index);
@@ -209,13 +221,14 @@ export const useChatStore = create<ChatStore>()(
{ {
text: Locale.Home.Revert, text: Locale.Home.Revert,
onClick() { onClick() {
set((state) => ({ set(() => ({
sessions: state.sessions sessions: get()
.slice(0, index) .sessions.slice(0, index)
.concat([deletedSession]) .concat([deletedSession])
.concat( .concat(
state.sessions.slice(index + Number(isLastSession)), get().sessions.slice(index + Number(isLastSession)),
), ),
currentSessionIndex: seletedSessionIndex,
})); }));
}, },
}, },