Browse Source

fix: #1130 #1131 delete right session

Yidadaa 1 year ago
parent
commit
c37885e743
4 changed files with 58 additions and 58 deletions
  1. 8 5
      app/components/chat-list.tsx
  2. 5 1
      app/components/sidebar.tsx
  3. 6 2
      app/components/ui-lib.tsx
  4. 39 50
      app/store/chat.ts

+ 8 - 5
app/components/chat-list.tsx

@@ -67,7 +67,10 @@ export function ChatItem(props: {
             </>
           )}
 
-          <div className={styles["chat-item-delete"]} onClick={props.onDelete}>
+          <div
+            className={styles["chat-item-delete"]}
+            onClickCapture={props.onDelete}
+          >
             <DeleteIcon />
           </div>
         </div>
@@ -77,14 +80,14 @@ export function ChatItem(props: {
 }
 
 export function ChatList(props: { narrow?: boolean }) {
-  const [sessions, selectedIndex, selectSession, removeSession, moveSession] =
-    useChatStore((state) => [
+  const [sessions, selectedIndex, selectSession, moveSession] = useChatStore(
+    (state) => [
       state.sessions,
       state.currentSessionIndex,
       state.selectSession,
-      state.removeSession,
       state.moveSession,
-    ]);
+    ],
+  );
   const chatStore = useChatStore();
   const navigate = useNavigate();
 

+ 5 - 1
app/components/sidebar.tsx

@@ -138,7 +138,11 @@ export function SideBar(props: { className?: string }) {
           <div className={styles["sidebar-action"] + " " + styles.mobile}>
             <IconButton
               icon={<CloseIcon />}
-              onClick={chatStore.deleteSession}
+              onClick={() => {
+                if (confirm(Locale.Home.DeleteChat)) {
+                  chatStore.deleteSession(chatStore.currentSessionIndex);
+                }
+              }}
             />
           </div>
           <div className={styles["sidebar-action"]}>

+ 6 - 2
app/components/ui-lib.tsx

@@ -158,6 +158,7 @@ export type ToastProps = {
     text: string;
     onClick: () => void;
   };
+  onClose?: () => void;
 };
 
 export function Toast(props: ToastProps) {
@@ -167,7 +168,10 @@ export function Toast(props: ToastProps) {
         <span>{props.content}</span>
         {props.action && (
           <button
-            onClick={props.action.onClick}
+            onClick={() => {
+              props.action?.onClick?.();
+              props.onClose?.();
+            }}
             className={styles["toast-action"]}
           >
             {props.action.text}
@@ -201,7 +205,7 @@ export function showToast(
     close();
   }, delay);
 
-  root.render(<Toast content={content} action={action} />);
+  root.render(<Toast content={content} action={action} onClose={close} />);
 }
 
 export type InputProps = React.HTMLProps<HTMLTextAreaElement> & {

+ 39 - 50
app/store/chat.ts

@@ -83,11 +83,10 @@ interface ChatStore {
   currentSessionIndex: number;
   globalId: number;
   clearSessions: () => void;
-  removeSession: (index: number) => void;
   moveSession: (from: number, to: number) => void;
   selectSession: (index: number) => void;
   newSession: (mask?: Mask) => void;
-  deleteSession: (index?: number) => void;
+  deleteSession: (index: number) => void;
   currentSession: () => ChatSession;
   onNewMessage: (message: Message) => void;
   onUserInput: (content: string) => Promise<void>;
@@ -130,31 +129,6 @@ export const useChatStore = create<ChatStore>()(
         });
       },
 
-      removeSession(index: number) {
-        set((state) => {
-          let nextIndex = state.currentSessionIndex;
-          const sessions = state.sessions;
-
-          if (sessions.length === 1) {
-            return {
-              currentSessionIndex: 0,
-              sessions: [createEmptySession()],
-            };
-          }
-
-          sessions.splice(index, 1);
-
-          if (nextIndex === index) {
-            nextIndex -= 1;
-          }
-
-          return {
-            currentSessionIndex: nextIndex,
-            sessions,
-          };
-        });
-      },
-
       moveSession(from: number, to: number) {
         set((state) => {
           const { sessions, currentSessionIndex: oldIndex } = state;
@@ -197,31 +171,46 @@ export const useChatStore = create<ChatStore>()(
         }));
       },
 
-      deleteSession(i?: number) {
-        const deletedSession = get().currentSession();
-        const index = i ?? get().currentSessionIndex;
-        const isLastSession = get().sessions.length === 1;
-        if (!isMobileScreen() || confirm(Locale.Home.DeleteChat)) {
-          get().removeSession(index);
+      deleteSession(index) {
+        const deletingLastSession = get().sessions.length === 1;
+        const deletedSession = get().sessions.at(index);
 
-          showToast(
-            Locale.Home.DeleteToast,
-            {
-              text: Locale.Home.Revert,
-              onClick() {
-                set((state) => ({
-                  sessions: state.sessions
-                    .slice(0, index)
-                    .concat([deletedSession])
-                    .concat(
-                      state.sessions.slice(index + Number(isLastSession)),
-                    ),
-                }));
-              },
-            },
-            5000,
-          );
+        if (!deletedSession) return;
+
+        const sessions = get().sessions.slice();
+        sessions.splice(index, 1);
+
+        let nextIndex = Math.min(
+          get().currentSessionIndex,
+          sessions.length - 1,
+        );
+
+        if (deletingLastSession) {
+          nextIndex = 0;
+          sessions.push(createEmptySession());
         }
+
+        // for undo delete action
+        const restoreState = {
+          currentSessionIndex: get().currentSessionIndex,
+          sessions: get().sessions.slice(),
+        };
+
+        set(() => ({
+          currentSessionIndex: nextIndex,
+          sessions,
+        }));
+
+        showToast(
+          Locale.Home.DeleteToast,
+          {
+            text: Locale.Home.Revert,
+            onClick() {
+              set(() => restoreState);
+            },
+          },
+          5000,
+        );
       },
 
       currentSession() {