mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-02-16 05:37:31 +00:00
refactor: replace messages with latestMessage in WebSocket context and related components
Why? Because, messages was only being used to access the latest message in the components it's used in.
This commit is contained in:
10
src/App.jsx
10
src/App.jsx
@@ -85,7 +85,7 @@ function AppContent() {
|
|||||||
// Triggers ChatInterface to reload messages without switching sessions
|
// Triggers ChatInterface to reload messages without switching sessions
|
||||||
const [externalMessageUpdate, setExternalMessageUpdate] = useState(0);
|
const [externalMessageUpdate, setExternalMessageUpdate] = useState(0);
|
||||||
|
|
||||||
const { ws, sendMessage, messages } = useWebSocket();
|
const { ws, sendMessage, latestMessage } = useWebSocket();
|
||||||
|
|
||||||
// Ref to track loading progress timeout for cleanup
|
// Ref to track loading progress timeout for cleanup
|
||||||
const loadingProgressTimeoutRef = useRef(null);
|
const loadingProgressTimeoutRef = useRef(null);
|
||||||
@@ -179,9 +179,7 @@ function AppContent() {
|
|||||||
|
|
||||||
// Handle WebSocket messages for real-time project updates
|
// Handle WebSocket messages for real-time project updates
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messages.length > 0) {
|
if (latestMessage) {
|
||||||
const latestMessage = messages[messages.length - 1];
|
|
||||||
|
|
||||||
// Handle loading progress updates
|
// Handle loading progress updates
|
||||||
if (latestMessage.type === 'loading_progress') {
|
if (latestMessage.type === 'loading_progress') {
|
||||||
if (loadingProgressTimeoutRef.current) {
|
if (loadingProgressTimeoutRef.current) {
|
||||||
@@ -281,7 +279,7 @@ function AppContent() {
|
|||||||
loadingProgressTimeoutRef.current = null;
|
loadingProgressTimeoutRef.current = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [messages, selectedProject, selectedSession, activeSessions]);
|
}, [latestMessage, selectedProject, selectedSession, activeSessions]);
|
||||||
|
|
||||||
const fetchProjects = async () => {
|
const fetchProjects = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -920,7 +918,7 @@ function AppContent() {
|
|||||||
setActiveTab={setActiveTab}
|
setActiveTab={setActiveTab}
|
||||||
ws={ws}
|
ws={ws}
|
||||||
sendMessage={sendMessage}
|
sendMessage={sendMessage}
|
||||||
messages={messages}
|
latestMessage={latestMessage}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
isPWA={isPWA}
|
isPWA={isPWA}
|
||||||
onMenuClick={() => setSidebarOpen(true)}
|
onMenuClick={() => setSidebarOpen(true)}
|
||||||
|
|||||||
@@ -1862,7 +1862,7 @@ const ImageAttachment = ({ file, onRemove, uploadProgress, error }) => {
|
|||||||
// - onReplaceTemporarySession: Called to replace temporary session ID with real WebSocket session ID
|
// - onReplaceTemporarySession: Called to replace temporary session ID with real WebSocket session ID
|
||||||
//
|
//
|
||||||
// This ensures uninterrupted chat experience by pausing sidebar refreshes during conversations.
|
// This ensures uninterrupted chat experience by pausing sidebar refreshes during conversations.
|
||||||
function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, messages, onFileOpen, onInputFocusChange, onSessionActive, onSessionInactive, onSessionProcessing, onSessionNotProcessing, processingSessions, onReplaceTemporarySession, onNavigateToSession, onShowSettings, autoExpandTools, showRawParameters, showThinking, autoScrollToBottom, sendByCtrlEnter, externalMessageUpdate, onTaskClick, onShowAllTasks }) {
|
function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, latestMessage, onFileOpen, onInputFocusChange, onSessionActive, onSessionInactive, onSessionProcessing, onSessionNotProcessing, processingSessions, onReplaceTemporarySession, onNavigateToSession, onShowSettings, autoExpandTools, showRawParameters, showThinking, autoScrollToBottom, sendByCtrlEnter, externalMessageUpdate, onTaskClick, onShowAllTasks }) {
|
||||||
const { tasksEnabled, isTaskMasterInstalled } = useTasksSettings();
|
const { tasksEnabled, isTaskMasterInstalled } = useTasksSettings();
|
||||||
const { t } = useTranslation('chat');
|
const { t } = useTranslation('chat');
|
||||||
const [input, setInput] = useState(() => {
|
const [input, setInput] = useState(() => {
|
||||||
@@ -3244,8 +3244,7 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Handle WebSocket messages
|
// Handle WebSocket messages
|
||||||
if (messages.length > 0) {
|
if (latestMessage) {
|
||||||
const latestMessage = messages[messages.length - 1];
|
|
||||||
const messageData = latestMessage.data?.message || latestMessage.data;
|
const messageData = latestMessage.data?.message || latestMessage.data;
|
||||||
|
|
||||||
// Filter messages by session ID to prevent cross-session interference
|
// Filter messages by session ID to prevent cross-session interference
|
||||||
@@ -4070,7 +4069,7 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [messages]);
|
}, [latestMessage]);
|
||||||
|
|
||||||
// Load file list when project changes
|
// Load file list when project changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ function MainContent({
|
|||||||
setActiveTab,
|
setActiveTab,
|
||||||
ws,
|
ws,
|
||||||
sendMessage,
|
sendMessage,
|
||||||
messages,
|
latestMessage,
|
||||||
isMobile,
|
isMobile,
|
||||||
isPWA, // ! Unused
|
isPWA, // ! Unused
|
||||||
onMenuClick,
|
onMenuClick,
|
||||||
@@ -477,7 +477,7 @@ function MainContent({
|
|||||||
selectedSession={selectedSession}
|
selectedSession={selectedSession}
|
||||||
ws={ws}
|
ws={ws}
|
||||||
sendMessage={sendMessage}
|
sendMessage={sendMessage}
|
||||||
messages={messages}
|
latestMessage={latestMessage}
|
||||||
onFileOpen={handleFileOpen}
|
onFileOpen={handleFileOpen}
|
||||||
onInputFocusChange={onInputFocusChange}
|
onInputFocusChange={onInputFocusChange}
|
||||||
onSessionActive={onSessionActive}
|
onSessionActive={onSessionActive}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const useTaskMaster = () => {
|
|||||||
|
|
||||||
export const TaskMasterProvider = ({ children }) => {
|
export const TaskMasterProvider = ({ children }) => {
|
||||||
// Get WebSocket messages from shared context to avoid duplicate connections
|
// Get WebSocket messages from shared context to avoid duplicate connections
|
||||||
const { messages } = useWebSocket();
|
const { latestMessage } = useWebSocket();
|
||||||
|
|
||||||
// Authentication context
|
// Authentication context
|
||||||
const { user, token, isLoading: authLoading } = useAuth();
|
const { user, token, isLoading: authLoading } = useAuth();
|
||||||
@@ -238,9 +238,8 @@ export const TaskMasterProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
}, [currentProject?.name, user, token, refreshTasks]);
|
}, [currentProject?.name, user, token, refreshTasks]);
|
||||||
|
|
||||||
// Handle WebSocket messages for TaskMaster updates
|
// Handle WebSocket latestMessage for TaskMaster updates
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const latestMessage = messages[messages.length - 1];
|
|
||||||
if (!latestMessage) return;
|
if (!latestMessage) return;
|
||||||
|
|
||||||
|
|
||||||
@@ -268,7 +267,7 @@ export const TaskMasterProvider = ({ children }) => {
|
|||||||
// Ignore non-TaskMaster messages
|
// Ignore non-TaskMaster messages
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, [messages, refreshProjects, refreshTasks, refreshMCPStatus, currentProject]);
|
}, [latestMessage, refreshProjects, refreshTasks, refreshMCPStatus, currentProject]);
|
||||||
|
|
||||||
// Context value
|
// Context value
|
||||||
const contextValue = {
|
const contextValue = {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { IS_PLATFORM } from '../constants/config';
|
|||||||
type WebSocketContextType = {
|
type WebSocketContextType = {
|
||||||
ws: WebSocket | null;
|
ws: WebSocket | null;
|
||||||
sendMessage: (message: any) => void;
|
sendMessage: (message: any) => void;
|
||||||
messages: any[];
|
latestMessage: any | null;
|
||||||
isConnected: boolean;
|
isConnected: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,8 +28,8 @@ const buildWebSocketUrl = (token: string | null) => {
|
|||||||
|
|
||||||
const useWebSocketProviderState = (): WebSocketContextType => {
|
const useWebSocketProviderState = (): WebSocketContextType => {
|
||||||
const wsRef = useRef<WebSocket | null>(null);
|
const wsRef = useRef<WebSocket | null>(null);
|
||||||
const unmountedRef = useRef(false);
|
const unmountedRef = useRef(false); // Track if component is unmounted
|
||||||
const [messages, setMessages] = useState<any[]>([]);
|
const [latestMessage, setLatestMessage] = useState<any>(null);
|
||||||
const [isConnected, setIsConnected] = useState(false);
|
const [isConnected, setIsConnected] = useState(false);
|
||||||
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
const { token } = useAuth();
|
const { token } = useAuth();
|
||||||
@@ -66,7 +66,7 @@ const useWebSocketProviderState = (): WebSocketContextType => {
|
|||||||
websocket.onmessage = (event) => {
|
websocket.onmessage = (event) => {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
setMessages(prev => [...prev, data]);
|
setLatestMessage(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error parsing WebSocket message:', error);
|
console.error('Error parsing WebSocket message:', error);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user