diff --git a/src/components/ExploreContainer.css b/src/components/ExploreContainer.css index 0cfddbf..0d4ebac 100644 --- a/src/components/ExploreContainer.css +++ b/src/components/ExploreContainer.css @@ -2,26 +2,42 @@ display: flex; flex-direction: column; align-items: center; - justify-content: space-around; /* Распределение элементов с равным отступом */ - height: 100vh; /* Высота на весь экран для центрирования */ + justify-content: space-around; + height: 100vh; text-align: center; } .peer-id-container { margin-bottom: 10px; + display: flex; + align-items: center; } .peer-id-text { font-size: 16px; color: #fff; + margin-right: 10px; } .copy-button { background: none; border: none; - color: #007aff; cursor: pointer; + padding: 0; +} + +.copy-notification { + position: fixed; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + background-color: #4caf50; + color: white; + padding: 10px 20px; + border-radius: 5px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); font-size: 16px; + z-index: 1000; } .input-container { @@ -30,7 +46,7 @@ justify-content: center; margin-bottom: 10px; width: 100%; - max-width: 400px; /* Ограничение ширины для компактности */ + max-width: 400px; } .call-info-container { @@ -43,13 +59,13 @@ .call-info-text { font-size: 18px; - margin-bottom: 5px; /* Небольшой отступ снизу для Peer ID */ + margin-bottom: 5px; color: #ffffff; } .call-duration-text { font-size: 18px; - margin-bottom: 15px; /* Отступ снизу для времени */ + margin-bottom: 15px; color: #ffffff; } @@ -66,7 +82,7 @@ } .custom-hang-up-button:hover svg { - transform: scale(1.1); /* Увеличение кнопки при наведении */ + transform: scale(1.1); } .call-button { @@ -76,7 +92,14 @@ cursor: pointer; font-size: 24px; margin-left: 10px; - padding: 10px; /* Увеличение кнопки для удобства */ + padding: 15px; + border-radius: 50%; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + transition: background 0.3s ease; +} + +.call-button:hover { + background: #005bb5; } .panel-optimizer { @@ -89,11 +112,17 @@ display: flex; align-items: center; justify-content: center; - height: 100vh; /* Центрирование всего контента по высоте экрана */ + height: 100vh; } .drone-gif { - width: 300px; /* Задайте нужный размер */ + width: 300px; height: auto; margin-bottom: 20px; +} + +.screen-off { + background-color: #000; + color: #000; + opacity: 0; } \ No newline at end of file diff --git a/src/components/ExploreContainer.tsx b/src/components/ExploreContainer.tsx index dd7807b..17457df 100644 --- a/src/components/ExploreContainer.tsx +++ b/src/components/ExploreContainer.tsx @@ -18,6 +18,10 @@ const ExploreContainer: React.FC = () => { const [callDuration, setCallDuration] = useState(0); const [callInterval, setCallInterval] = useState(null); const [currentCallId, setCurrentCallId] = useState(null); + const [connectionSpeed, setConnectionSpeed] = useState("0 kbps"); + const [activeCall, setActiveCall] = useState(null); + const [isScreenOff, setIsScreenOff] = useState(false); + const [isCopied, setIsCopied] = useState(false); useEffect(() => { const initializePeer = () => { @@ -41,9 +45,28 @@ const ExploreContainer: React.FC = () => { return cleanup; }, []); + useEffect(() => { + const handleProximity = (event: any) => { + if (event.value) { + // Если телефон близко к лицу, гасим экран + setIsScreenOff(true); + } else { + // Если телефон не близко, включаем экран + setIsScreenOff(false); + } + }; + + window.addEventListener('deviceproximity', handleProximity); + + return () => { + window.removeEventListener('deviceproximity', handleProximity); + }; + }, []); + const handleIncomingCall = useCallback((call: MediaConnection) => { console.log('Получен входящий звонок'); setCurrentCallId(call.peer); + setActiveCall(call); navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { setLocalStream(stream); call.answer(stream); @@ -52,6 +75,10 @@ const ExploreContainer: React.FC = () => { playAudio(remoteStream); startCallTimer(); setIsCallActive(true); + monitorConnectionSpeed(call); + }); + call.on('close', () => { + endCall(); }); }).catch((err) => { console.error('Не удалось получить локальный поток для ответа', err); @@ -65,6 +92,7 @@ const ExploreContainer: React.FC = () => { navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { setLocalStream(stream); const call = peer.call(callString, stream); + setActiveCall(call); setCurrentCallId(callString); call.on('stream', (remoteStream: MediaStream) => { console.log('Получен удалённый поток во время вызова'); @@ -72,6 +100,10 @@ const ExploreContainer: React.FC = () => { setIsLoading(false); startCallTimer(); setIsCallActive(true); + monitorConnectionSpeed(call); + }); + call.on('close', () => { + endCall(); }); }).catch((err) => { console.error('Не удалось получить локальный поток', err); @@ -86,6 +118,9 @@ const ExploreContainer: React.FC = () => { if (localStream) { localStream.getTracks().forEach(track => track.stop()); } + if (activeCall) { + activeCall.close(); + } setIsCallActive(false); setIsEnable(true); if (callInterval) { @@ -93,7 +128,8 @@ const ExploreContainer: React.FC = () => { } setCallDuration(0); setCurrentCallId(null); - }, [localStream, callInterval]); + setConnectionSpeed("0 kbps"); + }, [localStream, callInterval, activeCall]); const startCallTimer = useCallback(() => { const interval = setInterval(() => { @@ -112,11 +148,31 @@ const ExploreContainer: React.FC = () => { }); }, []); + const monitorConnectionSpeed = useCallback((call: MediaConnection) => { + call.on('iceStateChanged', () => { + if (call.peerConnection) { + const stats = call.peerConnection.getStats(); + stats.then((report) => { + report.forEach((result) => { + if (result.type === 'candidate-pair' && result.state === 'succeeded') { + const speed = `${Math.round(result.currentRoundTripTime * 1000)} kbps`; + setConnectionSpeed(speed); + } + }); + }); + } + }); + }, []); + const copyPeerId = useCallback(() => { if (connectionInfo) { navigator.clipboard.writeText(connectionInfo) .then(() => { console.log('Peer ID скопирован в буфер обмена'); + setIsCopied(true); + setTimeout(() => { + setIsCopied(false); + }, 2000); }) .catch((err) => { console.error('Не удалось скопировать Peer ID', err); @@ -126,12 +182,18 @@ const ExploreContainer: React.FC = () => { return ( <> - +
Ваш Peer ID: {connectionInfo} - +
+ {isCopied &&
Peer ID скопирован
}
{ Monkey with Drone Peer ID: {currentCallId} {Math.floor(callDuration / 60)}:{callDuration % 60} + Скорость соединения: {connectionSpeed}