From 00c1c21e6c6e2485a5143bce984d8278ca68e67b Mon Sep 17 00:00:00 2001 From: Bas van den Aakster Date: Wed, 10 Dec 2025 22:34:20 +0100 Subject: [PATCH] feat: Unified chat UX - auto-accept connections on both sides - Remove pending requests approval flow - Auto-accept and open chat immediately when someone connects (same UX as initiating) - Remove accept/decline buttons and pending requests UI - Simplified flow: connection -> chat opens automatically - Both offerer and answerer now have consistent UX --- src/App.jsx | 157 ++++++---------------------------------------------- 1 file changed, 18 insertions(+), 139 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 0867c27..00816c3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -90,7 +90,6 @@ 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); @@ -513,23 +512,34 @@ export default function App() { if (msg.type === 'identify') { // Peer identified themselves peerUsername = msg.from; - console.log(`📡 New connection request from: ${peerUsername}`); + console.log(`📡 New connection from: ${peerUsername}`); - // Add to pending requests for approval - setPendingRequests(prev => ({ + // Auto-accept and open chat immediately (same UX as answerer side) + setActiveChats(prev => ({ ...prev, [peerUsername]: { username: peerUsername, channel: dc, connection: pc, - timestamp: Date.now() + messages: prev[peerUsername]?.messages || [], + status: 'connected', + role: 'host' } })); + // Auto-select the chat + setSelectedChat(peerUsername); + + // Send acknowledgment + dc.send(JSON.stringify({ + type: 'identify_ack', + from: hostUsername + })); + // Show notification - toast(`${peerUsername} wants to chat with you`, { - duration: 5000, - icon: '👤' + toast.success(`${peerUsername} connected!`, { + duration: 3000, + icon: '💬' }); } else if (msg.type === 'message' && peerUsername) { // Chat message @@ -785,68 +795,6 @@ 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) => { @@ -1040,75 +988,6 @@ 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 && (