2025-04-15 10:04:00 +02:00
|
|
|
import { useMemo, memo, type FC, useCallback } from 'react';
|
|
|
|
|
import throttle from 'lodash/throttle';
|
♾️ 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 { parseISO, isToday } from 'date-fns';
|
📦 feat: Move Shared Components to `@librechat/client` (#8685)
* feat: init @librechat/client
* feat: Add common types and interfaces for accessibility, agents, artifacts, assistants, and tools
* feat: Add jotai as a peer dependency
* fix build client package
* feat: cleanup unused types from common/index.ts
- Remove 104 unused type exports from packages/client/src/common/index.ts
- Keep only 7 actually used exports (93% reduction)
- Add cleanup script with enhanced import pattern detection
- Support both named imports and namespace imports (* as t)
- Create automatic backups and comprehensive documentation
- Maintain type safety with build verification
- No breaking changes to existing code
Kept exports:
- TShowToast, Option, OptionWithIcon, DropdownValueSetter
- MentionOption, NotificationSeverity, MenuItemProps
Scripts: cleanup-common-types-safe.js, README-CLEANUP.md
* fix: cleanup
* fix: package; refactor: tsconfig
* feat: add back `recoil`
* fix: move dependencies to peerDependencies in client package
* feat: add @librechat/client as a dependency in package.json and package-lock.json
* feat: update client package configuration and dependencies
- Added new dependencies for Rollup plugins and updated existing ones in package.json and package-lock.json.
- Introduced a new Rollup configuration file for building the client package.
- Refactored build scripts to include a dedicated build command for the client.
- Updated TypeScript configuration for improved module resolution and type declaration output.
- Integrated a Toast component from the client package into the main App component.
* feat: enhance Rollup configuration for client package
- Updated terser plugin settings to preserve directives like 'use client'.
- Added custom warning handler to ignore "use client" directive warnings during the build process.
* chore: rename package/client build script command
* feat: update client package dependencies and Rollup configuration
- Added rollup-plugin-postcss to package.json and updated package-lock.json.
- Enhanced Rollup configuration to include postcss plugin for CSS handling.
- Updated index.ts to export all components from the components directory for better modularity.
* feat: add client package directory to update configuration
- Included the 'client' package directory in the update.js configuration to ensure it is recognized during updates.
* feat: export Toast component in client package
- Added export for the Toast component in index.ts to enhance modularity and accessibility of components.
* feat: /client transition to @librechat/client
* chore: fixed formatting issues
* fix: update peer dependencies in @librechat/client to prevent bundling them
* fix: correct useSprings implementation in SplitText component
* fix: circular dependencies in DataTable
* fix: add remaining peer dependencies and match actual versions previously used in `client/package.json`
* fix: correct frontend:ci script to include client package build
* chore: enhance unused package detection for @librechat/client and improve dependency extraction
* fix: add missing peer dependency for @radix-ui/react-collapsible
* chore: include "packages/client" in unused i18next keys detection
* test: update AgentFooter tests to use document.querySelector for spinner checks
test: mock window.matchMedia in setupTests.js for consistent test environment
* feat: add react-hook-form dependency and update FormInput component to use its types
* chore: linting
* refactor: remove unused defaultSelectedValues prop from MCPSelect and MultiSelect components
* chore: linting
* feat: update GitHub Actions workflow to publish @librechat/client
* chore: update GitHub Actions workflow to install and build data-provider and client dependencies
* chore: add missing @testing-library/react dependency to client package
* chore: update tsconfig.json to exclude additional test files
* chore: fix build issues, resolve latest LC changes
* chore: move MCP components outside of `~/components/ui`
* feat: implement dynamic theme system with environment variable support and Tailwind CSS integration
* chore: remove unnecessary logging of sttExternal and ttsExternal in Speech component
* chore: squashed cleanup commits
chore: move @tanstack/react-virtual to dependencies and remove recoil from package.json
chore: move dependencies to peerDependencies in package.json
feat: update package.json and rollup.config.js to include jotai and enhance bundling configuration
feat: update package.json and rollup.config.js to include jotai and enhance bundling configuration
refactor: reorganize exports in index.ts for improved clarity
refactor: remove unused types and interfaces from common files
refactor: update peer dependencies and improve component typings
- Removed duplicate peer dependencies from package.json and organized them.
- Updated rollup.config.js to disable TypeScript checking during the build process.
- Modified AnimatedTabs component to use React.ReactNode for label and content types, and added TypeScript workarounds for compatibility.
- Enhanced Label and Separator components to accept an optional className prop and improved prop spreading.
- Updated Slider component to include an optional className prop and refined prop handling for better type safety.
refactor: clean up client workflow and update package dependencies
refactor: update package dependencies and improve PostCSS and Rollup configurations
chore: bump version to 0.1.2 in package.json
chore: bump client version to 0.1.2 in package-lock.json
chore: bump client version to 0.1.3 and update dependencies
chore: bump client version to 0.1.4 and update @react-spring dependencies
chore: update package version to 0.1.5 and adjust peer dependencies
- Bump version in package.json from 0.1.4 to 0.1.5.
- Update peer dependency for @tanstack/react-query to allow version 5.0.0.
- Add @tanstack/react-table and @tanstack/react-virtual as dependencies.
- Update various dependencies to their latest compatible versions.
- Simplify postcss.config.js by removing unnecessary options.
- Clean up rollup.config.js by removing ignored PostCSS warnings.
- Update CheckboxButton component to cast icon as React JSX element.
- Adjust Combobox component's class names for better styling.
- Change DropdownPopup component to use React's namespace import.
- Modify InputOTP component to use 'any' type for OTPInputContext.
- Ensure displayLabel and value in ModelParameters are converted to strings.
- Update MultiSearch component's placeholder to ensure it's a string.
- Cast selectIcon in MultiSelect as React JSX element for consistency.
- Update OGDialogTemplate to cast selectText as React JSX element.
- Initialize animationRef in PixelCard with undefined for clarity.
- Add TypeScript ignore comments in Select and SelectDropDown components for Radix UI type conflicts.
- Ensure title in SelectDropDown is a string and adjust rendering of options.
- Update useLocalize hook to cast options as any for compatibility.
refactor: code structure; chore: translations cleanup
chore: remove unused imports and clean up code in NewChat component
refactor: enhance Menu component to support custom render functions for menu items
style: update itemClassName in ToolsDropdown for improved UI consistency
fix: merge conflicts
chore: update @radix-ui/react-accordion to version 1.2.11
* refactor: remove unnecessary TypeScript type assertions in AnimatedTabs, Label, Separator, and Slider components
* feat: enhance theme system with localStorage persistence and new theme atoms
* chore: bump version of @librechat/client to 0.1.7
* chore: fix ci/cd warnings/errors related to linting and unused localization keys
* chore: update dependencies for class-variance-authority, clsx, and match-sorter
* chore: bump @librechat/client to v0.1.8
* feat: add utility colors for theme customization and remove unused tailwindConfig
* v0.1.9
---------
Co-authored-by: Marco Beretta <81851188+berry-13@users.noreply.github.com>
2025-07-27 12:19:01 -04:00
|
|
|
import { Spinner, useMediaQuery } from '@librechat/client';
|
2025-04-15 10:04:00 +02:00
|
|
|
import { List, AutoSizer, CellMeasurer, CellMeasurerCache } from 'react-virtualized';
|
2023-07-27 14:49:47 -04:00
|
|
|
import { TConversation } from 'librechat-data-provider';
|
📦 feat: Move Shared Components to `@librechat/client` (#8685)
* feat: init @librechat/client
* feat: Add common types and interfaces for accessibility, agents, artifacts, assistants, and tools
* feat: Add jotai as a peer dependency
* fix build client package
* feat: cleanup unused types from common/index.ts
- Remove 104 unused type exports from packages/client/src/common/index.ts
- Keep only 7 actually used exports (93% reduction)
- Add cleanup script with enhanced import pattern detection
- Support both named imports and namespace imports (* as t)
- Create automatic backups and comprehensive documentation
- Maintain type safety with build verification
- No breaking changes to existing code
Kept exports:
- TShowToast, Option, OptionWithIcon, DropdownValueSetter
- MentionOption, NotificationSeverity, MenuItemProps
Scripts: cleanup-common-types-safe.js, README-CLEANUP.md
* fix: cleanup
* fix: package; refactor: tsconfig
* feat: add back `recoil`
* fix: move dependencies to peerDependencies in client package
* feat: add @librechat/client as a dependency in package.json and package-lock.json
* feat: update client package configuration and dependencies
- Added new dependencies for Rollup plugins and updated existing ones in package.json and package-lock.json.
- Introduced a new Rollup configuration file for building the client package.
- Refactored build scripts to include a dedicated build command for the client.
- Updated TypeScript configuration for improved module resolution and type declaration output.
- Integrated a Toast component from the client package into the main App component.
* feat: enhance Rollup configuration for client package
- Updated terser plugin settings to preserve directives like 'use client'.
- Added custom warning handler to ignore "use client" directive warnings during the build process.
* chore: rename package/client build script command
* feat: update client package dependencies and Rollup configuration
- Added rollup-plugin-postcss to package.json and updated package-lock.json.
- Enhanced Rollup configuration to include postcss plugin for CSS handling.
- Updated index.ts to export all components from the components directory for better modularity.
* feat: add client package directory to update configuration
- Included the 'client' package directory in the update.js configuration to ensure it is recognized during updates.
* feat: export Toast component in client package
- Added export for the Toast component in index.ts to enhance modularity and accessibility of components.
* feat: /client transition to @librechat/client
* chore: fixed formatting issues
* fix: update peer dependencies in @librechat/client to prevent bundling them
* fix: correct useSprings implementation in SplitText component
* fix: circular dependencies in DataTable
* fix: add remaining peer dependencies and match actual versions previously used in `client/package.json`
* fix: correct frontend:ci script to include client package build
* chore: enhance unused package detection for @librechat/client and improve dependency extraction
* fix: add missing peer dependency for @radix-ui/react-collapsible
* chore: include "packages/client" in unused i18next keys detection
* test: update AgentFooter tests to use document.querySelector for spinner checks
test: mock window.matchMedia in setupTests.js for consistent test environment
* feat: add react-hook-form dependency and update FormInput component to use its types
* chore: linting
* refactor: remove unused defaultSelectedValues prop from MCPSelect and MultiSelect components
* chore: linting
* feat: update GitHub Actions workflow to publish @librechat/client
* chore: update GitHub Actions workflow to install and build data-provider and client dependencies
* chore: add missing @testing-library/react dependency to client package
* chore: update tsconfig.json to exclude additional test files
* chore: fix build issues, resolve latest LC changes
* chore: move MCP components outside of `~/components/ui`
* feat: implement dynamic theme system with environment variable support and Tailwind CSS integration
* chore: remove unnecessary logging of sttExternal and ttsExternal in Speech component
* chore: squashed cleanup commits
chore: move @tanstack/react-virtual to dependencies and remove recoil from package.json
chore: move dependencies to peerDependencies in package.json
feat: update package.json and rollup.config.js to include jotai and enhance bundling configuration
feat: update package.json and rollup.config.js to include jotai and enhance bundling configuration
refactor: reorganize exports in index.ts for improved clarity
refactor: remove unused types and interfaces from common files
refactor: update peer dependencies and improve component typings
- Removed duplicate peer dependencies from package.json and organized them.
- Updated rollup.config.js to disable TypeScript checking during the build process.
- Modified AnimatedTabs component to use React.ReactNode for label and content types, and added TypeScript workarounds for compatibility.
- Enhanced Label and Separator components to accept an optional className prop and improved prop spreading.
- Updated Slider component to include an optional className prop and refined prop handling for better type safety.
refactor: clean up client workflow and update package dependencies
refactor: update package dependencies and improve PostCSS and Rollup configurations
chore: bump version to 0.1.2 in package.json
chore: bump client version to 0.1.2 in package-lock.json
chore: bump client version to 0.1.3 and update dependencies
chore: bump client version to 0.1.4 and update @react-spring dependencies
chore: update package version to 0.1.5 and adjust peer dependencies
- Bump version in package.json from 0.1.4 to 0.1.5.
- Update peer dependency for @tanstack/react-query to allow version 5.0.0.
- Add @tanstack/react-table and @tanstack/react-virtual as dependencies.
- Update various dependencies to their latest compatible versions.
- Simplify postcss.config.js by removing unnecessary options.
- Clean up rollup.config.js by removing ignored PostCSS warnings.
- Update CheckboxButton component to cast icon as React JSX element.
- Adjust Combobox component's class names for better styling.
- Change DropdownPopup component to use React's namespace import.
- Modify InputOTP component to use 'any' type for OTPInputContext.
- Ensure displayLabel and value in ModelParameters are converted to strings.
- Update MultiSearch component's placeholder to ensure it's a string.
- Cast selectIcon in MultiSelect as React JSX element for consistency.
- Update OGDialogTemplate to cast selectText as React JSX element.
- Initialize animationRef in PixelCard with undefined for clarity.
- Add TypeScript ignore comments in Select and SelectDropDown components for Radix UI type conflicts.
- Ensure title in SelectDropDown is a string and adjust rendering of options.
- Update useLocalize hook to cast options as any for compatibility.
refactor: code structure; chore: translations cleanup
chore: remove unused imports and clean up code in NewChat component
refactor: enhance Menu component to support custom render functions for menu items
style: update itemClassName in ToolsDropdown for improved UI consistency
fix: merge conflicts
chore: update @radix-ui/react-accordion to version 1.2.11
* refactor: remove unnecessary TypeScript type assertions in AnimatedTabs, Label, Separator, and Slider components
* feat: enhance theme system with localStorage persistence and new theme atoms
* chore: bump version of @librechat/client to 0.1.7
* chore: fix ci/cd warnings/errors related to linting and unused localization keys
* chore: update dependencies for class-variance-authority, clsx, and match-sorter
* chore: bump @librechat/client to v0.1.8
* feat: add utility colors for theme customization and remove unused tailwindConfig
* v0.1.9
---------
Co-authored-by: Marco Beretta <81851188+berry-13@users.noreply.github.com>
2025-07-27 12:19:01 -04:00
|
|
|
import { useLocalize, TranslationKeys } from '~/hooks';
|
♾️ 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 { groupConversationsByDate } from '~/utils';
|
|
|
|
|
import Convo from './Convo';
|
2023-02-06 13:27:28 -05:00
|
|
|
|
2025-04-15 10:04:00 +02:00
|
|
|
interface ConversationsProps {
|
2024-08-16 13:50:47 -04:00
|
|
|
conversations: Array<TConversation | null>;
|
2023-07-27 10:11:57 -04:00
|
|
|
moveToTop: () => void;
|
2023-11-17 08:00:42 -05:00
|
|
|
toggleNav: () => void;
|
2025-04-15 10:04:00 +02:00
|
|
|
containerRef: React.RefObject<HTMLDivElement | List>;
|
|
|
|
|
loadMoreConversations: () => void;
|
2025-04-17 03:07:43 +02:00
|
|
|
isLoading: boolean;
|
2025-04-15 10:04:00 +02:00
|
|
|
isSearchLoading: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-17 03:07:43 +02:00
|
|
|
const LoadingSpinner = memo(() => {
|
|
|
|
|
const localize = useLocalize();
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="mx-auto mt-2 flex items-center justify-center gap-2">
|
2025-05-16 17:50:18 +02:00
|
|
|
<Spinner className="text-text-primary" />
|
2025-04-17 03:07:43 +02:00
|
|
|
<span className="animate-pulse text-text-primary">{localize('com_ui_loading')}</span>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
});
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
const DateLabel: FC<{ groupName: string }> = memo(({ groupName }) => {
|
2024-05-14 11:00:01 -04:00
|
|
|
const localize = useLocalize();
|
2025-04-15 10:04:00 +02:00
|
|
|
return (
|
|
|
|
|
<div className="mt-2 pl-2 pt-1 text-text-secondary" style={{ fontSize: '0.7rem' }}>
|
|
|
|
|
{localize(groupName as TranslationKeys) || groupName}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
DateLabel.displayName = 'DateLabel';
|
|
|
|
|
|
|
|
|
|
type FlattenedItem =
|
|
|
|
|
| { type: 'header'; groupName: string }
|
2025-04-17 03:07:43 +02:00
|
|
|
| { type: 'convo'; convo: TConversation }
|
|
|
|
|
| { type: 'loading' };
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
const MemoizedConvo = memo(
|
|
|
|
|
({
|
|
|
|
|
conversation,
|
|
|
|
|
retainView,
|
|
|
|
|
toggleNav,
|
|
|
|
|
isLatestConvo,
|
|
|
|
|
}: {
|
|
|
|
|
conversation: TConversation;
|
|
|
|
|
retainView: () => void;
|
|
|
|
|
toggleNav: () => void;
|
|
|
|
|
isLatestConvo: boolean;
|
|
|
|
|
}) => {
|
|
|
|
|
return (
|
|
|
|
|
<Convo
|
|
|
|
|
conversation={conversation}
|
|
|
|
|
retainView={retainView}
|
|
|
|
|
toggleNav={toggleNav}
|
|
|
|
|
isLatestConvo={isLatestConvo}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
(prevProps, nextProps) => {
|
|
|
|
|
return (
|
|
|
|
|
prevProps.conversation.conversationId === nextProps.conversation.conversationId &&
|
|
|
|
|
prevProps.conversation.title === nextProps.conversation.title &&
|
|
|
|
|
prevProps.isLatestConvo === nextProps.isLatestConvo &&
|
|
|
|
|
prevProps.conversation.endpoint === nextProps.conversation.endpoint
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const Conversations: FC<ConversationsProps> = ({
|
|
|
|
|
conversations: rawConversations,
|
|
|
|
|
moveToTop,
|
|
|
|
|
toggleNav,
|
|
|
|
|
containerRef,
|
|
|
|
|
loadMoreConversations,
|
2025-04-17 03:07:43 +02:00
|
|
|
isLoading,
|
2025-04-15 10:04:00 +02:00
|
|
|
isSearchLoading,
|
|
|
|
|
}) => {
|
|
|
|
|
const isSmallScreen = useMediaQuery('(max-width: 768px)');
|
|
|
|
|
const convoHeight = isSmallScreen ? 44 : 34;
|
|
|
|
|
|
|
|
|
|
const filteredConversations = useMemo(
|
|
|
|
|
() => rawConversations.filter(Boolean) as TConversation[],
|
|
|
|
|
[rawConversations],
|
|
|
|
|
);
|
|
|
|
|
|
♾️ 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
|
|
|
const groupedConversations = useMemo(
|
2025-04-15 10:04:00 +02:00
|
|
|
() => groupConversationsByDate(filteredConversations),
|
|
|
|
|
[filteredConversations],
|
♾️ 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
|
|
|
);
|
2025-04-15 10:04:00 +02:00
|
|
|
|
2024-03-21 22:42:25 -04:00
|
|
|
const firstTodayConvoId = useMemo(
|
2024-05-14 11:00:01 -04:00
|
|
|
() =>
|
2025-04-15 10:04:00 +02:00
|
|
|
filteredConversations.find((convo) => convo.updatedAt && isToday(parseISO(convo.updatedAt)))
|
|
|
|
|
?.conversationId ?? undefined,
|
|
|
|
|
[filteredConversations],
|
2024-03-21 22:42:25 -04:00
|
|
|
);
|
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
|
|
|
|
2025-04-15 10:04:00 +02:00
|
|
|
const flattenedItems = useMemo(() => {
|
|
|
|
|
const items: FlattenedItem[] = [];
|
|
|
|
|
groupedConversations.forEach(([groupName, convos]) => {
|
|
|
|
|
items.push({ type: 'header', groupName });
|
|
|
|
|
items.push(...convos.map((convo) => ({ type: 'convo' as const, convo })));
|
|
|
|
|
});
|
2025-04-17 03:07:43 +02:00
|
|
|
|
|
|
|
|
if (isLoading) {
|
|
|
|
|
items.push({ type: 'loading' } as any);
|
|
|
|
|
}
|
2025-04-15 10:04:00 +02:00
|
|
|
return items;
|
2025-04-17 03:07:43 +02:00
|
|
|
}, [groupedConversations, isLoading]);
|
2025-04-15 10:04:00 +02:00
|
|
|
|
|
|
|
|
const cache = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
new CellMeasurerCache({
|
|
|
|
|
fixedWidth: true,
|
|
|
|
|
defaultHeight: convoHeight,
|
|
|
|
|
keyMapper: (index) => {
|
|
|
|
|
const item = flattenedItems[index];
|
2025-04-17 03:07:43 +02:00
|
|
|
if (item.type === 'header') {
|
|
|
|
|
return `header-${index}`;
|
|
|
|
|
}
|
|
|
|
|
if (item.type === 'convo') {
|
|
|
|
|
return `convo-${item.convo.conversationId}`;
|
|
|
|
|
}
|
|
|
|
|
if (item.type === 'loading') {
|
|
|
|
|
return `loading-${index}`;
|
|
|
|
|
}
|
|
|
|
|
return `unknown-${index}`;
|
2025-04-15 10:04:00 +02:00
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
[flattenedItems, convoHeight],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const rowRenderer = useCallback(
|
|
|
|
|
({ index, key, parent, style }) => {
|
|
|
|
|
const item = flattenedItems[index];
|
2025-04-17 03:07:43 +02:00
|
|
|
if (item.type === 'loading') {
|
|
|
|
|
return (
|
|
|
|
|
<CellMeasurer cache={cache} columnIndex={0} key={key} parent={parent} rowIndex={index}>
|
|
|
|
|
{({ registerChild }) => (
|
|
|
|
|
<div ref={registerChild} style={style}>
|
|
|
|
|
<LoadingSpinner />
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</CellMeasurer>
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-04-15 10:04:00 +02:00
|
|
|
return (
|
|
|
|
|
<CellMeasurer cache={cache} columnIndex={0} key={key} parent={parent} rowIndex={index}>
|
|
|
|
|
{({ registerChild }) => (
|
|
|
|
|
<div ref={registerChild} style={style}>
|
|
|
|
|
{item.type === 'header' ? (
|
|
|
|
|
<DateLabel groupName={item.groupName} />
|
2025-04-17 03:07:43 +02:00
|
|
|
) : item.type === 'convo' ? (
|
2025-04-15 10:04:00 +02:00
|
|
|
<MemoizedConvo
|
|
|
|
|
conversation={item.convo}
|
♾️ 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
|
|
|
retainView={moveToTop}
|
|
|
|
|
toggleNav={toggleNav}
|
2025-04-15 10:04:00 +02:00
|
|
|
isLatestConvo={item.convo.conversationId === firstTodayConvoId}
|
♾️ 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
|
|
|
/>
|
2025-04-17 03:07:43 +02:00
|
|
|
) : null}
|
♾️ 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
|
|
|
</div>
|
2025-04-15 10:04:00 +02:00
|
|
|
)}
|
|
|
|
|
</CellMeasurer>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
[cache, flattenedItems, firstTodayConvoId, moveToTop, toggleNav],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const getRowHeight = useCallback(
|
|
|
|
|
({ index }: { index: number }) => cache.getHeight(index, 0),
|
|
|
|
|
[cache],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const throttledLoadMore = useMemo(
|
|
|
|
|
() => throttle(loadMoreConversations, 300),
|
|
|
|
|
[loadMoreConversations],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const handleRowsRendered = useCallback(
|
|
|
|
|
({ stopIndex }: { stopIndex: number }) => {
|
2025-04-17 03:07:43 +02:00
|
|
|
if (stopIndex >= flattenedItems.length - 8) {
|
2025-04-15 10:04:00 +02:00
|
|
|
throttledLoadMore();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[flattenedItems.length, throttledLoadMore],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="relative flex h-full flex-col pb-2 text-sm text-text-primary">
|
|
|
|
|
{isSearchLoading ? (
|
|
|
|
|
<div className="flex flex-1 items-center justify-center">
|
|
|
|
|
<Spinner className="text-text-primary" />
|
|
|
|
|
<span className="ml-2 text-text-primary">Loading...</span>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<AutoSizer>
|
|
|
|
|
{({ width, height }) => (
|
|
|
|
|
<List
|
|
|
|
|
ref={containerRef as React.RefObject<List>}
|
|
|
|
|
width={width}
|
|
|
|
|
height={height}
|
|
|
|
|
deferredMeasurementCache={cache}
|
|
|
|
|
rowCount={flattenedItems.length}
|
|
|
|
|
rowHeight={getRowHeight}
|
|
|
|
|
rowRenderer={rowRenderer}
|
|
|
|
|
overscanRowCount={10}
|
|
|
|
|
className="outline-none"
|
|
|
|
|
style={{ outline: 'none' }}
|
|
|
|
|
role="list"
|
|
|
|
|
aria-label="Conversations"
|
|
|
|
|
onRowsRendered={handleRowsRendered}
|
2025-04-27 15:13:19 -04:00
|
|
|
tabIndex={-1}
|
2025-04-15 10:04:00 +02:00
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</AutoSizer>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
♾️ 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
|
|
|
</div>
|
2023-02-06 13:27:28 -05:00
|
|
|
);
|
2024-03-19 13:35:10 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default memo(Conversations);
|