mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-25 20:04:09 +01:00
refactor: Enhance navigation and chat components with new sidebar and button functionalities that free up space in the nav
This commit is contained in:
parent
cd4a3bd061
commit
84a1a16c3a
12 changed files with 205 additions and 211 deletions
|
|
@ -1,88 +1,27 @@
|
|||
import React, { useMemo, useCallback } from 'react';
|
||||
import { Search } from 'lucide-react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { QueryKeys, Constants } from 'librechat-data-provider';
|
||||
import type { TConversation, TMessage } from 'librechat-data-provider';
|
||||
import { createChatSearchParams, getEndpointField, getIconEndpoint, getIconKey } from '~/utils';
|
||||
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
||||
import { useGetEndpointsQuery } from '~/data-provider';
|
||||
import type { TMessage } from 'librechat-data-provider';
|
||||
import { NewChatIcon, MobileSidebar, Sidebar } from '~/components/svg';
|
||||
import { TooltipAnchor, Button } from '~/components/ui';
|
||||
import { useLocalize, useNewConvo } from '~/hooks';
|
||||
import { icons } from '~/hooks/Endpoint/Icons';
|
||||
import { NewChatIcon } from '~/components/svg';
|
||||
import { cn } from '~/utils';
|
||||
import { createChatSearchParams } from '~/utils';
|
||||
import store from '~/store';
|
||||
|
||||
const NewChatButtonIcon = React.memo(({ conversation }: { conversation: TConversation | null }) => {
|
||||
const { data: endpointsConfig } = useGetEndpointsQuery();
|
||||
const search = useRecoilValue(store.search);
|
||||
const searchQuery = search.debouncedQuery;
|
||||
|
||||
const computedIcon = useMemo(() => {
|
||||
if (searchQuery) {
|
||||
return null;
|
||||
}
|
||||
let { endpoint = '' } = conversation ?? {};
|
||||
const iconURL = conversation?.iconURL ?? '';
|
||||
endpoint = getIconEndpoint({ endpointsConfig, iconURL, endpoint });
|
||||
const endpointType = getEndpointField(endpointsConfig, endpoint, 'type');
|
||||
const endpointIconURL = getEndpointField(endpointsConfig, endpoint, 'iconURL');
|
||||
const iconKey = getIconKey({ endpoint, endpointsConfig, endpointType, endpointIconURL });
|
||||
const Icon = icons[iconKey];
|
||||
return { iconURL, endpoint, endpointType, endpointIconURL, Icon };
|
||||
}, [searchQuery, conversation, endpointsConfig]);
|
||||
|
||||
if (searchQuery) {
|
||||
return (
|
||||
<div className="shadow-stroke relative flex h-7 w-7 items-center justify-center rounded-full bg-white text-black dark:bg-white">
|
||||
<Search className="h-5 w-5" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!computedIcon) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { iconURL, endpoint, endpointIconURL, Icon } = computedIcon;
|
||||
|
||||
return (
|
||||
<div className="h-7 w-7 flex-shrink-0">
|
||||
{iconURL && iconURL.includes('http') ? (
|
||||
<ConvoIconURL
|
||||
iconURL={iconURL}
|
||||
modelLabel={conversation?.chatGptLabel ?? conversation?.modelLabel ?? ''}
|
||||
endpointIconURL={iconURL}
|
||||
context="nav"
|
||||
/>
|
||||
) : (
|
||||
<div className="shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white text-black dark:bg-surface-primary-alt dark:text-white dark:after:shadow-none">
|
||||
{endpoint && Icon && (
|
||||
<Icon
|
||||
size={41}
|
||||
context="nav"
|
||||
className="h-2/3 w-2/3"
|
||||
endpoint={endpoint}
|
||||
iconURL={endpointIconURL}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default function NewChat({
|
||||
index = 0,
|
||||
toggleNav,
|
||||
subHeaders,
|
||||
isSmallScreen,
|
||||
headerButtons,
|
||||
}: {
|
||||
index?: number;
|
||||
toggleNav: () => void;
|
||||
isSmallScreen?: boolean;
|
||||
subHeaders?: React.ReactNode;
|
||||
isSmallScreen: boolean;
|
||||
headerButtons?: React.ReactNode;
|
||||
}) {
|
||||
const queryClient = useQueryClient();
|
||||
/** Note: this component needs an explicit index passed if using more than one */
|
||||
|
|
@ -102,33 +41,50 @@ export default function NewChat({
|
|||
|
||||
newConvo();
|
||||
navigate(newRoute);
|
||||
toggleNav();
|
||||
}, [queryClient, conversation, newConvo, navigate, toggleNav, defaultPreset]);
|
||||
if (isSmallScreen) {
|
||||
toggleNav();
|
||||
}
|
||||
}, [queryClient, conversation, newConvo, navigate, toggleNav, defaultPreset, isSmallScreen]);
|
||||
|
||||
return (
|
||||
<div className="sticky left-0 right-0 top-0 z-50 bg-surface-primary-alt pt-3.5">
|
||||
<div className="pb-0.5 last:pb-0" style={{ transform: 'none' }}>
|
||||
<button
|
||||
data-testid="nav-new-chat-button"
|
||||
onClick={clickHandler}
|
||||
className={cn(
|
||||
'group flex h-10 w-full items-center gap-2 rounded-lg px-2 font-medium transition-colors duration-200 hover:bg-surface-hover',
|
||||
isSmallScreen ? 'h-14' : '',
|
||||
)}
|
||||
aria-label={localize('com_ui_new_chat')}
|
||||
>
|
||||
<NewChatButtonIcon conversation={conversation} />
|
||||
<div className="grow overflow-hidden text-ellipsis whitespace-nowrap text-sm text-text-primary">
|
||||
{localize('com_ui_new_chat')}
|
||||
</div>
|
||||
<div className="flex gap-3">
|
||||
<span className="flex items-center" data-state="closed">
|
||||
<NewChatIcon className="size-5" />
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
<>
|
||||
<div className="h-header-height xs:pe-3 flex items-center justify-between py-2">
|
||||
<TooltipAnchor
|
||||
description={localize('com_nav_close_sidebar')}
|
||||
render={
|
||||
<Button
|
||||
size="icon"
|
||||
variant="outline"
|
||||
data-testid="close-sidebar-button"
|
||||
aria-label={localize('com_nav_close_sidebar')}
|
||||
className="rounded-xl border-none bg-transparent p-2 hover:bg-surface-hover"
|
||||
onClick={toggleNav}
|
||||
>
|
||||
<Sidebar className="max-md:hidden" />
|
||||
<MobileSidebar className="md:hidden" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<div className="flex">
|
||||
{headerButtons}
|
||||
<TooltipAnchor
|
||||
description={localize('com_ui_new_chat')}
|
||||
render={
|
||||
<Button
|
||||
size="icon"
|
||||
variant="outline"
|
||||
data-testid="nav-new-chat-button"
|
||||
aria-label={localize('com_ui_new_chat')}
|
||||
className="rounded-xl border-none bg-transparent p-2 hover:bg-surface-hover"
|
||||
onClick={clickHandler}
|
||||
>
|
||||
<NewChatIcon />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{subHeaders != null ? subHeaders : null}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue