Skip to content

Commit 6a7f470

Browse files
authored
Fix/conversation title UI update (#22)
* fix: resolve TypeScript error in theme-provider test - Fix 'children' prop missing error by passing undefined instead of empty - All 11 tests still passing - Resolves TypeScript compilation error * fix: display actual title prop in ConversationTitle component (TDD) TDD Red Phase: - Added 3 failing tests for custom title display bug - Tests verified title was overridden to 'New Conversation' Root Cause: - Line 58 in conversation-title.tsx had conditional override: const displayTitle = isNewConversation ? 'New Conversation' : title - When messages.length === 0, isNewConversation is true - Component overrode custom title with 'New Conversation' TDD Green Phase: - Removed conditional override: const displayTitle = title - Component now always displays actual title prop - Updated test expecting old buggy behavior Result: - Title updates immediately in UI when changed - All 33 component tests passing - All 511 tests passing (no regressions) - Fixes issue documented in docs/04-development/issues/ Previous 7 fix attempts modified page.tsx state management, but bug was in component override logic all along. * docs: update issue resolution and README with title fix details
1 parent d2cce73 commit 6a7f470

4 files changed

Lines changed: 137 additions & 12 deletions

File tree

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,32 @@ An intelligent AI-powered chat application built with Next.js 15 and Google Gemi
2828
- Word documents (.docx) - Extracted text content
2929
- **🌐 Website Scraping:** Provide any website URL, and the application will scrape its content to use as a source
3030
- **📊 Source Management:** Clean sidebar interface to easily add, view, and remove your files and URL sources
31+
32+
## 🚀 Recent Updates
33+
34+
### November 4, 2025 - Conversation Title UI Fix 🐛
35+
-**Fixed Critical Bug** - Conversation titles now update immediately in the header
36+
- **Root Cause:** `ConversationTitle` component was overriding the title prop with hardcoded "New Conversation" when `messages.length === 0`
37+
- **Solution:** Removed conditional override logic - component now displays actual title prop
38+
- **Impact:** Instant UI updates when changing conversation titles (no more page refresh needed)
39+
- **Testing:** TDD methodology with 3 new tests, all 511 tests passing ✅
40+
- **Branch:** `fix/conversation-title-ui-update`
41+
- **Lesson:** Previous 7 fix attempts modified state management, but bug was in component display logic
42+
43+
### November 2, 2025 - Enhanced Conversation Management
44+
-**Save Empty Conversations** - You can now save and name conversations even without messages or files
45+
- Create conversations with custom titles before chatting
46+
- Edit conversation titles anytime (not just after first message)
47+
- Better organization for planning and research workflows
48+
49+
### October 30, 2025 - Extended File Type Support 📄
50+
-**Added support for 3 new file types:** CSV, Markdown, and Word documents
51+
- `.csv` - Parsed with column headers and formatted tables
52+
- `.md` - Markdown files with preserved formatting
53+
- `.docx` - Microsoft Word documents with extracted text
54+
-**Updated welcome message** to reflect all 5 supported file types
55+
-**Comprehensive testing** with Jest and Playwright for all file formats
56+
3157
- **🎨 AI-Powered Theme Generation:** Dynamically create and apply color themes with AI-generated background images powered by Gemini 2.5 Flash Image
3258
- **🌙 Dark/Light Mode:** Quick theme toggle with keyboard shortcut (`Ctrl+Shift+T`)
3359
- **📱 Responsive Design:** Modern, responsive UI that works across different screen sizes

docs/04-development/issues/conversation-title-not-updating-in-ui.md

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# Issue: Conversation Title Not Updating in UI
22

3-
**Status:** Open
3+
**Status:** ✅ RESOLVED
44
**Priority:** High
55
**Date Reported:** November 2, 2025
6-
**Branch:** feat/save-empty-conversations
6+
**Date Resolved:** November 4, 2025
7+
**Original Branch:** feat/save-empty-conversations
8+
**Fix Branch:** fix/conversation-title-ui-update
9+
**Commit:** a1dd36c
710

811
## Problem Description
912

@@ -147,14 +150,77 @@ useEffect(() => {
147150

148151
All unit tests pass, but the visual UI update is not happening. This suggests the issue is related to React's rendering cycle rather than the underlying logic.
149152

150-
## Next Steps
153+
---
151154

152-
1. Add detailed console logging to track state changes
153-
2. Inspect ChatHeader and ConversationTitle components for rendering issues
154-
3. Check React DevTools to see if props are updating
155-
4. Consider if this is a React 19 or Next.js 15 specific issue
156-
5. Try creating a minimal reproduction case
155+
## ✅ RESOLUTION (November 4, 2025)
157156

158-
## Workaround for Users
157+
### Root Cause Found
158+
The bug was **NOT** in `page.tsx` state management (as all 7 attempts assumed), but in the `ConversationTitle` component itself.
159+
160+
**File:** `src/components/conversation-title.tsx`
161+
**Line:** 58
162+
**Buggy Code:**
163+
```typescript
164+
const displayTitle = isNewConversation ? 'New Conversation' : title;
165+
```
166+
167+
**Problem:**
168+
- When `isNewConversation = !currentConversationId || messages.length === 0`
169+
- User sets custom title on empty conversation → `currentConversationId` exists
170+
- But `messages.length === 0` is still `true`
171+
- Therefore `isNewConversation` is `true`
172+
- Component **overrides** the `title` prop with hardcoded `"New Conversation"`
173+
- Title prop was correct, but component ignored it!
174+
175+
### Fix Applied (TDD Methodology)
176+
177+
**Red Phase:** Added 3 failing tests
178+
1. "displays custom title even when isNewConversation is true and has no messages"
179+
2. "displays 'New Conversation' only when title is actually 'New Conversation'"
180+
3. "updates from 'New Conversation' to custom title in real-time"
181+
182+
**Green Phase:** Fixed bug with single line change
183+
```typescript
184+
// BEFORE (BUGGY):
185+
const displayTitle = isNewConversation ? 'New Conversation' : title;
186+
187+
// AFTER (FIXED):
188+
// Always display the actual title prop - don't override with "New Conversation"
189+
// The parent component determines what title to show
190+
const displayTitle = title;
191+
```
192+
193+
Also updated existing test that expected buggy behavior.
194+
195+
**Result:**
196+
- ✅ Title updates immediately in UI
197+
- ✅ All 33 component tests passing
198+
- ✅ All 511 tests passing (no regressions)
199+
- ✅ Minimal change (1 line fix)
200+
201+
### Why Previous 7 Attempts Failed
202+
All previous fixes modified `page.tsx` state management:
203+
- Removed dependencies from auto-save
204+
- Added refs to prevent stale closures
205+
- Fixed state update order
206+
- Auto-synced refs with useEffect
207+
- Saved full conversation on title change
208+
- Updated refs before setting conversation ID
209+
210+
**The real problem:** State management was working correctly all along! The component was **fighting against** the parent's state updates by overriding the title prop internally.
211+
212+
### Lessons Learned
213+
1. **Component hierarchy matters** - Check child components for prop overrides
214+
2. **State vs Display** - Component was ignoring parent's state
215+
3. **Minimal testing** - Previous attempts only tested state, not DOM rendering
216+
4. **TDD helps** - Writing failing tests exposed the component-level bug
217+
218+
### Related Commits
219+
- Fix commit: `a1dd36c` on `fix/conversation-title-ui-update` branch
220+
- Previous attempts: 7 commits on `feat/save-empty-conversations` branch (superseded)
221+
222+
---
223+
224+
## Workaround for Users (NO LONGER NEEDED)
159225

160226
**Current Workaround:** Refresh the page (F5 or Ctrl+R) after changing title or loading conversation.

src/__tests__/components/conversation-title.test.tsx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ describe('ConversationTitle', () => {
1919
expect(screen.getByText('Test Conversation')).toBeInTheDocument();
2020
});
2121

22-
it('displays "New Conversation" for new conversations', () => {
22+
it('displays actual title prop even for new conversations', () => {
23+
// Fixed: Now displays the actual title prop, not hardcoded "New Conversation"
2324
render(<ConversationTitle {...defaultProps} isNewConversation={true} />);
24-
expect(screen.getByText('New Conversation')).toBeInTheDocument();
25+
expect(screen.getByText('Test Conversation')).toBeInTheDocument();
2526
});
2627

2728
it('shows edit button on hover (non-new conversations)', () => {
@@ -422,4 +423,34 @@ describe('ConversationTitle', () => {
422423
expect(input.value).toBe('External Update');
423424
});
424425
});
426+
427+
describe('Custom Title Display (Bug Fix)', () => {
428+
it('displays custom title even when isNewConversation is true and has no messages', () => {
429+
// BUG: When a new conversation gets a custom title but has no messages yet,
430+
// it should show the custom title, not "New Conversation"
431+
render(<ConversationTitle {...defaultProps} title="My Custom Title" isNewConversation={true} />);
432+
433+
// Should show custom title, not "New Conversation"
434+
expect(screen.getByText('My Custom Title')).toBeInTheDocument();
435+
expect(screen.queryByText('New Conversation')).not.toBeInTheDocument();
436+
});
437+
438+
it('displays "New Conversation" only when title is actually "New Conversation"', () => {
439+
render(<ConversationTitle {...defaultProps} title="New Conversation" isNewConversation={true} />);
440+
expect(screen.getByText('New Conversation')).toBeInTheDocument();
441+
});
442+
443+
it('updates from "New Conversation" to custom title in real-time', () => {
444+
const { rerender } = render(
445+
<ConversationTitle {...defaultProps} title="New Conversation" isNewConversation={true} />
446+
);
447+
expect(screen.getByText('New Conversation')).toBeInTheDocument();
448+
449+
// User sets custom title - should update immediately
450+
rerender(<ConversationTitle {...defaultProps} title="Research Notes" isNewConversation={true} />);
451+
expect(screen.getByText('Research Notes')).toBeInTheDocument();
452+
expect(screen.queryByText('New Conversation')).not.toBeInTheDocument();
453+
});
454+
});
425455
});
456+

src/components/conversation-title.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ export function ConversationTitle({ title, onTitleChange, isNewConversation }: C
5757
}
5858
};
5959

60-
const displayTitle = isNewConversation ? 'New Conversation' : title;
60+
// Always display the actual title prop - don't override with "New Conversation"
61+
// The parent component determines what title to show
62+
const displayTitle = title;
6163

6264
if (isEditing) {
6365
return (

0 commit comments

Comments
 (0)