mirror of
https://github.com/xtr-dev/rondevu-demo.git
synced 2025-12-13 11:53:23 +00:00
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
This commit is contained in:
1368
src/App-old.jsx
1368
src/App-old.jsx
File diff suppressed because it is too large
Load Diff
@@ -1,37 +0,0 @@
|
||||
import QRScanner from './QRScanner';
|
||||
|
||||
function ActionSelector({ action, onSelectAction, onScanComplete, onScanCancel, log }) {
|
||||
return (
|
||||
<div className="step-container">
|
||||
<h2>Chat Demo</h2>
|
||||
<div className="button-grid button-grid-three">
|
||||
<button
|
||||
className="action-button"
|
||||
onClick={() => onSelectAction('create')}
|
||||
>
|
||||
<div className="button-title">Create</div>
|
||||
<div className="button-description">Start a new connection</div>
|
||||
</button>
|
||||
<button
|
||||
className="action-button"
|
||||
onClick={() => onSelectAction('join')}
|
||||
>
|
||||
<div className="button-title">Join</div>
|
||||
<div className="button-description">Connect to existing peers</div>
|
||||
</button>
|
||||
<button
|
||||
className="action-button"
|
||||
onClick={() => onSelectAction('scan')}
|
||||
>
|
||||
<div className="button-title">Scan QR</div>
|
||||
<div className="button-description">Scan a connection code</div>
|
||||
</button>
|
||||
</div>
|
||||
{action === 'scan' && (
|
||||
<QRScanner onScan={onScanComplete} onCancel={onScanCancel} log={log} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ActionSelector;
|
||||
@@ -1,99 +0,0 @@
|
||||
import { useRef } from 'react';
|
||||
import Message from './Message';
|
||||
import FileUploadProgress from './FileUploadProgress';
|
||||
|
||||
function ChatView({
|
||||
connectedPeer,
|
||||
currentConnectionId,
|
||||
messages,
|
||||
messageInput,
|
||||
setMessageInput,
|
||||
channelReady,
|
||||
logs,
|
||||
fileUploadProgress,
|
||||
onSendMessage,
|
||||
onFileSelect,
|
||||
onDisconnect,
|
||||
onDownloadFile,
|
||||
onCancelUpload
|
||||
}) {
|
||||
const fileInputRef = useRef(null);
|
||||
|
||||
return (
|
||||
<div className="chat-container">
|
||||
<div className="chat-header">
|
||||
<div>
|
||||
<h2>Connected</h2>
|
||||
<p className="connection-details">
|
||||
Peer: {connectedPeer || 'Unknown'} • ID: {currentConnectionId}
|
||||
</p>
|
||||
</div>
|
||||
<button className="disconnect-button" onClick={onDisconnect}>Disconnect</button>
|
||||
</div>
|
||||
|
||||
<div className="messages">
|
||||
{messages.length === 0 ? (
|
||||
<p className="empty">No messages yet. Start chatting!</p>
|
||||
) : (
|
||||
messages.map((msg, idx) => (
|
||||
<Message key={idx} message={msg} onDownload={onDownloadFile} />
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
|
||||
{fileUploadProgress && (
|
||||
<FileUploadProgress
|
||||
fileName={fileUploadProgress.fileName}
|
||||
progress={fileUploadProgress.progress}
|
||||
onCancel={onCancelUpload}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="message-input">
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
onChange={onFileSelect}
|
||||
style={{ display: 'none' }}
|
||||
/>
|
||||
<button
|
||||
className="file-button"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
disabled={!channelReady || fileUploadProgress}
|
||||
title="Send file"
|
||||
>
|
||||
📎
|
||||
</button>
|
||||
<input
|
||||
type="text"
|
||||
value={messageInput}
|
||||
onChange={(e) => setMessageInput(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && onSendMessage()}
|
||||
placeholder="Type a message..."
|
||||
disabled={!channelReady}
|
||||
/>
|
||||
<button
|
||||
onClick={onSendMessage}
|
||||
disabled={!channelReady}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{logs.length > 0 && (
|
||||
<details className="logs">
|
||||
<summary>Activity Log ({logs.length})</summary>
|
||||
<div className="log-entries">
|
||||
{logs.map((log, idx) => (
|
||||
<div key={idx} className={`log-entry ${log.type}`}>
|
||||
[{log.timestamp}] {log.message}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</details>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChatView;
|
||||
@@ -1,53 +0,0 @@
|
||||
import QRCodeDisplay from './QRCodeDisplay';
|
||||
|
||||
function ConnectionForm({
|
||||
action,
|
||||
connectionId,
|
||||
setConnectionId,
|
||||
connectionStatus,
|
||||
qrCodeUrl,
|
||||
currentConnectionId,
|
||||
onConnect,
|
||||
onBack
|
||||
}) {
|
||||
return (
|
||||
<div className="step-container">
|
||||
<h2>{action === 'create' ? 'Create Connection' : 'Join Connection'}</h2>
|
||||
<div className="form-container">
|
||||
<div className="form-group">
|
||||
<label>Connection ID {action === 'create' && '(optional)'}</label>
|
||||
<input
|
||||
type="text"
|
||||
value={connectionId}
|
||||
onChange={(e) => setConnectionId(e.target.value)}
|
||||
placeholder={action === 'create' ? 'Auto-generated if empty' : 'Enter connection ID'}
|
||||
autoFocus={action === 'connect'}
|
||||
/>
|
||||
{action === 'create' && !connectionId && (
|
||||
<p className="help-text">Leave empty to auto-generate a random ID</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="button-row">
|
||||
<button className="back-button" onClick={onBack}>← Back</button>
|
||||
<button
|
||||
className="primary-button"
|
||||
onClick={onConnect}
|
||||
disabled={
|
||||
connectionStatus === 'connecting' ||
|
||||
(action === 'connect' && !connectionId)
|
||||
}
|
||||
>
|
||||
{connectionStatus === 'connecting' ? 'Connecting...' : (action === 'create' ? 'Create' : 'Connect')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{qrCodeUrl && connectionStatus === 'connecting' && action === 'create' && (
|
||||
<QRCodeDisplay qrCodeUrl={qrCodeUrl} connectionId={currentConnectionId} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ConnectionForm;
|
||||
@@ -1,17 +0,0 @@
|
||||
function FileUploadProgress({ fileName, progress, onCancel }) {
|
||||
return (
|
||||
<div className="file-upload-progress">
|
||||
<div className="file-upload-header">
|
||||
<span className="file-upload-name">{fileName}</span>
|
||||
<button className="file-upload-cancel" onClick={onCancel}>×</button>
|
||||
</div>
|
||||
<div className="progress-bar">
|
||||
<div className="progress-bar-fill" style={{ width: `${progress}%` }}>
|
||||
<span className="progress-text">{progress}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FileUploadProgress;
|
||||
@@ -1,32 +0,0 @@
|
||||
function Header() {
|
||||
return (
|
||||
<header className="header">
|
||||
<div className="header-content">
|
||||
<h1>Rondevu</h1>
|
||||
<p className="tagline">Simple WebRTC peer signaling and discovery. Meet peers by topic, peer ID, or connection ID.</p>
|
||||
<div className="header-links">
|
||||
<a href="https://github.com/xtr-dev/rondevu-client" target="_blank" rel="noopener noreferrer">
|
||||
<svg className="github-icon" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
|
||||
</svg>
|
||||
Client
|
||||
</a>
|
||||
<a href="https://github.com/xtr-dev/rondevu-server" target="_blank" rel="noopener noreferrer">
|
||||
<svg className="github-icon" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
|
||||
</svg>
|
||||
Server
|
||||
</a>
|
||||
<a href="https://github.com/xtr-dev/rondevu-demo" target="_blank" rel="noopener noreferrer">
|
||||
<svg className="github-icon" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
|
||||
</svg>
|
||||
Demo
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
||||
@@ -1,28 +0,0 @@
|
||||
function Message({ message, onDownload }) {
|
||||
const isFile = message.messageType === 'file';
|
||||
|
||||
return (
|
||||
<div className={`message ${message.type}`}>
|
||||
{isFile ? (
|
||||
<div className="message-file">
|
||||
<div className="file-icon">📎</div>
|
||||
<div className="file-info">
|
||||
<div className="file-name">{message.file.name}</div>
|
||||
<div className="file-size">{(message.file.size / 1024).toFixed(2)} KB</div>
|
||||
</div>
|
||||
<button
|
||||
className="file-download"
|
||||
onClick={() => onDownload(message.file)}
|
||||
>
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="message-text">{message.text}</div>
|
||||
)}
|
||||
<div className="message-time">{message.timestamp.toLocaleTimeString()}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Message;
|
||||
@@ -1,39 +0,0 @@
|
||||
function MethodSelector({ action, onSelectMethod, onBack }) {
|
||||
return (
|
||||
<div className="step-container">
|
||||
<h2>{action === 'create' ? 'Create' : 'Join'} by...</h2>
|
||||
<div className="button-grid">
|
||||
<button
|
||||
className="action-button"
|
||||
onClick={() => onSelectMethod('topic')}
|
||||
>
|
||||
<div className="button-title">Topic</div>
|
||||
<div className="button-description">
|
||||
{action === 'create' ? 'Create in a topic' : 'Auto-connect to first peer'}
|
||||
</div>
|
||||
</button>
|
||||
{action === 'join' && (
|
||||
<button
|
||||
className="action-button"
|
||||
onClick={() => onSelectMethod('peer-id')}
|
||||
>
|
||||
<div className="button-title">Peer ID</div>
|
||||
<div className="button-description">Connect to specific peer</div>
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
className="action-button"
|
||||
onClick={() => onSelectMethod('connection-id')}
|
||||
>
|
||||
<div className="button-title">Connection ID</div>
|
||||
<div className="button-description">
|
||||
{action === 'create' ? 'Custom connection code' : 'Direct connection'}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<button className="back-button" onClick={onBack}>← Back</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MethodSelector;
|
||||
@@ -1,13 +0,0 @@
|
||||
function QRCodeDisplay({ qrCodeUrl, connectionId }) {
|
||||
if (!qrCodeUrl) return null;
|
||||
|
||||
return (
|
||||
<div className="qr-code-container">
|
||||
<p className="qr-label">Scan to connect:</p>
|
||||
<img src={qrCodeUrl} alt="Connection QR Code" className="qr-code" />
|
||||
<p className="connection-id-display">{connectionId}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default QRCodeDisplay;
|
||||
@@ -1,74 +0,0 @@
|
||||
import { useRef, useEffect } from 'react';
|
||||
import { BrowserQRCodeReader } from '@zxing/library';
|
||||
|
||||
function QRScanner({ onScan, onCancel, log }) {
|
||||
const videoRef = useRef(null);
|
||||
const scannerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
startScanning();
|
||||
return () => {
|
||||
stopScanning();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const startScanning = async () => {
|
||||
try {
|
||||
scannerRef.current = new BrowserQRCodeReader();
|
||||
log('Starting QR scanner...', 'info');
|
||||
|
||||
const videoInputDevices = await scannerRef.current.listVideoInputDevices();
|
||||
|
||||
if (videoInputDevices.length === 0) {
|
||||
log('No camera found', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Prefer back camera (environment-facing)
|
||||
let selectedDeviceId = videoInputDevices[0].deviceId;
|
||||
const backCamera = videoInputDevices.find(device =>
|
||||
device.label.toLowerCase().includes('back') ||
|
||||
device.label.toLowerCase().includes('rear') ||
|
||||
device.label.toLowerCase().includes('environment')
|
||||
);
|
||||
|
||||
if (backCamera) {
|
||||
selectedDeviceId = backCamera.deviceId;
|
||||
log('Using back camera', 'info');
|
||||
} else {
|
||||
log('Back camera not found, using default', 'info');
|
||||
}
|
||||
|
||||
scannerRef.current.decodeFromVideoDevice(
|
||||
selectedDeviceId,
|
||||
videoRef.current,
|
||||
(result, err) => {
|
||||
if (result) {
|
||||
const scannedId = result.getText();
|
||||
log(`Scanned: ${scannedId}`, 'success');
|
||||
stopScanning();
|
||||
onScan(scannedId);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
log(`Scanner error: ${error.message}`, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
const stopScanning = () => {
|
||||
if (scannerRef.current) {
|
||||
scannerRef.current.reset();
|
||||
log('Scanner stopped', 'info');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="scanner-container">
|
||||
<video ref={videoRef} className="scanner-video" />
|
||||
<button className="back-button" onClick={onCancel}>← Cancel</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default QRScanner;
|
||||
@@ -1,120 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
function TopicsList({ rdv, onClose }) {
|
||||
const [topics, setTopics] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [page, setPage] = useState(1);
|
||||
const [pagination, setPagination] = useState(null);
|
||||
const [limit] = useState(20);
|
||||
|
||||
useEffect(() => {
|
||||
loadTopics();
|
||||
}, [page]);
|
||||
|
||||
const loadTopics = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await rdv.api.listTopics(page, limit);
|
||||
setTopics(response.topics);
|
||||
setPagination(response.pagination);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRefresh = () => {
|
||||
loadTopics();
|
||||
};
|
||||
|
||||
const handlePrevPage = () => {
|
||||
if (page > 1) {
|
||||
setPage(page - 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextPage = () => {
|
||||
if (pagination?.hasMore) {
|
||||
setPage(page + 1);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="modal-overlay" onClick={onClose}>
|
||||
<div className="modal-content topics-modal" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="modal-header">
|
||||
<h2>Active Topics</h2>
|
||||
<button className="close-button" onClick={onClose}>×</button>
|
||||
</div>
|
||||
|
||||
<div className="modal-body">
|
||||
{error && (
|
||||
<div className="error-message" style={{ marginBottom: '1rem' }}>
|
||||
Error: {error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading ? (
|
||||
<div className="loading-message">Loading topics...</div>
|
||||
) : (
|
||||
<>
|
||||
{topics.length === 0 ? (
|
||||
<div className="empty-message">
|
||||
No active topics found. Be the first to create one!
|
||||
</div>
|
||||
) : (
|
||||
<div className="topics-list">
|
||||
{topics.map((topic) => (
|
||||
<div key={topic.topic} className="topic-item">
|
||||
<div className="topic-name">{topic.topic}</div>
|
||||
<div className="topic-count">
|
||||
{topic.count} {topic.count === 1 ? 'peer' : 'peers'}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{pagination && (
|
||||
<div className="pagination">
|
||||
<button
|
||||
onClick={handlePrevPage}
|
||||
disabled={page === 1}
|
||||
className="pagination-button"
|
||||
>
|
||||
← Previous
|
||||
</button>
|
||||
<span className="pagination-info">
|
||||
Page {pagination.page} of {Math.ceil(pagination.total / pagination.limit)}
|
||||
{' '}({pagination.total} total)
|
||||
</span>
|
||||
<button
|
||||
onClick={handleNextPage}
|
||||
disabled={!pagination.hasMore}
|
||||
className="pagination-button"
|
||||
>
|
||||
Next →
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="modal-footer">
|
||||
<button onClick={handleRefresh} className="button button-secondary">
|
||||
🔄 Refresh
|
||||
</button>
|
||||
<button onClick={onClose} className="button button-primary">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TopicsList;
|
||||
Reference in New Issue
Block a user