diff --git a/client/src/App.tsx b/client/src/App.tsx index 9cbb4ab..e1f790b 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -27,6 +27,7 @@ import SettingsPage from "@/pages/SettingsPage"; import FocusPage from "@/pages/FocusPage"; import ThemePage from "@/pages/ThemePage"; import BenchmarkPage from "@/pages/BenchmarkPage"; +import ChatPage from "@/pages/ChatPage"; import NotFound from "@/pages/not-found"; function Router() { @@ -45,6 +46,7 @@ function Router() { + diff --git a/client/src/i18n/locales/en.json b/client/src/i18n/locales/en.json index e1c59c0..28da038 100644 --- a/client/src/i18n/locales/en.json +++ b/client/src/i18n/locales/en.json @@ -34,6 +34,7 @@ "voice": "Voice Commands", "analytics": "Analytics", "monitoring": "System Monitor", + "chat": "Messages", "settings": "Settings", "logout": "Logout", "profile": "Profile" @@ -70,6 +71,44 @@ "taskUpdated": "Task updated successfully", "taskDeleted": "Task deleted successfully" }, + "chat": { + "title": "Messages", + "searchPlaceholder": "Search conversations...", + "professionalServices": "Professional Services", + "typeMessage": "Type a message...", + "welcome": "Welcome to Messages", + "welcomeDescription": "Select a conversation to start messaging with your contacts and professional service providers.", + "selectedChat": "Selected Contact", + "lastSeen": "Last seen", + "minutesAgo": "minutes ago", + "noMessages": "No messages yet", + "edited": "edited", + "online": "Online", + "offline": "Offline", + "newContact": "Add Contact", + "newGroup": "New Group", + "callContact": "Call", + "videoCall": "Video Call", + "moreOptions": "More Options", + "messageStatus": { + "sent": "Sent", + "delivered": "Delivered", + "read": "Read" + }, + "messageTypes": { + "text": "Text", + "image": "Image", + "document": "Document", + "voice": "Voice Message", + "video": "Video", + "location": "Location" + }, + "attachments": "Attachments", + "voiceMessage": "Voice Message", + "sendMessage": "Send Message", + "today": "Today", + "yesterday": "Yesterday" + }, "finances": { "title": "Finances", "overview": "Financial Overview", diff --git a/server/routes.ts b/server/routes.ts index 3601788..b3c8e7c 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -443,5 +443,55 @@ export async function registerRoutes(app: Express): Promise { app.use(errorTrackingMiddleware); const httpServer = createServer(app); + + // WebSocket server setup for real-time chat + const wss = new WebSocketServer({ server: httpServer, path: '/ws' }); + + wss.on('connection', (ws: WebSocket) => { + console.log('New WebSocket connection'); + let userId: number | null = null; + + ws.on('message', (data: Buffer) => { + try { + const message = JSON.parse(data.toString()); + + if (message.type === 'join' && message.userId) { + userId = message.userId; + + // Add connection to user's connection list + if (!wsConnections.has(userId)) { + wsConnections.set(userId, []); + } + wsConnections.get(userId)!.push(ws); + + console.log(`User ${userId} connected to WebSocket`); + } + } catch (error) { + console.error('Error parsing WebSocket message:', error); + } + }); + + ws.on('close', () => { + if (userId) { + // Remove connection from user's connection list + const connections = wsConnections.get(userId); + if (connections) { + const index = connections.indexOf(ws); + if (index > -1) { + connections.splice(index, 1); + } + if (connections.length === 0) { + wsConnections.delete(userId); + } + } + console.log(`User ${userId} disconnected from WebSocket`); + } + }); + + ws.on('error', (error) => { + console.error('WebSocket error:', error); + }); + }); + return httpServer; }