From b89e16bc0ddfdece9dc73c3806546520bb495c5a Mon Sep 17 00:00:00 2001 From: Bas van den Aakster Date: Fri, 12 Dec 2025 22:50:29 +0100 Subject: [PATCH] Remove dead code: App-old.jsx and unused components Cleanup: - Delete App-old.jsx (1,368 lines) - outdated pre-refactor version - Delete entire src/components/ directory (10 unused files) - QRScanner.jsx, QRCodeDisplay.jsx, Message.jsx - MethodSelector.jsx, FileUploadProgress.jsx, ChatView.jsx - ActionSelector.jsx, Header.jsx, TopicsList.jsx, ConnectionForm.jsx Impact: Removes ~1,500 lines of dead code Verified: No imports found, build passes --- src/App-old.jsx | 1368 ------------------------- src/components/ActionSelector.jsx | 37 - src/components/ChatView.jsx | 99 -- src/components/ConnectionForm.jsx | 53 - src/components/FileUploadProgress.jsx | 17 - src/components/Header.jsx | 32 - src/components/Message.jsx | 28 - src/components/MethodSelector.jsx | 39 - src/components/QRCodeDisplay.jsx | 13 - src/components/QRScanner.jsx | 74 -- src/components/TopicsList.jsx | 120 --- 11 files changed, 1880 deletions(-) delete mode 100644 src/App-old.jsx delete mode 100644 src/components/ActionSelector.jsx delete mode 100644 src/components/ChatView.jsx delete mode 100644 src/components/ConnectionForm.jsx delete mode 100644 src/components/FileUploadProgress.jsx delete mode 100644 src/components/Header.jsx delete mode 100644 src/components/Message.jsx delete mode 100644 src/components/MethodSelector.jsx delete mode 100644 src/components/QRCodeDisplay.jsx delete mode 100644 src/components/QRScanner.jsx delete mode 100644 src/components/TopicsList.jsx diff --git a/src/App-old.jsx b/src/App-old.jsx deleted file mode 100644 index 5c0bf56..0000000 --- a/src/App-old.jsx +++ /dev/null @@ -1,1368 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react'; -import { Rondevu } from '@xtr-dev/rondevu-client'; -import toast, { Toaster } from 'react-hot-toast'; - -const API_URL = 'https://api.ronde.vu'; - -// Preset RTC configurations -const RTC_PRESETS = { - 'ipv4-turn': { - name: 'IPv4 TURN (Recommended)', - config: { - iceServers: [ - { urls: ["stun:57.129.61.67:3478"] }, - { - urls: [ - "turn:57.129.61.67:3478?transport=tcp", - "turn:57.129.61.67:3478?transport=udp", - ], - username: "webrtcuser", - credential: "supersecretpassword" - } - ], - } - }, - 'hostname-turns': { - name: 'Hostname TURNS (TLS)', - config: { - iceServers: [ - { urls: ["stun:turn.share.fish:3478"] }, - { - urls: [ - "turns:turn.share.fish:5349?transport=tcp", - "turns:turn.share.fish:5349?transport=udp", - "turn:turn.share.fish:3478?transport=tcp", - "turn:turn.share.fish:3478?transport=udp", - ], - username: "webrtcuser", - credential: "supersecretpassword" - } - ], - } - }, - 'google-stun': { - name: 'Google STUN Only', - config: { - iceServers: [ - { urls: 'stun:stun.l.google.com:19302' }, - { urls: 'stun:stun1.l.google.com:19302' } - ] - } - }, - 'relay-only': { - name: 'Force TURN Relay (Testing)', - config: { - iceServers: [ - { urls: ["stun:57.129.61.67:3478"] }, - { - urls: [ - "turn:57.129.61.67:3478?transport=tcp", - "turn:57.129.61.67:3478?transport=udp", - ], - username: "webrtcuser", - credential: "supersecretpassword" - } - ], - iceTransportPolicy: 'relay' - } - }, - 'custom': { - name: 'Custom Configuration', - config: null // Will be loaded from user input - } -}; - -export default function App() { - const [client, setClient] = useState(null); - const [credentials, setCredentials] = useState(null); - const [myUsername, setMyUsername] = useState(null); - - // Setup - const [setupStep, setSetupStep] = useState('register'); // register, claim, ready - const [usernameInput, setUsernameInput] = useState(''); - - // Contacts - const [contacts, setContacts] = useState([]); - const [contactInput, setContactInput] = useState(''); - const [onlineUsers, setOnlineUsers] = useState(new Set()); - - // Chat - const [activeChats, setActiveChats] = useState({}); - const [selectedChat, setSelectedChat] = useState(null); - const [messageInputs, setMessageInputs] = useState({}); - - // Service - const [serviceHandle, setServiceHandle] = useState(null); - const chatEndRef = useRef(null); - - // Settings - const [showSettings, setShowSettings] = useState(false); - const [rtcPreset, setRtcPreset] = useState('ipv4-turn'); - const [customRtcConfig, setCustomRtcConfig] = useState(''); - - // Get current RTC configuration - const getCurrentRtcConfig = () => { - if (rtcPreset === 'custom') { - try { - return JSON.parse(customRtcConfig); - } catch (err) { - console.error('Invalid custom RTC config:', err); - return RTC_PRESETS['ipv4-turn'].config; - } - } - return RTC_PRESETS[rtcPreset]?.config || RTC_PRESETS['ipv4-turn'].config; - }; - - // Load saved settings - useEffect(() => { - const savedPreset = localStorage.getItem('rondevu-rtc-preset'); - const savedCustomConfig = localStorage.getItem('rondevu-rtc-custom'); - - if (savedPreset) { - setRtcPreset(savedPreset); - } - if (savedCustomConfig) { - setCustomRtcConfig(savedCustomConfig); - } - }, []); - - // Save settings when they change - useEffect(() => { - localStorage.setItem('rondevu-rtc-preset', rtcPreset); - }, [rtcPreset]); - - useEffect(() => { - if (customRtcConfig) { - localStorage.setItem('rondevu-rtc-custom', customRtcConfig); - } - }, [customRtcConfig]); - - // Load saved data and auto-register - useEffect(() => { - const savedCreds = localStorage.getItem('rondevu-chat-credentials'); - const savedUsername = localStorage.getItem('rondevu-chat-username'); - const savedContacts = localStorage.getItem('rondevu-chat-contacts'); - - const initialize = async () => { - let clientInstance; - - // Load contacts first - if (savedContacts) { - try { - setContacts(JSON.parse(savedContacts)); - } catch (err) { - console.error('Failed to load contacts:', err); - } - } - - // Handle credentials - if (savedCreds) { - try { - const creds = JSON.parse(savedCreds); - setCredentials(creds); - clientInstance = new Rondevu({ baseUrl: API_URL, credentials: creds }); - setClient(clientInstance); - - // If we have username too, go straight to ready - if (savedUsername) { - setMyUsername(savedUsername); - setSetupStep('ready'); - } else { - // Have creds but no username - go to claim step - setSetupStep('claim'); - } - } catch (err) { - console.error('Failed to load credentials:', err); - // Invalid saved creds - auto-register - clientInstance = new Rondevu({ baseUrl: API_URL }); - setClient(clientInstance); - await autoRegister(clientInstance); - } - } else { - // No saved credentials - auto-register - console.log('No saved credentials, auto-registering...'); - clientInstance = new Rondevu({ baseUrl: API_URL }); - setClient(clientInstance); - await autoRegister(clientInstance); - } - }; - - const autoRegister = async (clientInstance) => { - try { - console.log('Starting auto-registration...'); - const creds = await clientInstance.register(); - console.log('Registration successful:', creds); - setCredentials(creds); - localStorage.setItem('rondevu-chat-credentials', JSON.stringify(creds)); - const newClient = new Rondevu({ baseUrl: API_URL, credentials: creds }); - setClient(newClient); - setSetupStep('claim'); - } catch (err) { - console.error('Auto-registration failed:', err); - toast.error(`Registration failed: ${err.message}`); - setSetupStep('claim'); // Still allow username claim, might work anyway - } - }; - - initialize(); - }, []); - - // Auto-scroll chat - useEffect(() => { - chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }); - }, [activeChats, selectedChat]); - - // Start chat service when ready - useEffect(() => { - if (setupStep === 'ready' && myUsername && client && !serviceHandle) { - startChatService(); - } - }, [setupStep, myUsername, client]); - - // Check online status periodically - // Note: Online detection by attempting to query services - // In v0.9.0 there's no direct listServices API, so we check by attempting connection - useEffect(() => { - if (setupStep !== 'ready' || !client) return; - - const checkOnlineStatus = async () => { - const online = new Set(); - for (const contact of contacts) { - try { - // Try to query the service via discovery endpoint - const response = await fetch(`${API_URL}/index/${contact}/query`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ serviceFqn: 'chat.rondevu@1.0.0' }) - }); - - if (response.ok) { - online.add(contact); - } - } catch (err) { - // User offline or doesn't exist - } - } - setOnlineUsers(online); - }; - - checkOnlineStatus(); - const interval = setInterval(checkOnlineStatus, 10000); // Check every 10s - - return () => clearInterval(interval); - }, [contacts, setupStep, client]); - - // Claim username - const handleClaimUsername = async () => { - if (!client || !usernameInput) return; - try { - const claim = await client.usernames.claimUsername(usernameInput); - client.usernames.saveKeypairToStorage(usernameInput, claim.publicKey, claim.privateKey); - setMyUsername(usernameInput); - localStorage.setItem('rondevu-chat-username', usernameInput); - setSetupStep('ready'); - toast.success(`Welcome, ${usernameInput}!`); - } catch (err) { - toast.error(`Error: ${err.message}`); - } - }; - - // Start pooled chat service with durable connections - const startChatService = async () => { - if (!client || !myUsername || serviceHandle) return; - - try { - const keypair = client.usernames.loadKeypairFromStorage(myUsername); - if (!keypair) { - toast.error('Username keypair not found'); - return; - } - - const service = await client.exposeService({ - username: myUsername, - privateKey: keypair.privateKey, - serviceFqn: 'chat.rondevu@1.0.0', - isPublic: true, - ttl: 300000, // 5 minutes - service auto-refreshes - ttlRefreshMargin: 0.2, // Refresh at 80% of TTL - poolSize: 10, // Support up to 10 simultaneous connections - rtcConfig: getCurrentRtcConfig(), - handler: (channel, connectionId) => { - console.log(`📡 New chat connection: ${connectionId}`); - - // Wait for peer to identify themselves - channel.on('message', (data) => { - try { - const msg = JSON.parse(data); - - if (msg.type === 'identify') { - // Peer identified themselves - setActiveChats(prev => ({ - ...prev, - [msg.from]: { - username: msg.from, - channel, - connectionId, - messages: prev[msg.from]?.messages || [], - status: 'connected' - } - })); - - // Remove old handler and add new one for chat messages - channel.off('message'); - channel.on('message', (chatData) => { - try { - const chatMsg = JSON.parse(chatData); - if (chatMsg.type === 'message') { - setActiveChats(prev => ({ - ...prev, - [msg.from]: { - ...prev[msg.from], - messages: [...(prev[msg.from]?.messages || []), { - from: msg.from, - text: chatMsg.text, - timestamp: Date.now() - }] - } - })); - } - } catch (err) { - console.error('Failed to parse chat message:', err); - } - }); - - // Send acknowledgment - channel.send(JSON.stringify({ - type: 'identify_ack', - from: myUsername - })); - } - } catch (err) { - console.error('Failed to parse identify message:', err); - } - }); - - channel.on('close', () => { - console.log(`👋 Chat closed: ${connectionId}`); - setActiveChats(prev => { - const updated = { ...prev }; - Object.keys(updated).forEach(user => { - if (updated[user].connectionId === connectionId) { - updated[user] = { ...updated[user], status: 'disconnected' }; - } - }); - return updated; - }); - }); - } - }); - - // Start the service - await service.start(); - - // Listen for service events - service.on('connection', (connId) => { - console.log(`🔗 New connection: ${connId}`); - }); - - service.on('disconnection', (connId) => { - console.log(`🔌 Disconnected: ${connId}`); - }); - - service.on('ttl-refreshed', (expiresAt) => { - console.log(`🔄 Service TTL refreshed, expires at: ${new Date(expiresAt)}`); - }); - - service.on('error', (error, context) => { - console.error(`❌ Service error (${context}):`, error); - }); - - setServiceHandle(service); - console.log('✅ Chat service started'); - } catch (err) { - console.error('Error starting chat service:', err); - toast.error(`Failed to start chat: ${err.message}`); - } - }; - - // Add contact - const handleAddContact = () => { - if (!contactInput || contacts.includes(contactInput)) { - toast.error('Invalid or duplicate contact'); - return; - } - if (contactInput === myUsername) { - toast.error("You can't add yourself!"); - return; - } - - const newContacts = [...contacts, contactInput]; - setContacts(newContacts); - localStorage.setItem('rondevu-chat-contacts', JSON.stringify(newContacts)); - setContactInput(''); - toast.success(`Added ${contactInput}`); - }; - - // Remove contact - const handleRemoveContact = (contact) => { - const newContacts = contacts.filter(c => c !== contact); - setContacts(newContacts); - localStorage.setItem('rondevu-chat-contacts', JSON.stringify(newContacts)); - if (selectedChat === contact) { - setSelectedChat(null); - } - toast.success(`Removed ${contact}`); - }; - - // Start chat with contact using durable connection - const handleStartChat = async (contact) => { - if (!client || activeChats[contact]?.status === 'connected') { - setSelectedChat(contact); - return; - } - - try { - toast.loading(`Connecting to ${contact}...`, { id: 'connecting' }); - - // Create durable connection - const connection = await client.connect(contact, 'chat.rondevu@1.0.0', { - rtcConfig: getCurrentRtcConfig(), - maxReconnectAttempts: 5 - }); - - // Create data channel (must match service pool's channel name) - const channel = connection.createChannel('rondevu-service'); - - // Listen for connection events - connection.on('connected', () => { - console.log(`✅ Connected to ${contact}`); - }); - - connection.on('reconnecting', (attempt, max, delay) => { - console.log(`🔄 Reconnecting to ${contact} (${attempt}/${max}) in ${delay}ms`); - toast.loading(`Reconnecting to ${contact}...`, { id: 'reconnecting' }); - }); - - connection.on('disconnected', () => { - console.log(`🔌 Disconnected from ${contact}`); - setActiveChats(prev => ({ - ...prev, - [contact]: { ...prev[contact], status: 'reconnecting' } - })); - }); - - connection.on('failed', (error) => { - console.error(`❌ Connection to ${contact} failed:`, error); - toast.error(`Connection to ${contact} failed`, { id: 'connecting' }); - setActiveChats(prev => ({ - ...prev, - [contact]: { ...prev[contact], status: 'disconnected' } - })); - }); - - // Wait for acknowledgment - channel.on('message', (data) => { - try { - const msg = JSON.parse(data); - - if (msg.type === 'identify_ack') { - // Connection established - toast.success(`Connected to ${contact}`, { id: 'connecting' }); - - setActiveChats(prev => ({ - ...prev, - [contact]: { - username: contact, - channel, - connection, - messages: prev[contact]?.messages || [], - status: 'connected' - } - })); - setSelectedChat(contact); - - // Update handler for chat messages - channel.off('message'); - channel.on('message', (chatData) => { - try { - const chatMsg = JSON.parse(chatData); - if (chatMsg.type === 'message') { - setActiveChats(prev => ({ - ...prev, - [contact]: { - ...prev[contact], - messages: [...(prev[contact]?.messages || []), { - from: contact, - text: chatMsg.text, - timestamp: Date.now() - }] - } - })); - } - } catch (err) { - console.error('Failed to parse message:', err); - } - }); - } - } catch (err) { - console.error('Failed to parse ack:', err); - } - }); - - channel.on('close', () => { - setActiveChats(prev => ({ - ...prev, - [contact]: { ...prev[contact], status: 'disconnected' } - })); - toast.error(`Disconnected from ${contact}`); - }); - - // Connect and send identification - await connection.connect(); - - channel.send(JSON.stringify({ - type: 'identify', - from: myUsername - })); - - } catch (err) { - console.error('Failed to connect:', err); - toast.error(`Failed to connect to ${contact}`, { id: 'connecting' }); - } - }; - - // Send message - const handleSendMessage = (contact) => { - const text = messageInputs[contact]; - if (!text || !activeChats[contact]?.channel) return; - - const chat = activeChats[contact]; - if (chat.status !== 'connected') { - toast.error('Not connected'); - return; - } - - try { - chat.channel.send(JSON.stringify({ - type: 'message', - text - })); - - setActiveChats(prev => ({ - ...prev, - [contact]: { - ...prev[contact], - messages: [...prev[contact].messages, { - from: myUsername, - text, - timestamp: Date.now() - }] - } - })); - - setMessageInputs(prev => ({ ...prev, [contact]: '' })); - } catch (err) { - console.error('Failed to send message:', err); - toast.error('Failed to send message'); - } - }; - - // Clear all data - const handleLogout = () => { - if (window.confirm('Are you sure you want to logout? This will clear all data.')) { - localStorage.clear(); - window.location.reload(); - } - }; - - if (!client) { - return
Loading...
; - } - - return ( -
- - - {/* Settings Modal */} - {showSettings && ( -
setShowSettings(false)}> -
e.stopPropagation()}> -

WebRTC Configuration

- -
- - -
- - {rtcPreset === 'custom' && ( -
- -