2025-04-15 10:04:00 +02:00
|
|
|
import { useCallback, useEffect, useState, useMemo, memo, lazy, Suspense, useRef } from 'react';
|
2024-05-14 11:00:01 -04:00
|
|
|
import { useRecoilValue } from 'recoil';
|
2024-08-22 17:09:05 -04:00
|
|
|
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
🧭 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
2025-04-27 14:03:25 -04:00
|
|
|
import type { ConversationListResponse } from 'librechat-data-provider';
|
2025-04-15 10:04:00 +02:00
|
|
|
import type { InfiniteQueryObserverResult } from '@tanstack/react-query';
|
2023-12-08 04:40:23 +01:00
|
|
|
import {
|
2024-08-22 17:09:05 -04:00
|
|
|
useLocalize,
|
|
|
|
|
useHasAccess,
|
2023-12-08 04:40:23 +01:00
|
|
|
useMediaQuery,
|
♾️ style: Infinite Scroll Nav and Sort Convos by Date/Usage (#1708)
* Style: Infinite Scroll and Group convos by date
* Style: Infinite Scroll and Group convos by date- Redesign NavBar
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Clean code
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Including OpenRouter and Mistral icon
* refactor(Conversations): cleanup use of utility functions and typing
* refactor(Nav/NewChat): use localStorage `lastConversationSetup` to determine the endpoint to use, as well as icons -> JSX components, remove use of `endpointSelected`
* refactor: remove use of `isFirstToday`
* refactor(Nav): remove use of `endpointSelected`, consolidate scrolling logic to its own hook `useNavScrolling`, remove use of recoil `conversation`
* refactor: Add spinner to bottom of list, throttle fetching, move query hooks to client workspace
* chore: sort by `updatedAt` field
* refactor: optimize conversation infinite query, use optimistic updates, add conversation helpers for managing pagination, remove unnecessary operations
* feat: gen_title route for generating the title for the conversation
* style(Convo): change hover bg-color
* refactor: memoize groupedConversations and return as array of tuples, correctly update convos pre/post message stream, only call genTitle if conversation is new, make `addConversation` dynamically either add/update depending if convo exists in pages already, reorganize type definitions
* style: rename Header NewChat Button -> HeaderNewChat, add NewChatIcon, closely match main Nav New Chat button to ChatGPT
* style(NewChat): add hover bg color
* style: cleanup comments, match ChatGPT nav styling, redesign search bar, make part of new chat sticky header, move Nav under same parent as outlet/mobilenav, remove legacy code, search only if searchQuery is not empty
* feat: add tests for conversation helpers and ensure no duplicate conversations are ever grouped
* style: hover bg-color
* feat: alt-click on convo item to open conversation in new tab
* chore: send error message when `gen_title` fails
---------
Co-authored-by: Walber Cardoso <walbercardoso@gmail.com>
2024-02-03 20:25:35 -05:00
|
|
|
useAuthContext,
|
2023-12-08 04:40:23 +01:00
|
|
|
useLocalStorage,
|
♾️ style: Infinite Scroll Nav and Sort Convos by Date/Usage (#1708)
* Style: Infinite Scroll and Group convos by date
* Style: Infinite Scroll and Group convos by date- Redesign NavBar
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Clean code
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Including OpenRouter and Mistral icon
* refactor(Conversations): cleanup use of utility functions and typing
* refactor(Nav/NewChat): use localStorage `lastConversationSetup` to determine the endpoint to use, as well as icons -> JSX components, remove use of `endpointSelected`
* refactor: remove use of `isFirstToday`
* refactor(Nav): remove use of `endpointSelected`, consolidate scrolling logic to its own hook `useNavScrolling`, remove use of recoil `conversation`
* refactor: Add spinner to bottom of list, throttle fetching, move query hooks to client workspace
* chore: sort by `updatedAt` field
* refactor: optimize conversation infinite query, use optimistic updates, add conversation helpers for managing pagination, remove unnecessary operations
* feat: gen_title route for generating the title for the conversation
* style(Convo): change hover bg-color
* refactor: memoize groupedConversations and return as array of tuples, correctly update convos pre/post message stream, only call genTitle if conversation is new, make `addConversation` dynamically either add/update depending if convo exists in pages already, reorganize type definitions
* style: rename Header NewChat Button -> HeaderNewChat, add NewChatIcon, closely match main Nav New Chat button to ChatGPT
* style(NewChat): add hover bg color
* style: cleanup comments, match ChatGPT nav styling, redesign search bar, make part of new chat sticky header, move Nav under same parent as outlet/mobilenav, remove legacy code, search only if searchQuery is not empty
* feat: add tests for conversation helpers and ensure no duplicate conversations are ever grouped
* style: hover bg-color
* feat: alt-click on convo item to open conversation in new tab
* chore: send error message when `gen_title` fails
---------
Co-authored-by: Walber Cardoso <walbercardoso@gmail.com>
2024-02-03 20:25:35 -05:00
|
|
|
useNavScrolling,
|
2023-12-08 04:40:23 +01:00
|
|
|
} from '~/hooks';
|
2024-05-14 11:00:01 -04:00
|
|
|
import { useConversationsInfiniteQuery } from '~/data-provider';
|
♾️ style: Infinite Scroll Nav and Sort Convos by Date/Usage (#1708)
* Style: Infinite Scroll and Group convos by date
* Style: Infinite Scroll and Group convos by date- Redesign NavBar
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Clean code
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component
* Including OpenRouter and Mistral icon
* refactor(Conversations): cleanup use of utility functions and typing
* refactor(Nav/NewChat): use localStorage `lastConversationSetup` to determine the endpoint to use, as well as icons -> JSX components, remove use of `endpointSelected`
* refactor: remove use of `isFirstToday`
* refactor(Nav): remove use of `endpointSelected`, consolidate scrolling logic to its own hook `useNavScrolling`, remove use of recoil `conversation`
* refactor: Add spinner to bottom of list, throttle fetching, move query hooks to client workspace
* chore: sort by `updatedAt` field
* refactor: optimize conversation infinite query, use optimistic updates, add conversation helpers for managing pagination, remove unnecessary operations
* feat: gen_title route for generating the title for the conversation
* style(Convo): change hover bg-color
* refactor: memoize groupedConversations and return as array of tuples, correctly update convos pre/post message stream, only call genTitle if conversation is new, make `addConversation` dynamically either add/update depending if convo exists in pages already, reorganize type definitions
* style: rename Header NewChat Button -> HeaderNewChat, add NewChatIcon, closely match main Nav New Chat button to ChatGPT
* style(NewChat): add hover bg color
* style: cleanup comments, match ChatGPT nav styling, redesign search bar, make part of new chat sticky header, move Nav under same parent as outlet/mobilenav, remove legacy code, search only if searchQuery is not empty
* feat: add tests for conversation helpers and ensure no duplicate conversations are ever grouped
* style: hover bg-color
* feat: alt-click on convo item to open conversation in new tab
* chore: send error message when `gen_title` fails
---------
Co-authored-by: Walber Cardoso <walbercardoso@gmail.com>
2024-02-03 20:25:35 -05:00
|
|
|
import { Conversations } from '~/components/Conversations';
|
2025-04-15 10:04:00 +02:00
|
|
|
import SearchBar from './SearchBar';
|
WIP: Update UI to match Official Style; Vision and Assistants 👷🏽 (#1190)
* wip: initial client side code
* wip: initial api code
* refactor: export query keys from own module, export assistant hooks
* refactor(SelectDropDown): more customization via props
* feat: create Assistant and render real Assistants
* refactor: major refactor of UI components to allow multi-chat, working alongside CreationPanel
* refactor: move assistant routes to own directory
* fix(CreationHeader): state issue with assistant select
* refactor: style changes for form, fix setSiblingIdx from useChatHelpers to use latestMessageParentId, fix render issue with ChatView and change location
* feat: parseCompactConvo: begin refactor of slimmer JSON payloads between client/api
* refactor(endpoints): add assistant endpoint, also use EModelEndpoint as much as possible
* refactor(useGetConversationsQuery): use object to access query data easily
* fix(MultiMessage): react warning of bad state set, making use of effect during render (instead of useEffect)
* fix(useNewConvo): use correct atom key (index instead of convoId) for reset latestMessageFamily
* refactor: make routing navigation/conversation change simpler
* chore: add removeNullishValues for smaller payloads, remove unused fields, setup frontend pinging of assistant endpoint
* WIP: initial complete assistant run handling
* fix: CreationPanel form correctly setting internal state
* refactor(api/assistants/chat): revise functions to working run handling strategy
* refactor(UI): initial major refactor of ChatForm and options
* feat: textarea hook
* refactor: useAuthRedirect hook and change directory name
* feat: add ChatRoute (/c/), make optionsBar absolute and change on textarea height, add temp header
* feat: match new toggle Nav open button to ChatGPT's
* feat: add OpenAI custom classnames
* feat: useOriginNavigate
* feat: messages loading view
* fix: conversation navigation and effects
* refactor: make toggle change nav opacity
* WIP: new endpoint menu
* feat: NewEndpointsMenu complete
* fix: ensure set key dialog shows on endpoint change, and new conversation resets messages
* WIP: textarea styling fix, add temp footer, create basic file handling component
* feat: image file handling (UI)
* feat: PopOver and ModelSelect in Header, remove GenButtons
* feat: drop file handling
* refactor: bug fixes
use SSE at route level
add opts to useOriginNavigate
delay render of unfinishedMessage to avoid flickering
pass params (convoId) to chatHelpers to set messages query data based on param when the route is new (fixes can't continue convo on /new/)
style(MessagesView): matches height to official
fix(SSE): pass paramId and invalidate convos
style(Message): make bg uniform
* refactor(useSSE): setStorage within setConversation updates
* feat: conversationKeysAtom, allConversationsSelector, update convos query data on created message (if new), correctly handle convo deletion (individual)
* feat: add popover select dropdowns to allow options in header while allowing horizontal scroll for mobile
* style(pluginsSelect): styling changes
* refactor(NewEndpointsMenu): make UI components modular
* feat: Presets complete
* fix: preset editing, make by index
* fix: conversations not setting on inital navigation, fix getMessages() based on query param
* fix: changing preset no longer resets latestMessage
* feat: useOnClickOutside for OptionsPopover and fix bug that causes selection of preset when deleting
* fix: revert /chat/ switchToConvo, also use NewDeleteButton in Convo
* fix: Popover correctly closes on close Popover button using custom condition for useOnClickOutside
* style: new message and nav styling
* style: hover/sibling buttons and preset menu scrolling
* feat: new convo header button
* style(Textarea): minor style changes to textarea buttons
* feat: stop/continue generating and hide hoverbuttons when submitting
* feat: compact AI Provider schemas to make json payloads and db saves smaller
* style: styling changes for consistency on chat route
* fix: created usePresetIndexOptions to prevent bugs between /c/ and /chat/ routes when editing presets, removed redundant code from the new dialog
* chore: make /chat/ route default for now since we still lack full image support
2023-11-16 10:42:24 -05:00
|
|
|
import NewChat from './NewChat';
|
|
|
|
|
import { cn } from '~/utils';
|
2023-07-27 10:11:57 -04:00
|
|
|
import store from '~/store';
|
2023-05-19 20:21:34 +05:30
|
|
|
|
2025-04-15 10:04:00 +02:00
|
|
|
const BookmarkNav = lazy(() => import('./Bookmarks/BookmarkNav'));
|
|
|
|
|
const AccountSettings = lazy(() => import('./AccountSettings'));
|
|
|
|
|
|
|
|
|
|
const NAV_WIDTH_DESKTOP = '260px';
|
|
|
|
|
const NAV_WIDTH_MOBILE = '320px';
|
|
|
|
|
|
|
|
|
|
const NavMask = memo(
|
|
|
|
|
({ navVisible, toggleNavVisible }: { navVisible: boolean; toggleNavVisible: () => void }) => (
|
|
|
|
|
<div
|
|
|
|
|
id="mobile-nav-mask-toggle"
|
|
|
|
|
role="button"
|
|
|
|
|
tabIndex={0}
|
|
|
|
|
className={`nav-mask ${navVisible ? 'active' : ''}`}
|
|
|
|
|
onClick={toggleNavVisible}
|
|
|
|
|
onKeyDown={(e) => {
|
|
|
|
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
|
|
|
toggleNavVisible();
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
aria-label="Toggle navigation"
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const MemoNewChat = memo(NewChat);
|
|
|
|
|
|
|
|
|
|
const Nav = memo(
|
|
|
|
|
({
|
|
|
|
|
navVisible,
|
|
|
|
|
setNavVisible,
|
|
|
|
|
}: {
|
|
|
|
|
navVisible: boolean;
|
|
|
|
|
setNavVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
|
|
|
|
}) => {
|
|
|
|
|
const localize = useLocalize();
|
|
|
|
|
const { isAuthenticated } = useAuthContext();
|
|
|
|
|
|
|
|
|
|
const [navWidth, setNavWidth] = useState(NAV_WIDTH_DESKTOP);
|
|
|
|
|
const isSmallScreen = useMediaQuery('(max-width: 768px)');
|
|
|
|
|
const [newUser, setNewUser] = useLocalStorage('newUser', true);
|
|
|
|
|
const [showLoading, setShowLoading] = useState(false);
|
|
|
|
|
const [tags, setTags] = useState<string[]>([]);
|
|
|
|
|
|
|
|
|
|
const hasAccessToBookmarks = useHasAccess({
|
|
|
|
|
permissionType: PermissionTypes.BOOKMARKS,
|
|
|
|
|
permission: Permissions.USE,
|
|
|
|
|
});
|
|
|
|
|
|
2025-04-17 03:07:43 +02:00
|
|
|
const search = useRecoilValue(store.search);
|
|
|
|
|
|
|
|
|
|
const { data, fetchNextPage, isFetchingNextPage, isLoading, isFetching, refetch } =
|
|
|
|
|
useConversationsInfiniteQuery(
|
|
|
|
|
{
|
|
|
|
|
tags: tags.length === 0 ? undefined : tags,
|
|
|
|
|
search: search.debouncedQuery || undefined,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
enabled: isAuthenticated,
|
|
|
|
|
staleTime: 30000,
|
|
|
|
|
cacheTime: 300000,
|
|
|
|
|
},
|
|
|
|
|
);
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
const computedHasNextPage = useMemo(() => {
|
2025-04-17 03:07:43 +02:00
|
|
|
if (data?.pages && data.pages.length > 0) {
|
2025-04-15 10:04:00 +02:00
|
|
|
const lastPage: ConversationListResponse = data.pages[data.pages.length - 1];
|
|
|
|
|
return lastPage.nextCursor !== null;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2025-04-17 03:07:43 +02:00
|
|
|
}, [data?.pages]);
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
const outerContainerRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
const listRef = useRef<any>(null);
|
|
|
|
|
|
2025-04-17 03:07:43 +02:00
|
|
|
const { moveToTop } = useNavScrolling<ConversationListResponse>({
|
2025-04-15 10:04:00 +02:00
|
|
|
setShowLoading,
|
|
|
|
|
fetchNextPage: async (options?) => {
|
|
|
|
|
if (computedHasNextPage) {
|
2025-04-17 03:07:43 +02:00
|
|
|
return fetchNextPage(options);
|
2025-04-15 10:04:00 +02:00
|
|
|
}
|
|
|
|
|
return Promise.resolve(
|
2025-04-17 03:07:43 +02:00
|
|
|
{} as InfiniteQueryObserverResult<ConversationListResponse, unknown>,
|
2025-04-15 10:04:00 +02:00
|
|
|
);
|
|
|
|
|
},
|
2025-04-17 03:07:43 +02:00
|
|
|
isFetchingNext: isFetchingNextPage,
|
2024-03-11 09:18:10 -04:00
|
|
|
});
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
const conversations = useMemo(() => {
|
|
|
|
|
return data ? data.pages.flatMap((page) => page.conversations) : [];
|
2025-04-17 03:07:43 +02:00
|
|
|
}, [data]);
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
const toggleNavVisible = useCallback(() => {
|
|
|
|
|
setNavVisible((prev: boolean) => {
|
|
|
|
|
localStorage.setItem('navVisible', JSON.stringify(!prev));
|
|
|
|
|
return !prev;
|
|
|
|
|
});
|
|
|
|
|
if (newUser) {
|
|
|
|
|
setNewUser(false);
|
|
|
|
|
}
|
|
|
|
|
}, [newUser, setNavVisible, setNewUser]);
|
|
|
|
|
|
|
|
|
|
const itemToggleNav = useCallback(() => {
|
|
|
|
|
if (isSmallScreen) {
|
|
|
|
|
toggleNavVisible();
|
|
|
|
|
}
|
|
|
|
|
}, [isSmallScreen, toggleNavVisible]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (isSmallScreen) {
|
|
|
|
|
const savedNavVisible = localStorage.getItem('navVisible');
|
|
|
|
|
if (savedNavVisible === null) {
|
|
|
|
|
toggleNavVisible();
|
2024-09-13 08:59:09 -04:00
|
|
|
}
|
2025-04-15 10:04:00 +02:00
|
|
|
setNavWidth(NAV_WIDTH_MOBILE);
|
|
|
|
|
} else {
|
|
|
|
|
setNavWidth(NAV_WIDTH_DESKTOP);
|
|
|
|
|
}
|
|
|
|
|
}, [isSmallScreen, toggleNavVisible]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
refetch();
|
|
|
|
|
}, [tags, refetch]);
|
|
|
|
|
|
|
|
|
|
const loadMoreConversations = useCallback(() => {
|
|
|
|
|
if (isFetchingNextPage || !computedHasNextPage) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fetchNextPage();
|
|
|
|
|
}, [isFetchingNextPage, computedHasNextPage, fetchNextPage]);
|
|
|
|
|
|
|
|
|
|
const subHeaders = useMemo(
|
🧭 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
2025-04-27 14:03:25 -04:00
|
|
|
() => 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],
|
2025-04-15 10:04:00 +02:00
|
|
|
);
|
|
|
|
|
|
2025-04-17 03:07:43 +02:00
|
|
|
const [isSearchLoading, setIsSearchLoading] = useState(
|
|
|
|
|
!!search.query && (search.isTyping || isLoading || isFetching),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (search.isTyping) {
|
|
|
|
|
setIsSearchLoading(true);
|
|
|
|
|
} else if (!isLoading && !isFetching) {
|
|
|
|
|
setIsSearchLoading(false);
|
|
|
|
|
} else if (!!search.query && (isLoading || isFetching)) {
|
|
|
|
|
setIsSearchLoading(true);
|
|
|
|
|
}
|
|
|
|
|
}, [search.query, search.isTyping, isLoading, isFetching]);
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<div
|
|
|
|
|
data-testid="nav"
|
|
|
|
|
className={cn(
|
|
|
|
|
'nav active max-w-[320px] flex-shrink-0 overflow-x-hidden bg-surface-primary-alt',
|
|
|
|
|
'md:max-w-[260px]',
|
|
|
|
|
)}
|
|
|
|
|
style={{
|
|
|
|
|
width: navVisible ? navWidth : '0px',
|
|
|
|
|
visibility: navVisible ? 'visible' : 'hidden',
|
|
|
|
|
transition: 'width 0.2s, visibility 0.2s',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div className="h-full w-[320px] md:w-[260px]">
|
|
|
|
|
<div className="flex h-full flex-col">
|
🧭 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
2025-04-27 14:03:25 -04:00
|
|
|
<div className="flex h-full flex-col transition-opacity">
|
2025-04-15 10:04:00 +02:00
|
|
|
<div className="flex h-full flex-col">
|
|
|
|
|
<nav
|
|
|
|
|
id="chat-history-nav"
|
|
|
|
|
aria-label={localize('com_ui_chat_history')}
|
🧭 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
2025-04-27 14:03:25 -04:00
|
|
|
className="flex h-full flex-col px-2 pb-3.5 md:px-3"
|
🤲 feat(a11y): Initial a11y improvements, added linters, tests; fix: close sidebars in mobile view (#3536)
* chore: playwright setup update
* refactor: update ChatRoute component with accessible loading spinner with live region
* chore(Message): typing
* ci: first pass, a11y testing
* refactor: update lang attribute in index.html to "en-US"
* ci: jsx-a11y dev eslint plugin
* ci: jsx plugin
* fix: Exclude 'vite.config.ts' from TypeScript compilation for testing
* fix(a11y): Remove tabIndex from non-interactive element in MessagesView component
* fix(a11y):
- Visible, non-interactive elements with click handlers must have at least one keyboard listener.eslintjsx-a11y/click-events-have-key-events
- Avoid non-native interactive elements. If using native HTML is not possible, add an appropriate role and support for tabbing, mouse, keyboard, and touch inputs to an interactive content element.eslintjsx-a11y/no-static-element-interactions
chore: remove unused bookmarks panel
- fix some "Unexpected nullable boolean value in conditional" warnings
* fix(NewChat): a11y, nested button issue, add aria-label, remove implicit role
* fix(a11y):
- partially address #3515 with `main` landmark
other:
- eslint@typescript-eslint/strict-boolean-expressions
* chore(MenuButton): Use button element instead of div for accessibility
* chore: Update TitleButton to use button element for accessibility
* chore: Update TitleButton to use button element for accessibility
* refactor(ChatMenuItem): Improve focus accessibility and code readability
* chore(MenuButton): Update aria-label to dynamically include primaryText
* fix(a11y): SearchBar
- If a form control does not have a properly associated text label, the function or purpose of that form control may not be presented to screen reader users. Visible form labels also provide visible descriptions and larger clickable targets for form controls which placeholders do not.
* chore: remove duplicate SearchBar twcss
* fix(a11y):
- The edit and copy buttons that are visually hidden are exposed to Assistive technology and are announced to screen reader users.
* fix(a11y): visible focus outline
* fix(a11y): The button to select the LLM Model has the aria-haspopup and aria- expanded attributes which makes its role ambuguous and unclear. It functions like a combobox but doesn't fully support that interaction and also fucntions like a dialog but doesn't completely support that interaction either.
* fix(a11y): fix visible focus outline
* fix(a11y): Scroll to bottom button missing accessible name #3474
* fix(a11y): The page lacks any heading structure. There should be at least one H1 and other headings to help users understand the orgainzation of the page and the contents.
Note: h1 won't be correct here so made it h2
* fix(a11y): LLM controls aria-labels
* fix(a11y): There is no visible focus outline to the 'send message' button
* fix(a11y): fix visible focus outline for Fork button
* refactor(MessageRender): add focus ring to message cards, consolidate complex conditions, add logger for setting latest message, add tabindex for card
* fix: focus border color and fix set latest message card condition
* fix(a11y): Adequate contrast for MessageAudio buttton
* feat: Add GitHub Actions workflow for accessibility linting
* chore: Update GitHub Actions workflow for accessibility linting to include client/src/** path
* fix(Nav): navmask and accessibility
* fix: Update Nav component to handle potential undefined type in SearchContext
* fix(a11y): add focus visibility to attach files button #3475
* fix(a11y): discernible text for NewChat button
* fix(a11y): accessible landmark names, all page content in landmarks, ensures landmarks are unique #3514 #3515
* fix(Prompts): update isChatRoute prop to be required in List component
* fix(a11y): buttons must have discernible text
2024-08-04 20:39:52 -04:00
|
|
|
>
|
2025-04-15 10:04:00 +02:00
|
|
|
<div className="flex flex-1 flex-col" ref={outerContainerRef}>
|
|
|
|
|
<MemoNewChat
|
|
|
|
|
subHeaders={subHeaders}
|
🧭 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
2025-04-27 14:03:25 -04:00
|
|
|
toggleNav={toggleNavVisible}
|
|
|
|
|
headerButtons={headerButtons}
|
|
|
|
|
isSmallScreen={isSmallScreen}
|
2025-04-15 10:04:00 +02:00
|
|
|
/>
|
|
|
|
|
<Conversations
|
|
|
|
|
conversations={conversations}
|
|
|
|
|
moveToTop={moveToTop}
|
|
|
|
|
toggleNav={itemToggleNav}
|
|
|
|
|
containerRef={listRef}
|
|
|
|
|
loadMoreConversations={loadMoreConversations}
|
2025-04-17 03:07:43 +02:00
|
|
|
isLoading={isFetchingNextPage || showLoading || isLoading}
|
2025-04-15 10:04:00 +02:00
|
|
|
isSearchLoading={isSearchLoading}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<Suspense fallback={null}>
|
|
|
|
|
<AccountSettings />
|
|
|
|
|
</Suspense>
|
|
|
|
|
</nav>
|
|
|
|
|
</div>
|
2023-10-11 03:11:02 +02:00
|
|
|
</div>
|
2023-07-15 10:43:15 -04:00
|
|
|
</div>
|
2023-03-12 00:32:03 +08:00
|
|
|
</div>
|
2023-02-06 13:27:28 -05:00
|
|
|
</div>
|
2025-04-15 10:04:00 +02:00
|
|
|
{isSmallScreen && <NavMask navVisible={navVisible} toggleNavVisible={toggleNavVisible} />}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Nav.displayName = 'Nav';
|
|
|
|
|
|
|
|
|
|
export default Nav;
|