mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 18:00:15 +01:00
🧭 refactor: Modernize Nav/Header (#7094)
* refactor: streamline model preset handling in conversation setup * refactor: integrate navigation and location hooks in chat functions and event handlers, prevent cache from fetching on final event handling * fix: prevent adding code interpreter non-image output to file list on message attachment event, fix all unhandled edge cases when this is done (treating the file download as an image attachment, undefined fields, message tokenCount issues, use of `startsWith` on undefined "text") although it is now prevent altogether * chore: remove unused jailbreak prop from MinimalIcon component in EndpointIcon * feat: add new SVG icons (MobileSidebar, Sidebar, XAIcon), fix: xAI styling in dark vs. light modes, adjust styling of Landing icons * fix: open conversation in new tab on navigation with ctrl/meta key * refactor: update Nav & Header to use close/open sidebar buttons, as well as redesign "New Chat"/"Bookmarks" buttons to the top of the Nav, matching the latest design of ChatGPT for simplicity and to free up space * chore: remove unused isToggleHovering state and simplify opacity logic in Nav component * style: match mobile nav to mobile header
This commit is contained in:
parent
c0ebb434a6
commit
550c7cc68a
37 changed files with 361 additions and 298 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback, useEffect, useState, useMemo, memo, lazy, Suspense, useRef } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
||||
import type { TConversation, ConversationListResponse } from 'librechat-data-provider';
|
||||
import type { ConversationListResponse } from 'librechat-data-provider';
|
||||
import type { InfiniteQueryObserverResult } from '@tanstack/react-query';
|
||||
import {
|
||||
useLocalize,
|
||||
|
|
@ -13,7 +13,6 @@ import {
|
|||
} from '~/hooks';
|
||||
import { useConversationsInfiniteQuery } from '~/data-provider';
|
||||
import { Conversations } from '~/components/Conversations';
|
||||
import NavToggle from './NavToggle';
|
||||
import SearchBar from './SearchBar';
|
||||
import NewChat from './NewChat';
|
||||
import { cn } from '~/utils';
|
||||
|
|
@ -59,7 +58,6 @@ const Nav = memo(
|
|||
const [navWidth, setNavWidth] = useState(NAV_WIDTH_DESKTOP);
|
||||
const isSmallScreen = useMediaQuery('(max-width: 768px)');
|
||||
const [newUser, setNewUser] = useLocalStorage('newUser', true);
|
||||
const [isToggleHovering, setIsToggleHovering] = useState(false);
|
||||
const [showLoading, setShowLoading] = useState(false);
|
||||
const [tags, setTags] = useState<string[]>([]);
|
||||
|
||||
|
|
@ -152,20 +150,21 @@ const Nav = memo(
|
|||
}, [isFetchingNextPage, computedHasNextPage, fetchNextPage]);
|
||||
|
||||
const subHeaders = useMemo(
|
||||
() => (
|
||||
<>
|
||||
{search.enabled === true && <SearchBar isSmallScreen={isSmallScreen} />}
|
||||
{hasAccessToBookmarks && (
|
||||
<>
|
||||
<div className="mt-1.5" />
|
||||
<Suspense fallback={null}>
|
||||
<BookmarkNav tags={tags} setTags={setTags} isSmallScreen={isSmallScreen} />
|
||||
</Suspense>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
[search.enabled, hasAccessToBookmarks, isSmallScreen, tags, setTags],
|
||||
() => search.enabled === true && <SearchBar isSmallScreen={isSmallScreen} />,
|
||||
[search.enabled, isSmallScreen],
|
||||
);
|
||||
|
||||
const headerButtons = useMemo(
|
||||
() =>
|
||||
hasAccessToBookmarks && (
|
||||
<>
|
||||
<div className="mt-1.5" />
|
||||
<Suspense fallback={null}>
|
||||
<BookmarkNav tags={tags} setTags={setTags} isSmallScreen={isSmallScreen} />
|
||||
</Suspense>
|
||||
</>
|
||||
),
|
||||
[hasAccessToBookmarks, tags, isSmallScreen],
|
||||
);
|
||||
|
||||
const [isSearchLoading, setIsSearchLoading] = useState(
|
||||
|
|
@ -198,23 +197,19 @@ const Nav = memo(
|
|||
>
|
||||
<div className="h-full w-[320px] md:w-[260px]">
|
||||
<div className="flex h-full flex-col">
|
||||
<div
|
||||
className={cn(
|
||||
'flex h-full flex-col transition-opacity',
|
||||
isToggleHovering && !isSmallScreen ? 'opacity-50' : 'opacity-100',
|
||||
)}
|
||||
>
|
||||
<div className="flex h-full flex-col transition-opacity">
|
||||
<div className="flex h-full flex-col">
|
||||
<nav
|
||||
id="chat-history-nav"
|
||||
aria-label={localize('com_ui_chat_history')}
|
||||
className="flex h-full flex-col px-3 pb-3.5"
|
||||
className="flex h-full flex-col px-2 pb-3.5 md:px-3"
|
||||
>
|
||||
<div className="flex flex-1 flex-col" ref={outerContainerRef}>
|
||||
<MemoNewChat
|
||||
toggleNav={itemToggleNav}
|
||||
isSmallScreen={isSmallScreen}
|
||||
subHeaders={subHeaders}
|
||||
toggleNav={toggleNavVisible}
|
||||
headerButtons={headerButtons}
|
||||
isSmallScreen={isSmallScreen}
|
||||
/>
|
||||
<Conversations
|
||||
conversations={conversations}
|
||||
|
|
@ -235,15 +230,6 @@ const Nav = memo(
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NavToggle
|
||||
isHovering={isToggleHovering}
|
||||
setIsHovering={setIsToggleHovering}
|
||||
onToggle={toggleNavVisible}
|
||||
navVisible={navVisible}
|
||||
className="fixed left-0 top-1/2 z-40 hidden md:flex"
|
||||
/>
|
||||
|
||||
{isSmallScreen && <NavMask navVisible={navVisible} toggleNavVisible={toggleNavVisible} />}
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue