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:
Haileyesus
2026-01-31 15:43:24 +03:00
parent 4f87018e61
commit 20d31da4f4
5 changed files with 16 additions and 20 deletions

View File

@@ -85,7 +85,7 @@ function AppContent() {
// Triggers ChatInterface to reload messages without switching sessions
const [externalMessageUpdate, setExternalMessageUpdate] = useState(0);
const { ws, sendMessage, messages } = useWebSocket();
const { ws, sendMessage, latestMessage } = useWebSocket();
// Ref to track loading progress timeout for cleanup
const loadingProgressTimeoutRef = useRef(null);
@@ -179,9 +179,7 @@ function AppContent() {
// Handle WebSocket messages for real-time project updates
useEffect(() => {
if (messages.length > 0) {
const latestMessage = messages[messages.length - 1];
if (latestMessage) {
// Handle loading progress updates
if (latestMessage.type === 'loading_progress') {
if (loadingProgressTimeoutRef.current) {
@@ -281,7 +279,7 @@ function AppContent() {
loadingProgressTimeoutRef.current = null;
}
};
}, [messages, selectedProject, selectedSession, activeSessions]);
}, [latestMessage, selectedProject, selectedSession, activeSessions]);
const fetchProjects = async () => {
try {
@@ -920,7 +918,7 @@ function AppContent() {
setActiveTab={setActiveTab}
ws={ws}
sendMessage={sendMessage}
messages={messages}
latestMessage={latestMessage}
isMobile={isMobile}
isPWA={isPWA}
onMenuClick={() => setSidebarOpen(true)}

View File

@@ -1862,7 +1862,7 @@ const ImageAttachment = ({ file, onRemove, uploadProgress, error }) => {
// - onReplaceTemporarySession: Called to replace temporary session ID with real WebSocket session ID
//
// 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 { t } = useTranslation('chat');
const [input, setInput] = useState(() => {
@@ -3244,8 +3244,7 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess
useEffect(() => {
// Handle WebSocket messages
if (messages.length > 0) {
const latestMessage = messages[messages.length - 1];
if (latestMessage) {
const messageData = latestMessage.data?.message || latestMessage.data;
// 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
useEffect(() => {

View File

@@ -36,7 +36,7 @@ function MainContent({
setActiveTab,
ws,
sendMessage,
messages,
latestMessage,
isMobile,
isPWA, // ! Unused
onMenuClick,
@@ -477,7 +477,7 @@ function MainContent({
selectedSession={selectedSession}
ws={ws}
sendMessage={sendMessage}
messages={messages}
latestMessage={latestMessage}
onFileOpen={handleFileOpen}
onInputFocusChange={onInputFocusChange}
onSessionActive={onSessionActive}

View File

@@ -42,7 +42,7 @@ export const useTaskMaster = () => {
export const TaskMasterProvider = ({ children }) => {
// Get WebSocket messages from shared context to avoid duplicate connections
const { messages } = useWebSocket();
const { latestMessage } = useWebSocket();
// Authentication context
const { user, token, isLoading: authLoading } = useAuth();
@@ -238,9 +238,8 @@ export const TaskMasterProvider = ({ children }) => {
}
}, [currentProject?.name, user, token, refreshTasks]);
// Handle WebSocket messages for TaskMaster updates
// Handle WebSocket latestMessage for TaskMaster updates
useEffect(() => {
const latestMessage = messages[messages.length - 1];
if (!latestMessage) return;
@@ -268,7 +267,7 @@ export const TaskMasterProvider = ({ children }) => {
// Ignore non-TaskMaster messages
break;
}
}, [messages, refreshProjects, refreshTasks, refreshMCPStatus, currentProject]);
}, [latestMessage, refreshProjects, refreshTasks, refreshMCPStatus, currentProject]);
// Context value
const contextValue = {

View File

@@ -5,7 +5,7 @@ import { IS_PLATFORM } from '../constants/config';
type WebSocketContextType = {
ws: WebSocket | null;
sendMessage: (message: any) => void;
messages: any[];
latestMessage: any | null;
isConnected: boolean;
};
@@ -28,8 +28,8 @@ const buildWebSocketUrl = (token: string | null) => {
const useWebSocketProviderState = (): WebSocketContextType => {
const wsRef = useRef<WebSocket | null>(null);
const unmountedRef = useRef(false);
const [messages, setMessages] = useState<any[]>([]);
const unmountedRef = useRef(false); // Track if component is unmounted
const [latestMessage, setLatestMessage] = useState<any>(null);
const [isConnected, setIsConnected] = useState(false);
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const { token } = useAuth();
@@ -66,7 +66,7 @@ const useWebSocketProviderState = (): WebSocketContextType => {
websocket.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
setMessages(prev => [...prev, data]);
setLatestMessage(data);
} catch (error) {
console.error('Error parsing WebSocket message:', error);
}