diff --git a/src/App.jsx b/src/App.jsx index fc22381..13906ff 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -90,6 +90,7 @@ export default function App() { const [activeChats, setActiveChats] = useState({}); const [selectedChat, setSelectedChat] = useState(null); const [messageInputs, setMessageInputs] = useState({}); + const [pendingRequests, setPendingRequests] = useState({}); // Pending incoming connection requests // Service - we publish one service that can accept multiple connections const [myServicePublished, setMyServicePublished] = useState(false); @@ -508,29 +509,24 @@ export default function App() { if (msg.type === 'identify') { // Peer identified themselves peerUsername = msg.from; - console.log(`📡 New chat connection from: ${peerUsername}`); + console.log(`📡 New connection request from: ${peerUsername}`); - setActiveChats(prev => ({ + // Add to pending requests for approval + setPendingRequests(prev => ({ ...prev, [peerUsername]: { username: peerUsername, channel: dc, connection: pc, - messages: prev[peerUsername]?.messages || [], - status: 'connected', - role: 'host' + timestamp: Date.now() } })); - // Auto-select the incoming chat to show it immediately - setSelectedChat(peerUsername); - toast.success(`${peerUsername} connected to you!`); - - // Send acknowledgment - dc.send(JSON.stringify({ - type: 'identify_ack', - from: hostUsername - })); + // Show notification + toast(`${peerUsername} wants to chat with you`, { + duration: 5000, + icon: '👤' + }); } else if (msg.type === 'message' && peerUsername) { // Chat message setActiveChats(prev => ({ @@ -785,6 +781,69 @@ export default function App() { })); }; + // Accept incoming connection request + const handleAcceptRequest = (username) => { + const request = pendingRequests[username]; + if (!request) return; + + console.log(`✅ Accepting connection request from: ${username}`); + + // Move from pending to active chats + setActiveChats(prev => ({ + ...prev, + [username]: { + username: username, + channel: request.channel, + connection: request.connection, + messages: prev[username]?.messages || [], + status: 'connected', + role: 'host' + } + })); + + // Remove from pending + setPendingRequests(prev => { + const updated = { ...prev }; + delete updated[username]; + return updated; + }); + + // Send acknowledgment + request.channel.send(JSON.stringify({ + type: 'identify_ack', + from: myUsername + })); + + // Auto-select the chat + setSelectedChat(username); + toast.success(`Connected with ${username}!`); + }; + + // Deny incoming connection request + const handleDenyRequest = (username) => { + const request = pendingRequests[username]; + if (!request) return; + + console.log(`❌ Denying connection request from: ${username}`); + + // Close the connection + try { + request.channel.close(); + request.connection.close(); + } catch (err) { + console.error('Error closing connection:', err); + } + + // Remove from pending + setPendingRequests(prev => { + const updated = { ...prev }; + delete updated[username]; + return updated; + }); + + toast.success(`Declined request from ${username}`); + }; + // Send message const handleSendMessage = (contact) => { const text = messageInputs[contact]; @@ -977,11 +1036,81 @@ export default function App() { + {/* Pending Connection Requests */} + {Object.keys(pendingRequests).length > 0 && ( +
+
+ Connection Requests ({Object.keys(pendingRequests).length}) +
+ {Object.keys(pendingRequests).map(username => ( +
+
+
+ {username[0].toUpperCase()} + +
+
+
{username}
+
+ Wants to chat +
+
+
+
+ + +
+
+ ))} +
+ )} + {/* Incoming Chats (not in contacts) */} {Object.keys(activeChats).filter(username => !contacts.includes(username) && activeChats[username].status === 'connected').length > 0 && (
- Incoming Chats ({Object.keys(activeChats).filter(username => !contacts.includes(username) && activeChats[username].status === 'connected').length}) + Active Chats ({Object.keys(activeChats).filter(username => !contacts.includes(username) && activeChats[username].status === 'connected').length})
{Object.keys(activeChats) .filter(username => !contacts.includes(username) && activeChats[username].status === 'connected') @@ -1005,7 +1134,7 @@ export default function App() {
{contact}
- Connected (incoming) + Connected
@@ -1053,15 +1182,51 @@ export default function App() { {hasActiveChat ? 'Chatting' : isOnline ? 'Online' : 'Offline'} + {hasActiveChat && ( + + )} );