mirror of
https://github.com/NovaOSS/nova-betterchat.git
synced 2024-11-25 21:34:00 +01:00
feat: change tab title to current chat title
This commit is contained in:
parent
f58382137d
commit
bdc385158b
|
@ -11,12 +11,22 @@ import CrossIcon from '@icon/CrossIcon';
|
||||||
import useInitialiseNewChat from '@hooks/useInitialiseNewChat';
|
import useInitialiseNewChat from '@hooks/useInitialiseNewChat';
|
||||||
|
|
||||||
const ChatHistoryList = () => {
|
const ChatHistoryList = () => {
|
||||||
const setCurrentChatIndex = useStore((state) => state.setCurrentChatIndex);
|
const currentChatIndex = useStore((state) => state.currentChatIndex);
|
||||||
const chatTitles = useStore(
|
const chatTitles = useStore(
|
||||||
(state) => state.chats?.map((chat) => chat.title),
|
(state) => state.chats?.map((chat) => chat.title),
|
||||||
shallow
|
shallow
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
chatTitles &&
|
||||||
|
currentChatIndex >= 0 &&
|
||||||
|
currentChatIndex < chatTitles.length
|
||||||
|
) {
|
||||||
|
document.title = chatTitles[currentChatIndex];
|
||||||
|
}
|
||||||
|
}, [currentChatIndex, chatTitles]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex-col flex-1 overflow-y-auto border-b border-white/20'>
|
<div className='flex-col flex-1 overflow-y-auto border-b border-white/20'>
|
||||||
<div className='flex flex-col gap-2 text-gray-100 text-sm'>
|
<div className='flex flex-col gap-2 text-gray-100 text-sm'>
|
||||||
|
@ -26,9 +36,6 @@ const ChatHistoryList = () => {
|
||||||
title={title}
|
title={title}
|
||||||
key={`${title}-${index}`}
|
key={`${title}-${index}`}
|
||||||
chatIndex={index}
|
chatIndex={index}
|
||||||
onClick={() => {
|
|
||||||
setCurrentChatIndex(index);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{/* <ShowMoreButton /> */}
|
{/* <ShowMoreButton /> */}
|
||||||
|
@ -56,117 +63,113 @@ const ChatHistoryClass = {
|
||||||
'absolute inset-y-0 right-0 w-8 z-10 bg-gradient-to-l from-gray-800',
|
'absolute inset-y-0 right-0 w-8 z-10 bg-gradient-to-l from-gray-800',
|
||||||
};
|
};
|
||||||
|
|
||||||
const ChatHistory = ({
|
const ChatHistory = React.memo(
|
||||||
title,
|
({ title, chatIndex }: { title: string; chatIndex: number }) => {
|
||||||
chatIndex,
|
const initialiseNewChat = useInitialiseNewChat();
|
||||||
onClick,
|
const setCurrentChatIndex = useStore((state) => state.setCurrentChatIndex);
|
||||||
}: {
|
const setChats = useStore((state) => state.setChats);
|
||||||
title: string;
|
const active = useStore((state) => state.currentChatIndex === chatIndex);
|
||||||
chatIndex: number;
|
|
||||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
||||||
}) => {
|
|
||||||
const initialiseNewChat = useInitialiseNewChat();
|
|
||||||
const setCurrentChatIndex = useStore((state) => state.setCurrentChatIndex);
|
|
||||||
const setChats = useStore((state) => state.setChats);
|
|
||||||
const currentChatIndex = useStore((state) => state.currentChatIndex);
|
|
||||||
|
|
||||||
const [isDelete, setIsDelete] = useState<boolean>(false);
|
const [isDelete, setIsDelete] = useState<boolean>(false);
|
||||||
const [isEdit, setIsEdit] = useState<boolean>(false);
|
const [isEdit, setIsEdit] = useState<boolean>(false);
|
||||||
const [_title, _setTitle] = useState<string>(title);
|
const [_title, _setTitle] = useState<string>(title);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const active = currentChatIndex === chatIndex;
|
const handleTick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.stopPropagation();
|
||||||
const handleTick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
const updatedChats = JSON.parse(
|
||||||
e.stopPropagation();
|
JSON.stringify(useStore.getState().chats)
|
||||||
const updatedChats = JSON.parse(JSON.stringify(useStore.getState().chats));
|
);
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
updatedChats[chatIndex].title = _title;
|
updatedChats[chatIndex].title = _title;
|
||||||
setChats(updatedChats);
|
|
||||||
setIsEdit(false);
|
|
||||||
} else if (isDelete) {
|
|
||||||
updatedChats.splice(chatIndex, 1);
|
|
||||||
if (updatedChats.length > 0) {
|
|
||||||
setCurrentChatIndex(0);
|
|
||||||
setChats(updatedChats);
|
setChats(updatedChats);
|
||||||
} else {
|
setIsEdit(false);
|
||||||
initialiseNewChat();
|
} else if (isDelete) {
|
||||||
|
updatedChats.splice(chatIndex, 1);
|
||||||
|
if (updatedChats.length > 0) {
|
||||||
|
setCurrentChatIndex(0);
|
||||||
|
setChats(updatedChats);
|
||||||
|
} else {
|
||||||
|
initialiseNewChat();
|
||||||
|
}
|
||||||
|
setIsDelete(false);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCross = () => {
|
||||||
setIsDelete(false);
|
setIsDelete(false);
|
||||||
}
|
setIsEdit(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCross = () => {
|
useEffect(() => {
|
||||||
setIsDelete(false);
|
if (inputRef && inputRef.current) inputRef.current.focus();
|
||||||
setIsEdit(false);
|
}, [isEdit]);
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
return (
|
||||||
if (inputRef && inputRef.current) inputRef.current.focus();
|
<a
|
||||||
}, [isEdit]);
|
className={active ? ChatHistoryClass.active : ChatHistoryClass.normal}
|
||||||
|
onClick={(e) => {
|
||||||
return (
|
setCurrentChatIndex(chatIndex);
|
||||||
<a
|
}}
|
||||||
className={active ? ChatHistoryClass.active : ChatHistoryClass.normal}
|
>
|
||||||
onClick={(e) => onClick && onClick(e)}
|
<ChatIcon />
|
||||||
>
|
<div className='flex-1 text-ellipsis max-h-5 overflow-hidden break-all relative'>
|
||||||
<ChatIcon />
|
{isEdit ? (
|
||||||
<div className='flex-1 text-ellipsis max-h-5 overflow-hidden break-all relative'>
|
<input
|
||||||
{isEdit ? (
|
type='text'
|
||||||
<input
|
className='focus:outline-blue-600 text-sm border-none bg-transparent p-0 m-0 w-full'
|
||||||
type='text'
|
value={_title}
|
||||||
className='focus:outline-blue-600 text-sm border-none bg-transparent p-0 m-0 w-full'
|
onChange={(e) => {
|
||||||
value={_title}
|
_setTitle(e.target.value);
|
||||||
onChange={(e) => {
|
}}
|
||||||
_setTitle(e.target.value);
|
ref={inputRef}
|
||||||
}}
|
/>
|
||||||
ref={inputRef}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
_title
|
|
||||||
)}
|
|
||||||
|
|
||||||
{isEdit || (
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
active
|
|
||||||
? ChatHistoryClass.activeGradient
|
|
||||||
: ChatHistoryClass.normalGradient
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{active && (
|
|
||||||
<div className='absolute flex right-1 z-10 text-gray-300 visible'>
|
|
||||||
{isDelete || isEdit ? (
|
|
||||||
<>
|
|
||||||
<button className='p-1 hover:text-white' onClick={handleTick}>
|
|
||||||
<TickIcon />
|
|
||||||
</button>
|
|
||||||
<button className='p-1 hover:text-white' onClick={handleCross}>
|
|
||||||
<CrossIcon />
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
) : (
|
) : (
|
||||||
<>
|
_title
|
||||||
<button
|
)}
|
||||||
className='p-1 hover:text-white'
|
|
||||||
onClick={() => setIsEdit(true)}
|
{isEdit || (
|
||||||
>
|
<div
|
||||||
<EditIcon />
|
className={
|
||||||
</button>
|
active
|
||||||
<button
|
? ChatHistoryClass.activeGradient
|
||||||
className='p-1 hover:text-white'
|
: ChatHistoryClass.normalGradient
|
||||||
onClick={() => setIsDelete(true)}
|
}
|
||||||
>
|
/>
|
||||||
<DeleteIcon />
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
{active && (
|
||||||
</a>
|
<div className='absolute flex right-1 z-10 text-gray-300 visible'>
|
||||||
);
|
{isDelete || isEdit ? (
|
||||||
};
|
<>
|
||||||
|
<button className='p-1 hover:text-white' onClick={handleTick}>
|
||||||
|
<TickIcon />
|
||||||
|
</button>
|
||||||
|
<button className='p-1 hover:text-white' onClick={handleCross}>
|
||||||
|
<CrossIcon />
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
className='p-1 hover:text-white'
|
||||||
|
onClick={() => setIsEdit(true)}
|
||||||
|
>
|
||||||
|
<EditIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='p-1 hover:text-white'
|
||||||
|
onClick={() => setIsDelete(true)}
|
||||||
|
>
|
||||||
|
<DeleteIcon />
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default ChatHistoryList;
|
export default ChatHistoryList;
|
||||||
|
|
Loading…
Reference in a new issue