add feature to create new chat in a given folder (#174)

* add feature to create new chat in a given folder

This to not have to drag and drop a chat each time in a folder

* change style

* fix margin

* style: folder gradient

* style

---------

Co-authored-by: Jing Hua <59118459+ztjhz@users.noreply.github.com>
This commit is contained in:
Tindo N. Arsel 2023-04-03 17:33:40 +01:00 committed by GitHub
parent bfe3f1adfa
commit 6d1ae9f526
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 13 deletions

View file

@ -10,6 +10,7 @@ import {
} from '@type/chat';
import ChatHistory from './ChatHistory';
import NewChat from './NewChat';
import EditIcon from '@icon/EditIcon';
import DeleteIcon from '@icon/DeleteIcon';
import CrossIcon from '@icon/CrossIcon';
@ -35,6 +36,7 @@ const ChatFolder = ({
const inputRef = useRef<HTMLInputElement>(null);
const folderRef = useRef<HTMLDivElement>(null);
const gradientRef = useRef<HTMLDivElement>(null);
const [_folderName, _setFolderName] = useState<string>(folderName);
const [isEdit, setIsEdit] = useState<boolean>(false);
@ -153,16 +155,18 @@ const ChatFolder = ({
style={{ background: color || '' }}
className={`${
color ? '' : 'hover:bg-gray-850'
} transition-colors flex py-3 px-3 items-center gap-3 relative rounded-md break-all cursor-pointer`}
} transition-colors flex py-3 pl-3 pr-1 items-center gap-3 relative rounded-md break-all cursor-pointer`}
onClick={toggleExpanded}
ref={folderRef}
onMouseEnter={() => {
if (color && folderRef.current)
folderRef.current.style.background = `${color}dd`;
if (gradientRef.current) gradientRef.current.style.width = '0px';
}}
onMouseLeave={() => {
if (color && folderRef.current)
folderRef.current.style.background = color;
if (gradientRef.current) gradientRef.current.style.width = '1rem';
}}
>
<FolderIcon className='h-4 w-4' />
@ -182,6 +186,19 @@ const ChatFolder = ({
) : (
_folderName
)}
{isEdit || (
<div
ref={gradientRef}
className='absolute inset-y-0 right-0 w-4 z-10 transition-all'
style={{
background:
color &&
`linear-gradient(to left, ${
color || 'var(--color-900)'
}, rgb(32 33 35 / 0))`,
}}
/>
)}
</div>
<div
className='flex text-gray-300'
@ -255,7 +272,7 @@ const ChatFolder = ({
)}
</div>
</div>
<div className='ml-3 pl-1 border-l-2 border-gray-700 flex flex-col gap-1'>
<div className='group/folder ml-3 pl-1 border-l-2 border-gray-700 flex flex-col gap-1'>
{isExpanded &&
folderChats.map((chat) => (
<ChatHistory
@ -264,6 +281,7 @@ const ChatFolder = ({
key={`${chat.title}-${chat.index}`}
/>
))}
{isExpanded && <NewChat folder={folderId} />}
</div>
</div>
);

View file

@ -156,7 +156,7 @@ const ChatHistoryList = () => {
return (
<div
className={`flex-col flex-1 overflow-y-auto border-b border-white/20 ${
className={`flex-col flex-1 overflow-y-scroll -mr-2 border-b border-white/20 ${
isHover ? 'bg-gray-800/40' : ''
}`}
onDrop={handleDrop}

View file

@ -6,26 +6,39 @@ import PlusIcon from '@icon/PlusIcon';
import useAddChat from '@hooks/useAddChat';
const NewChat = () => {
const NewChat = ({ folder }: { folder?: string }) => {
const { t } = useTranslation();
const addChat = useAddChat();
const generating = useStore((state) => state.generating);
return (
<a
className={`max-md:hidden flex py-3 px-3 items-center gap-3 rounded-md hover:bg-gray-500/10 transition-colors duration-200 text-white text-sm md:mb-2 flex-shrink-0 md:border md:border-white/20 transition-opacity ${
className={`flex items-center max-md:hidden rounded-md hover:bg-gray-500/10 transition-all duration-200 text-white text-sm flex-shrink-0 ${
generating
? 'cursor-not-allowed opacity-40'
: 'cursor-pointer opacity-100'
} ${
folder
? 'justify-start'
: 'py-3 px-3 gap-3 md:mb-2 md:border md:border-white/20'
}`}
onClick={() => {
if (!generating) addChat();
if (!generating) addChat(folder);
}}
title={folder ? String(t('newChat')) : ''}
>
<PlusIcon />{' '}
<span className='hidden md:inline-flex text-white text-sm'>
{t('newChat')}
</span>
{folder ? (
<div className='max-h-0 group-hover/folder:max-h-10 group-hover/folder:py-3 px-3 overflow-hidden transition-all duration-200 delay-500 text-sm flex gap-3 items-center text-gray-100'>
<PlusIcon /> {t('newChat')}
</div>
) : (
<>
<PlusIcon />
<span className='hidden md:inline-flex text-white text-sm'>
{t('newChat')}
</span>
</>
)}
</a>
);
};

View file

@ -57,7 +57,7 @@ export const _defaultChatConfig: ConfigInterface = {
frequency_penalty: 0,
};
export const generateDefaultChat = (title?: string): ChatInterface => ({
export const generateDefaultChat = (title?: string, folder?: string): ChatInterface => ({
id: uuidv4(),
title: title ? title : 'New Chat',
messages:
@ -66,6 +66,7 @@ export const generateDefaultChat = (title?: string): ChatInterface => ({
: [],
config: { ...useStore.getState().defaultChatConfig },
titleSet: false,
folder
});
export const codeLanguageSubset = [

View file

@ -7,7 +7,7 @@ const useAddChat = () => {
const setChats = useStore((state) => state.setChats);
const setCurrentChatIndex = useStore((state) => state.setCurrentChatIndex);
const addChat = () => {
const addChat = (folder?:string) => {
const chats = useStore.getState().chats;
if (chats) {
const updatedChats: ChatInterface[] = JSON.parse(JSON.stringify(chats));
@ -19,7 +19,7 @@ const useAddChat = () => {
title = `New Chat ${titleIndex}`;
}
updatedChats.unshift(generateDefaultChat(title));
updatedChats.unshift(generateDefaultChat(title, folder));
setChats(updatedChats);
setCurrentChatIndex(0);
}