From e8467fca929df480bf43283b2dce0e58d1857bdc Mon Sep 17 00:00:00 2001
From: Your Name <you@example.com>
Date: Sat, 3 Feb 2024 22:38:06 -0600
Subject: [PATCH] update: we can change the chat title for each session
 following the Chatgpt

---
 src/App.tsx                |  22 ++++++++
 src/components/Sidebar.tsx | 100 +++++++++++++++++++++++++++++++++----
 src/store/sessions.tsx     |   1 +
 3 files changed, 113 insertions(+), 10 deletions(-)

diff --git a/src/App.tsx b/src/App.tsx
index a880483..b7ad283 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -70,6 +70,26 @@ const App = () => {
         }
     };
 
+    const onRenameSession = (id: string, newTitle: string) => {
+        let confirmStr = "确定要更新主题名称变更为 " + newTitle + " 吗?  ";
+        const _sessions = {
+                ...sessions,
+                [id]: [
+                    {
+                        ...sessions[id][0],
+                        title: newTitle
+                    },
+                    ...sessions[id].slice(1)
+                ],
+            };
+
+        sendUserConfirm(confirmStr, () => {
+            dispatch(updateSessions(_sessions));
+            sendUserAlert("对话记录已更新");
+        });
+
+    };
+
     const handleDeleteSession = (id: string) => {
         sendUserConfirm("确定要删除这条对话记录吗?", () => {
             navigate(routes.index.prefix);
@@ -138,6 +158,7 @@ const App = () => {
                 {
                     role: "user",
                     parts: prompt,
+                    title: prompt.slice(0, 20),
                     timestamp: currentTimestamp,
                     attachment: uploadInlineData,
                 },
@@ -221,6 +242,7 @@ const App = () => {
                         newChatUrl={routes.index.prefix}
                         onExportSession={handleExportSession}
                         onDeleteSession={handleDeleteSession}
+                        onRenameSession={onRenameSession}
                     />
                     <Container
                         ref={mainSectionRef}
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx
index 1e03238..9587302 100644
--- a/src/components/Sidebar.tsx
+++ b/src/components/Sidebar.tsx
@@ -1,5 +1,7 @@
 import exportIcon from "../assets/icons/file-export-solid.svg";
 import deleteIcon from "../assets/icons/trash-can-solid.svg";
+import renameIcon from "../assets/icons/pen-to-square-solid.svg";
+
 import historyIcon from "../assets/icons/clock-rotate-left-solid.svg";
 import { useEffect, useState } from "react";
 import { Link } from "react-router-dom";
@@ -13,6 +15,7 @@ interface SidebarProps {
     readonly sessions: Sessions;
     readonly onDeleteSession?: (id: string) => void;
     readonly onExportSession?: (id: string) => void;
+    readonly onRenameSession?: (id: string, newTitle: string) => void;
 }
 
 export const Sidebar = (props: SidebarProps) => {
@@ -24,8 +27,12 @@ export const Sidebar = (props: SidebarProps) => {
         sessions,
         onDeleteSession,
         onExportSession,
+        onRenameSession,
     } = props;
 
+    const [editingId, setEditingId] = useState("")
+    const [chatTitle, setChatTitle] = useState("")
+
     const [sessionsLimitation, setSessionsLimitation] = useState(
         limitation || 10
     );
@@ -115,8 +122,35 @@ export const Sidebar = (props: SidebarProps) => {
                                         className="flex-1 text-sm text-left truncate"
                                         to={`/chat/${item}`}
                                     >
-                                        {sessionsCategory.today[item][0].parts}
+                                        
+                                        {sessionsCategory.today[item][0].title? sessionsCategory.today[item][0].title : sessionsCategory.today[item][0].parts}
                                     </Link>
+                                    {editingId == item ? (
+                                    <input 
+                                        autoFocus={true}
+                                        className="flex=1 min-w-0 bg-transparent outline-none"
+                                        value={chatTitle}
+                                        onChange={(e) => {
+                                            setChatTitle(e.target.value)
+                                        }}
+                                        onBlur={(e)=>{
+                                            onRenameSession &&
+                                            onRenameSession(item, e.target.value)
+                                            setEditingId("")
+                                        }}
+                                        
+                                     />) :(
+                                    <img
+                                        className="cursor-pointer text-xs size-3 hover:scale-125 transition-all"
+                                        src={renameIcon}
+                                        alt="Rename"
+                                        onClick={() => {
+                                            setEditingId(item)
+                                            setChatTitle(String(sessionsCategory.today[item][0].title? sessionsCategory.today[item][0].title : sessionsCategory.today[item][0].parts))
+                                        }
+
+                                        }
+                                    />)}
                                     <img
                                         className="cursor-pointer text-xs size-3 hover:scale-125 transition-all"
                                         src={exportIcon}
@@ -152,11 +186,35 @@ export const Sidebar = (props: SidebarProps) => {
                                         className="flex-1 text-sm text-left truncate"
                                         to={`/chat/${item}`}
                                     >
-                                        {
-                                            sessionsCategory.yesterday[item][0]
-                                                .parts
-                                        }
+    
+                                        {sessionsCategory.yesterday[item][0].title? sessionsCategory.yesterday[item][0].title : sessionsCategory.yesterday[item][0].parts}
                                     </Link>
+                                    {editingId == item ? (
+                                    <input 
+                                        autoFocus={true}
+                                        className="flex=1 min-w-0 bg-transparent outline-none"
+                                        value={chatTitle}
+                                        onChange={(e) => {
+                                            setChatTitle(e.target.value)
+                                        }}
+                                        onBlur={(e)=>{
+                                            onRenameSession &&
+                                            onRenameSession(item, e.target.value)
+                                            setEditingId("")
+                                        }}
+                                        
+                                     />) :(
+                                    <img
+                                        className="cursor-pointer text-xs size-3 hover:scale-125 transition-all"
+                                        src={renameIcon}
+                                        alt="Rename"
+                                        onClick={() => {
+                                            setEditingId(item)
+                                            setChatTitle(String(sessionsCategory.yesterday[item][0].title? sessionsCategory.yesterday[item][0].title : sessionsCategory.yesterday[item][0].parts))
+                                        }
+
+                                        }
+                                    />)}
                                     <img
                                         className="cursor-pointer text-xs size-3 hover:scale-125 transition-all"
                                         src={exportIcon}
@@ -194,12 +252,34 @@ export const Sidebar = (props: SidebarProps) => {
                                             className="flex-1 text-sm text-left truncate"
                                             to={`/chat/${item}`}
                                         >
-                                            {
-                                                sessionsCategory.earlier[
-                                                    item
-                                                ][0].parts
-                                            }
+                                            {sessionsCategory.earlier[item][0].title? sessionsCategory.earlier[item][0].title : sessionsCategory.earlier[item][0].parts}
                                         </Link>
+                                        {editingId == item ? (
+                                        <input 
+                                            autoFocus={true}
+                                            className="flex=1 min-w-0 bg-transparent outline-none"
+                                            value={chatTitle}
+                                            onChange={(e) => {
+                                                setChatTitle(e.target.value)
+                                            }}
+                                            onBlur={(e)=>{
+                                                onRenameSession &&
+                                                onRenameSession(item, e.target.value)
+                                                setEditingId("")
+                                            }}
+                                            
+                                        />) :(
+                                        <img
+                                            className="cursor-pointer text-xs size-3 hover:scale-125 transition-all"
+                                            src={renameIcon}
+                                            alt="Rename"
+                                            onClick={() => {
+                                                setEditingId(item)
+                                                setChatTitle(String(sessionsCategory.yesterday[item][0].title? sessionsCategory.yesterday[item][0].title : sessionsCategory.yesterday[item][0].parts))
+                                            }
+
+                                            }
+                                        />)}
                                         <img
                                             className="cursor-pointer text-xs size-3 hover:scale-125 transition-all"
                                             src={exportIcon}
diff --git a/src/store/sessions.tsx b/src/store/sessions.tsx
index 175641d..d627464 100644
--- a/src/store/sessions.tsx
+++ b/src/store/sessions.tsx
@@ -6,6 +6,7 @@ export interface SessionHistory {
     readonly parts: string;
     readonly timestamp: number;
     readonly attachment?: GenerativeContentBlob;
+    readonly title?: string;
 }
 export type Sessions = Record<string, SessionHistory[]>;
 export const initialSessions: Sessions = {};