| | import { useMemo } from 'react'; |
| | import { useMediaQuery } from '@librechat/client'; |
| | import { useOutletContext } from 'react-router-dom'; |
| | import { getConfigDefaults, PermissionTypes, Permissions } from 'librechat-data-provider'; |
| | import type { ContextType } from '~/common'; |
| | import ModelSelector from './Menus/Endpoints/ModelSelector'; |
| | import { PresetsMenu, HeaderNewChat, OpenSidebar } from './Menus'; |
| | import { useGetStartupConfig } from '~/data-provider'; |
| | import ExportAndShareMenu from './ExportAndShareMenu'; |
| | import BookmarkMenu from './Menus/BookmarkMenu'; |
| | import { TemporaryChat } from './TemporaryChat'; |
| | import AddMultiConvo from './AddMultiConvo'; |
| | import { useHasAccess } from '~/hooks'; |
| | import { AnimatePresence, motion } from 'framer-motion'; |
| |
|
| | const defaultInterface = getConfigDefaults().interface; |
| |
|
| | export default function Header() { |
| | const { data: startupConfig } = useGetStartupConfig(); |
| | const { navVisible, setNavVisible } = useOutletContext<ContextType>(); |
| |
|
| | const interfaceConfig = useMemo( |
| | () => startupConfig?.interface ?? defaultInterface, |
| | [startupConfig], |
| | ); |
| |
|
| | const hasAccessToBookmarks = useHasAccess({ |
| | permissionType: PermissionTypes.BOOKMARKS, |
| | permission: Permissions.USE, |
| | }); |
| |
|
| | const hasAccessToMultiConvo = useHasAccess({ |
| | permissionType: PermissionTypes.MULTI_CONVO, |
| | permission: Permissions.USE, |
| | }); |
| |
|
| | const isSmallScreen = useMediaQuery('(max-width: 768px)'); |
| |
|
| | return ( |
| | <div className="sticky top-0 z-10 flex h-14 w-full items-center justify-between bg-white p-2 font-semibold text-text-primary dark:bg-gray-800"> |
| | <div className="hide-scrollbar flex w-full items-center justify-between gap-2 overflow-x-auto"> |
| | <div className="mx-1 flex items-center"> |
| | <AnimatePresence initial={false}> |
| | {!navVisible && ( |
| | <motion.div |
| | className={`flex items-center gap-2`} |
| | initial={{ width: 0, opacity: 0 }} |
| | animate={{ width: 'auto', opacity: 1 }} |
| | exit={{ width: 0, opacity: 0 }} |
| | transition={{ duration: 0.2 }} |
| | key="header-buttons" |
| | > |
| | <OpenSidebar setNavVisible={setNavVisible} className="max-md:hidden" /> |
| | <HeaderNewChat /> |
| | </motion.div> |
| | )} |
| | </AnimatePresence> |
| | |
| | <div className={navVisible ? 'flex items-center gap-2' : 'ml-2 flex items-center gap-2'}> |
| | <ModelSelector startupConfig={startupConfig} /> |
| | {interfaceConfig.presets === true && interfaceConfig.modelSelect && <PresetsMenu />} |
| | {hasAccessToBookmarks === true && <BookmarkMenu />} |
| | {hasAccessToMultiConvo === true && <AddMultiConvo />} |
| | {isSmallScreen && ( |
| | <> |
| | <ExportAndShareMenu |
| | isSharedButtonEnabled={startupConfig?.sharedLinksEnabled ?? false} |
| | /> |
| | <TemporaryChat /> |
| | </> |
| | )} |
| | </div> |
| | </div> |
| | {!isSmallScreen && ( |
| | <div className="flex items-center gap-2"> |
| | <ExportAndShareMenu |
| | isSharedButtonEnabled={startupConfig?.sharedLinksEnabled ?? false} |
| | /> |
| | <TemporaryChat /> |
| | </div> |
| | )} |
| | </div> |
| | {} |
| | <div /> |
| | </div> |
| | ); |
| | } |
| |
|