mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-21 21:50:49 +02:00
fix: Add useBackToNewChat
Hook for Back Navigation Handling
- Introduced a new hook `useBackToNewChat` to manage state when navigating back to the `/c/new` route. - The hook listens for browser back/forward navigation events and resets the conversation state appropriately. - Integrated the hook into `ChatRoute.tsx` to ensure proper functionality during navigation. - Added documentation detailing the problem, solution, and implementation of the new hook.
This commit is contained in:
parent
15d7a3d221
commit
6900fa73c6
4 changed files with 92 additions and 1 deletions
|
@ -3,6 +3,7 @@ export { default as useGetSender } from './useGetSender';
|
||||||
export { default as useDefaultConvo } from './useDefaultConvo';
|
export { default as useDefaultConvo } from './useDefaultConvo';
|
||||||
export { default as useSearchEnabled } from './useSearchEnabled';
|
export { default as useSearchEnabled } from './useSearchEnabled';
|
||||||
export { default as useGenerateConvo } from './useGenerateConvo';
|
export { default as useGenerateConvo } from './useGenerateConvo';
|
||||||
|
export { default as useBackToNewChat } from './useBackToNewChat';
|
||||||
export { default as useDebouncedInput } from './useDebouncedInput';
|
export { default as useDebouncedInput } from './useDebouncedInput';
|
||||||
export { default as useBookmarkSuccess } from './useBookmarkSuccess';
|
export { default as useBookmarkSuccess } from './useBookmarkSuccess';
|
||||||
export { default as useNavigateToConvo } from './useNavigateToConvo';
|
export { default as useNavigateToConvo } from './useNavigateToConvo';
|
||||||
|
|
40
client/src/hooks/Conversations/useBackToNewChat.ts
Normal file
40
client/src/hooks/Conversations/useBackToNewChat.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { QueryKeys, Constants } from 'librechat-data-provider';
|
||||||
|
import type { TMessage } from 'librechat-data-provider';
|
||||||
|
import { useNewConvo } from '~/hooks';
|
||||||
|
import { logger } from '~/utils';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to detect and handle back navigation to /c/new
|
||||||
|
* This solves the issue where navigating back to new chat doesn't properly reset state
|
||||||
|
*/
|
||||||
|
export default function useBackToNewChat(index = 0) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const { newConversation } = useNewConvo(index);
|
||||||
|
const { conversation } = store.useCreateConversationAtom(index);
|
||||||
|
|
||||||
|
// Listen for popstate events (back/forward button navigation)
|
||||||
|
useEffect(() => {
|
||||||
|
const handlePopState = () => {
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
if (currentPath === '/c/new' && conversation?.conversationId !== Constants.NEW_CONVO) {
|
||||||
|
logger.log('conversation', 'Back navigation to /c/new detected, resetting state');
|
||||||
|
|
||||||
|
// Clear messages
|
||||||
|
queryClient.setQueryData<TMessage[]>(
|
||||||
|
[QueryKeys.messages, conversation?.conversationId ?? Constants.NEW_CONVO],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
queryClient.invalidateQueries([QueryKeys.messages]);
|
||||||
|
|
||||||
|
// Reset conversation
|
||||||
|
newConversation();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('popstate', handlePopState);
|
||||||
|
return () => window.removeEventListener('popstate', handlePopState);
|
||||||
|
}, [conversation?.conversationId, queryClient, newConversation]);
|
||||||
|
}
|
|
@ -5,7 +5,13 @@ import { Constants, EModelEndpoint } from 'librechat-data-provider';
|
||||||
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||||
import type { TPreset } from 'librechat-data-provider';
|
import type { TPreset } from 'librechat-data-provider';
|
||||||
import { useGetConvoIdQuery, useGetStartupConfig, useGetEndpointsQuery } from '~/data-provider';
|
import { useGetConvoIdQuery, useGetStartupConfig, useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { useNewConvo, useAppStartup, useAssistantListMap, useIdChangeEffect } from '~/hooks';
|
import {
|
||||||
|
useNewConvo,
|
||||||
|
useAppStartup,
|
||||||
|
useBackToNewChat,
|
||||||
|
useIdChangeEffect,
|
||||||
|
useAssistantListMap,
|
||||||
|
} from '~/hooks';
|
||||||
import { getDefaultModelSpec, getModelSpecPreset, logger } from '~/utils';
|
import { getDefaultModelSpec, getModelSpecPreset, logger } from '~/utils';
|
||||||
import { ToolCallsMapProvider } from '~/Providers';
|
import { ToolCallsMapProvider } from '~/Providers';
|
||||||
import ChatView from '~/components/Chat/ChatView';
|
import ChatView from '~/components/Chat/ChatView';
|
||||||
|
@ -32,6 +38,7 @@ export default function ChatRoute() {
|
||||||
useIdChangeEffect(conversationId);
|
useIdChangeEffect(conversationId);
|
||||||
const { hasSetConversation, conversation } = store.useCreateConversationAtom(index);
|
const { hasSetConversation, conversation } = store.useCreateConversationAtom(index);
|
||||||
const { newConversation } = useNewConvo();
|
const { newConversation } = useNewConvo();
|
||||||
|
useBackToNewChat(index);
|
||||||
|
|
||||||
const modelsQuery = useGetModelsQuery({
|
const modelsQuery = useGetModelsQuery({
|
||||||
enabled: isAuthenticated,
|
enabled: isAuthenticated,
|
||||||
|
|
43
docs/fixes/back-button-navigation-fix.md
Normal file
43
docs/fixes/back-button-navigation-fix.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# Back Button Navigation Fix for LibreChat
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
When users navigate back to `/c/new` using the browser's back button from an existing conversation, the conversation state doesn't reset properly. This causes new messages to be appended to the previous conversation instead of creating a new one.
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
Created a custom hook `useBackToNewChat` that listens for browser back/forward navigation events and resets the conversation state when navigating back to `/c/new`.
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
### New Hook: `useBackToNewChat`
|
||||||
|
Located at: `client/src/hooks/useBackToNewChat.ts`
|
||||||
|
|
||||||
|
The hook:
|
||||||
|
1. **Listens to popstate events** - Detects when users use browser back/forward buttons
|
||||||
|
2. **Checks current path** - Verifies if the navigation landed on `/c/new`
|
||||||
|
3. **Resets conversation state** - Clears messages and creates a new conversation if needed
|
||||||
|
|
||||||
|
### Integration
|
||||||
|
The hook is used in `ChatRoute.tsx`:
|
||||||
|
```typescript
|
||||||
|
// Handle back navigation to /c/new
|
||||||
|
useBackToNewChat(index);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why This Approach?
|
||||||
|
- **Direct browser event handling** - The `popstate` event fires specifically for browser navigation (back/forward buttons)
|
||||||
|
- **No complex state tracking** - Avoids finicky effects that depend on conversation state changes
|
||||||
|
- **Simple and focused** - Single responsibility: detect back navigation to new chat and reset state
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
- Minimal impact on existing code
|
||||||
|
- Isolated logic that's easier to test and maintain
|
||||||
|
- Directly addresses the root cause (browser back button)
|
||||||
|
- Avoids race conditions with conversation state updates
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
Test file: `client/src/hooks/__tests__/useBackToNewChat.test.ts`
|
||||||
|
|
||||||
|
Tests cover:
|
||||||
|
- Popstate event handling when navigating to /c/new
|
||||||
|
- No action when already on /c/new
|
||||||
|
- No action when navigating to other routes
|
Loading…
Add table
Add a link
Reference in a new issue