mirror of
https://github.com/NovaOSS/nova-betterchat.git
synced 2024-11-25 22:34:00 +01:00
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:
parent
bfe3f1adfa
commit
6d1ae9f526
|
@ -10,6 +10,7 @@ import {
|
||||||
} from '@type/chat';
|
} from '@type/chat';
|
||||||
|
|
||||||
import ChatHistory from './ChatHistory';
|
import ChatHistory from './ChatHistory';
|
||||||
|
import NewChat from './NewChat';
|
||||||
import EditIcon from '@icon/EditIcon';
|
import EditIcon from '@icon/EditIcon';
|
||||||
import DeleteIcon from '@icon/DeleteIcon';
|
import DeleteIcon from '@icon/DeleteIcon';
|
||||||
import CrossIcon from '@icon/CrossIcon';
|
import CrossIcon from '@icon/CrossIcon';
|
||||||
|
@ -35,6 +36,7 @@ const ChatFolder = ({
|
||||||
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const folderRef = useRef<HTMLDivElement>(null);
|
const folderRef = useRef<HTMLDivElement>(null);
|
||||||
|
const gradientRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [_folderName, _setFolderName] = useState<string>(folderName);
|
const [_folderName, _setFolderName] = useState<string>(folderName);
|
||||||
const [isEdit, setIsEdit] = useState<boolean>(false);
|
const [isEdit, setIsEdit] = useState<boolean>(false);
|
||||||
|
@ -153,16 +155,18 @@ const ChatFolder = ({
|
||||||
style={{ background: color || '' }}
|
style={{ background: color || '' }}
|
||||||
className={`${
|
className={`${
|
||||||
color ? '' : 'hover:bg-gray-850'
|
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}
|
onClick={toggleExpanded}
|
||||||
ref={folderRef}
|
ref={folderRef}
|
||||||
onMouseEnter={() => {
|
onMouseEnter={() => {
|
||||||
if (color && folderRef.current)
|
if (color && folderRef.current)
|
||||||
folderRef.current.style.background = `${color}dd`;
|
folderRef.current.style.background = `${color}dd`;
|
||||||
|
if (gradientRef.current) gradientRef.current.style.width = '0px';
|
||||||
}}
|
}}
|
||||||
onMouseLeave={() => {
|
onMouseLeave={() => {
|
||||||
if (color && folderRef.current)
|
if (color && folderRef.current)
|
||||||
folderRef.current.style.background = color;
|
folderRef.current.style.background = color;
|
||||||
|
if (gradientRef.current) gradientRef.current.style.width = '1rem';
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FolderIcon className='h-4 w-4' />
|
<FolderIcon className='h-4 w-4' />
|
||||||
|
@ -182,6 +186,19 @@ const ChatFolder = ({
|
||||||
) : (
|
) : (
|
||||||
_folderName
|
_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>
|
||||||
<div
|
<div
|
||||||
className='flex text-gray-300'
|
className='flex text-gray-300'
|
||||||
|
@ -255,7 +272,7 @@ const ChatFolder = ({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</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 &&
|
{isExpanded &&
|
||||||
folderChats.map((chat) => (
|
folderChats.map((chat) => (
|
||||||
<ChatHistory
|
<ChatHistory
|
||||||
|
@ -264,6 +281,7 @@ const ChatFolder = ({
|
||||||
key={`${chat.title}-${chat.index}`}
|
key={`${chat.title}-${chat.index}`}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
{isExpanded && <NewChat folder={folderId} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -156,7 +156,7 @@ const ChatHistoryList = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<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' : ''
|
isHover ? 'bg-gray-800/40' : ''
|
||||||
}`}
|
}`}
|
||||||
onDrop={handleDrop}
|
onDrop={handleDrop}
|
||||||
|
|
|
@ -6,26 +6,39 @@ import PlusIcon from '@icon/PlusIcon';
|
||||||
|
|
||||||
import useAddChat from '@hooks/useAddChat';
|
import useAddChat from '@hooks/useAddChat';
|
||||||
|
|
||||||
const NewChat = () => {
|
const NewChat = ({ folder }: { folder?: string }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const addChat = useAddChat();
|
const addChat = useAddChat();
|
||||||
const generating = useStore((state) => state.generating);
|
const generating = useStore((state) => state.generating);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<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
|
generating
|
||||||
? 'cursor-not-allowed opacity-40'
|
? 'cursor-not-allowed opacity-40'
|
||||||
: 'cursor-pointer opacity-100'
|
: 'cursor-pointer opacity-100'
|
||||||
|
} ${
|
||||||
|
folder
|
||||||
|
? 'justify-start'
|
||||||
|
: 'py-3 px-3 gap-3 md:mb-2 md:border md:border-white/20'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!generating) addChat();
|
if (!generating) addChat(folder);
|
||||||
}}
|
}}
|
||||||
|
title={folder ? String(t('newChat')) : ''}
|
||||||
>
|
>
|
||||||
<PlusIcon />{' '}
|
{folder ? (
|
||||||
<span className='hidden md:inline-flex text-white text-sm'>
|
<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'>
|
||||||
{t('newChat')}
|
<PlusIcon /> {t('newChat')}
|
||||||
</span>
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<PlusIcon />
|
||||||
|
<span className='hidden md:inline-flex text-white text-sm'>
|
||||||
|
{t('newChat')}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,7 +57,7 @@ export const _defaultChatConfig: ConfigInterface = {
|
||||||
frequency_penalty: 0,
|
frequency_penalty: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const generateDefaultChat = (title?: string): ChatInterface => ({
|
export const generateDefaultChat = (title?: string, folder?: string): ChatInterface => ({
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
title: title ? title : 'New Chat',
|
title: title ? title : 'New Chat',
|
||||||
messages:
|
messages:
|
||||||
|
@ -66,6 +66,7 @@ export const generateDefaultChat = (title?: string): ChatInterface => ({
|
||||||
: [],
|
: [],
|
||||||
config: { ...useStore.getState().defaultChatConfig },
|
config: { ...useStore.getState().defaultChatConfig },
|
||||||
titleSet: false,
|
titleSet: false,
|
||||||
|
folder
|
||||||
});
|
});
|
||||||
|
|
||||||
export const codeLanguageSubset = [
|
export const codeLanguageSubset = [
|
||||||
|
|
|
@ -7,7 +7,7 @@ const useAddChat = () => {
|
||||||
const setChats = useStore((state) => state.setChats);
|
const setChats = useStore((state) => state.setChats);
|
||||||
const setCurrentChatIndex = useStore((state) => state.setCurrentChatIndex);
|
const setCurrentChatIndex = useStore((state) => state.setCurrentChatIndex);
|
||||||
|
|
||||||
const addChat = () => {
|
const addChat = (folder?:string) => {
|
||||||
const chats = useStore.getState().chats;
|
const chats = useStore.getState().chats;
|
||||||
if (chats) {
|
if (chats) {
|
||||||
const updatedChats: ChatInterface[] = JSON.parse(JSON.stringify(chats));
|
const updatedChats: ChatInterface[] = JSON.parse(JSON.stringify(chats));
|
||||||
|
@ -19,7 +19,7 @@ const useAddChat = () => {
|
||||||
title = `New Chat ${titleIndex}`;
|
title = `New Chat ${titleIndex}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedChats.unshift(generateDefaultChat(title));
|
updatedChats.unshift(generateDefaultChat(title, folder));
|
||||||
setChats(updatedChats);
|
setChats(updatedChats);
|
||||||
setCurrentChatIndex(0);
|
setCurrentChatIndex(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue