Skip to content

Commit c7702db

Browse files
committed
Function: Add switch branch buttons
1 parent e2d992a commit c7702db

File tree

2 files changed

+109
-3
lines changed

2 files changed

+109
-3
lines changed

src/components/chat/ChatMessageArea.tsx

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Send, Square, Copy, RotateCcw, Share2, Pencil, Loader2 } from 'lucide-r
44
import MarkdownContent from './MarkdownContent';
55
import MessageToolboxMenu, { ToolboxAction } from '../ui/MessageToolboxMenu';
66
import { MessageHelper } from '../../services/message-helper';
7+
import { DatabaseIntegrationService } from '../../services/database-integration';
78

89
interface ChatMessageAreaProps {
910
activeConversation: Conversation | null;
@@ -43,7 +44,7 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
4344
setMessagesList(MessageHelper.mapMessagesTreeToList(activeConversation));
4445
}
4546
}, [activeConversation, activeConversation?.messages]);
46-
47+
4748
const handleSubmit = (e: FormEvent) => {
4849
e.preventDefault();
4950

@@ -112,6 +113,63 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
112113
return messagesList;
113114
}
114115

116+
const handleMessageIndexChange = async (messageId: string, isPrevious: boolean) => {
117+
if (!activeConversation) return;
118+
119+
const message = messagesList.find(m => m.messageId === messageId);
120+
if (!message || !message.fatherMessageId) return;
121+
122+
const fatherMessage = activeConversation.messages.get(message.fatherMessageId);
123+
if (!fatherMessage) return;
124+
125+
const currentIndex = fatherMessage.childrenMessageIds.indexOf(messageId);
126+
if (currentIndex <= 0 && isPrevious) return;
127+
if (currentIndex >= fatherMessage.childrenMessageIds.length - 1 && !isPrevious) return;
128+
129+
// Create updated message
130+
const updatedFatherMessage = {
131+
...fatherMessage,
132+
preferIndex: currentIndex + (isPrevious ? -1 : 1),
133+
};
134+
135+
// Update activeConversation
136+
activeConversation.messages.set(updatedFatherMessage.messageId, updatedFatherMessage);
137+
138+
// Update database
139+
const dbService = DatabaseIntegrationService.getInstance();
140+
await dbService.updateChatMessage(
141+
updatedFatherMessage.messageId,
142+
updatedFatherMessage,
143+
updatedFatherMessage.conversationId
144+
);
145+
146+
setMessagesList(MessageHelper.mapMessagesTreeToList(activeConversation));
147+
};
148+
149+
const getCurrentMessageIndex = (messageId: string) => {
150+
const message = messagesList.find(m => m.messageId === messageId);
151+
if (!message) return 0;
152+
153+
const fatherMessage = messagesList.find(m => m.messageId === message.fatherMessageId);
154+
if (fatherMessage) {
155+
// Find the index of this message in the father's children
156+
const index = fatherMessage.childrenMessageIds.indexOf(messageId);
157+
return index >= 0 ? index : 0;
158+
}
159+
return 0;
160+
}
161+
162+
const getTotalMessagesNumber = (messageId: string) => {
163+
const message = messagesList.find(m => m.messageId === messageId);
164+
if (!message) return 0;
165+
166+
const fatherMessage = messagesList.find(m => m.messageId === message.fatherMessageId);
167+
if (fatherMessage) {
168+
return fatherMessage.childrenMessageIds.length;
169+
}
170+
return 0;
171+
}
172+
115173
// If no active conversation is selected
116174
if (!activeConversation) {
117175
return (
@@ -226,6 +284,10 @@ export const ChatMessageArea: React.FC<ChatMessageAreaProps> = ({
226284
<MessageToolboxMenu
227285
actions={toolboxActions}
228286
className={`mr-1 ${hoveredMessageId === message.messageId ? 'opacity-100' : 'opacity-0'}`}
287+
currentMessageIndex={getCurrentMessageIndex(message.messageId)}
288+
totalMessages={getTotalMessagesNumber(message.messageId)}
289+
onPreviousMessageClick={() => handleMessageIndexChange(message.messageId, true)}
290+
onNextMessageClick={() => handleMessageIndexChange(message.messageId, false)}
229291
/>
230292
</div>
231293
</>

src/components/ui/MessageToolboxMenu.tsx

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState } from 'react';
2-
import { LucideIcon } from 'lucide-react';
2+
import { ChevronLeft, ChevronRight, LucideIcon } from 'lucide-react';
33

44
export interface ToolboxAction {
55
id: string;
@@ -12,6 +12,10 @@ export interface ToolboxAction {
1212
interface MessageToolboxMenuProps {
1313
actions: ToolboxAction[];
1414
className?: string;
15+
currentMessageIndex: number;
16+
totalMessages: number;
17+
onPreviousMessageClick: () => void;
18+
onNextMessageClick: () => void;
1519
}
1620

1721
/**
@@ -20,10 +24,22 @@ interface MessageToolboxMenuProps {
2024
*/
2125
const MessageToolboxMenu: React.FC<MessageToolboxMenuProps> = ({
2226
actions,
23-
className = ''
27+
className = '',
28+
currentMessageIndex,
29+
totalMessages,
30+
onPreviousMessageClick,
31+
onNextMessageClick
2432
}) => {
2533
const [activeTooltip, setActiveTooltip] = useState<string | null>(null);
2634

35+
const handlePreviousMessageClick = () => {
36+
onPreviousMessageClick();
37+
};
38+
39+
const handleNextMessageClick = () => {
40+
onNextMessageClick();
41+
};
42+
2743
return (
2844
<div
2945
className={`flex items-center justify-end space-x-1 transition-opacity duration-200 ${className}`}
@@ -55,6 +71,34 @@ const MessageToolboxMenu: React.FC<MessageToolboxMenuProps> = ({
5571
)}
5672
</div>
5773
))}
74+
75+
{totalMessages > 1 && (
76+
<>
77+
<button
78+
onClick={handlePreviousMessageClick}
79+
className={`flex items-center justify-center p-1.5 text-gray-600 rounded hover:bg-gray-100 transition-colors cursor-pointer`}
80+
title={'Previous Message'}
81+
aria-label={'Previous Message'}
82+
onMouseEnter={() => setActiveTooltip('previousMessage')}
83+
onMouseLeave={() => setActiveTooltip(null)}
84+
>
85+
<ChevronLeft />
86+
</button>
87+
88+
<span className='text-gray-600'>{currentMessageIndex + 1} / {totalMessages}</span>
89+
90+
<button
91+
onClick={handleNextMessageClick}
92+
className={`flex items-center justify-center p-1.5 text-gray-600 rounded hover:bg-gray-100 transition-colors cursor-pointer`}
93+
title={'Next Message'}
94+
aria-label={'Next Message'}
95+
onMouseEnter={() => setActiveTooltip('nextMessage')}
96+
onMouseLeave={() => setActiveTooltip(null)}
97+
>
98+
<ChevronRight />
99+
</button>
100+
</>
101+
)}
58102
</div>
59103
);
60104
};

0 commit comments

Comments
 (0)