Compare commits
No commits in common. "8ebeeb4bc82055195373792a9d95056141cba665" and "b5e1d5ddf3d33fbcb1b39ff659a3bcfeb4fb406e" have entirely different histories.
8ebeeb4bc8
...
b5e1d5ddf3
@ -2,42 +2,26 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-around;
|
justify-content: space-around; /* Распределение элементов с равным отступом */
|
||||||
height: 100vh;
|
height: 100vh; /* Высота на весь экран для центрирования */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.peer-id-container {
|
.peer-id-container {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.peer-id-text {
|
.peer-id-text {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-button {
|
.copy-button {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
color: #007aff;
|
||||||
cursor: pointer;
|
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;
|
font-size: 16px;
|
||||||
z-index: 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-container {
|
.input-container {
|
||||||
@ -46,7 +30,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 400px;
|
max-width: 400px; /* Ограничение ширины для компактности */
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-info-container {
|
.call-info-container {
|
||||||
@ -59,13 +43,13 @@
|
|||||||
|
|
||||||
.call-info-text {
|
.call-info-text {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px; /* Небольшой отступ снизу для Peer ID */
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-duration-text {
|
.call-duration-text {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px; /* Отступ снизу для времени */
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +66,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.custom-hang-up-button:hover svg {
|
.custom-hang-up-button:hover svg {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1); /* Увеличение кнопки при наведении */
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-button {
|
.call-button {
|
||||||
@ -92,14 +76,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
padding: 15px;
|
padding: 10px; /* Увеличение кнопки для удобства */
|
||||||
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 {
|
.panel-optimizer {
|
||||||
@ -112,17 +89,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100vh;
|
height: 100vh; /* Центрирование всего контента по высоте экрана */
|
||||||
}
|
}
|
||||||
|
|
||||||
.drone-gif {
|
.drone-gif {
|
||||||
width: 300px;
|
width: 300px; /* Задайте нужный размер */
|
||||||
height: auto;
|
height: auto;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
|
||||||
|
|
||||||
.screen-off {
|
|
||||||
background-color: #000;
|
|
||||||
color: #000;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
}
|
@ -18,10 +18,6 @@ const ExploreContainer: React.FC = () => {
|
|||||||
const [callDuration, setCallDuration] = useState<number>(0);
|
const [callDuration, setCallDuration] = useState<number>(0);
|
||||||
const [callInterval, setCallInterval] = useState<NodeJS.Timeout | null>(null);
|
const [callInterval, setCallInterval] = useState<NodeJS.Timeout | null>(null);
|
||||||
const [currentCallId, setCurrentCallId] = useState<string | null>(null);
|
const [currentCallId, setCurrentCallId] = useState<string | null>(null);
|
||||||
const [connectionSpeed, setConnectionSpeed] = useState<string>("0 kbps");
|
|
||||||
const [activeCall, setActiveCall] = useState<MediaConnection | null>(null);
|
|
||||||
const [isScreenOff, setIsScreenOff] = useState(false);
|
|
||||||
const [isCopied, setIsCopied] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initializePeer = () => {
|
const initializePeer = () => {
|
||||||
@ -45,28 +41,9 @@ const ExploreContainer: React.FC = () => {
|
|||||||
return cleanup;
|
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) => {
|
const handleIncomingCall = useCallback((call: MediaConnection) => {
|
||||||
console.log('Получен входящий звонок');
|
console.log('Получен входящий звонок');
|
||||||
setCurrentCallId(call.peer);
|
setCurrentCallId(call.peer);
|
||||||
setActiveCall(call);
|
|
||||||
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
||||||
setLocalStream(stream);
|
setLocalStream(stream);
|
||||||
call.answer(stream);
|
call.answer(stream);
|
||||||
@ -75,10 +52,6 @@ const ExploreContainer: React.FC = () => {
|
|||||||
playAudio(remoteStream);
|
playAudio(remoteStream);
|
||||||
startCallTimer();
|
startCallTimer();
|
||||||
setIsCallActive(true);
|
setIsCallActive(true);
|
||||||
monitorConnectionSpeed(call);
|
|
||||||
});
|
|
||||||
call.on('close', () => {
|
|
||||||
endCall();
|
|
||||||
});
|
});
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.error('Не удалось получить локальный поток для ответа', err);
|
console.error('Не удалось получить локальный поток для ответа', err);
|
||||||
@ -92,7 +65,6 @@ const ExploreContainer: React.FC = () => {
|
|||||||
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
||||||
setLocalStream(stream);
|
setLocalStream(stream);
|
||||||
const call = peer.call(callString, stream);
|
const call = peer.call(callString, stream);
|
||||||
setActiveCall(call);
|
|
||||||
setCurrentCallId(callString);
|
setCurrentCallId(callString);
|
||||||
call.on('stream', (remoteStream: MediaStream) => {
|
call.on('stream', (remoteStream: MediaStream) => {
|
||||||
console.log('Получен удалённый поток во время вызова');
|
console.log('Получен удалённый поток во время вызова');
|
||||||
@ -100,10 +72,6 @@ const ExploreContainer: React.FC = () => {
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
startCallTimer();
|
startCallTimer();
|
||||||
setIsCallActive(true);
|
setIsCallActive(true);
|
||||||
monitorConnectionSpeed(call);
|
|
||||||
});
|
|
||||||
call.on('close', () => {
|
|
||||||
endCall();
|
|
||||||
});
|
});
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.error('Не удалось получить локальный поток', err);
|
console.error('Не удалось получить локальный поток', err);
|
||||||
@ -118,9 +86,6 @@ const ExploreContainer: React.FC = () => {
|
|||||||
if (localStream) {
|
if (localStream) {
|
||||||
localStream.getTracks().forEach(track => track.stop());
|
localStream.getTracks().forEach(track => track.stop());
|
||||||
}
|
}
|
||||||
if (activeCall) {
|
|
||||||
activeCall.close();
|
|
||||||
}
|
|
||||||
setIsCallActive(false);
|
setIsCallActive(false);
|
||||||
setIsEnable(true);
|
setIsEnable(true);
|
||||||
if (callInterval) {
|
if (callInterval) {
|
||||||
@ -128,8 +93,7 @@ const ExploreContainer: React.FC = () => {
|
|||||||
}
|
}
|
||||||
setCallDuration(0);
|
setCallDuration(0);
|
||||||
setCurrentCallId(null);
|
setCurrentCallId(null);
|
||||||
setConnectionSpeed("0 kbps");
|
}, [localStream, callInterval]);
|
||||||
}, [localStream, callInterval, activeCall]);
|
|
||||||
|
|
||||||
const startCallTimer = useCallback(() => {
|
const startCallTimer = useCallback(() => {
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
@ -148,31 +112,11 @@ 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(() => {
|
const copyPeerId = useCallback(() => {
|
||||||
if (connectionInfo) {
|
if (connectionInfo) {
|
||||||
navigator.clipboard.writeText(connectionInfo)
|
navigator.clipboard.writeText(connectionInfo)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('Peer ID скопирован в буфер обмена');
|
console.log('Peer ID скопирован в буфер обмена');
|
||||||
setIsCopied(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
setIsCopied(false);
|
|
||||||
}, 2000);
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Не удалось скопировать Peer ID', err);
|
console.error('Не удалось скопировать Peer ID', err);
|
||||||
@ -182,18 +126,12 @@ const ExploreContainer: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IonContent fullscreen={true} className={`ion-padding ${isScreenOff ? 'screen-off' : ''}`}>
|
<IonContent fullscreen={true} className="ion-padding">
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div className="peer-id-container">
|
<div className="peer-id-container">
|
||||||
<IonText className="peer-id-text">Ваш Peer ID: {connectionInfo}</IonText>
|
<IonText className="peer-id-text">Ваш Peer ID: {connectionInfo}</IonText>
|
||||||
<button className="copy-button" onClick={copyPeerId}>
|
<button className="copy-button" onClick={copyPeerId}>Копировать</button>
|
||||||
<svg width="51" height="51" fill="none" stroke="#34554a" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M19.078 6H8.672A2.672 2.672 0 0 0 6 8.672v10.406a2.672 2.672 0 0 0 2.672 2.672h10.406a2.672 2.672 0 0 0 2.672-2.672V8.672A2.672 2.672 0 0 0 19.078 6Z"></path>
|
|
||||||
<path d="M17.977 6 18 4.875a2.633 2.633 0 0 0-2.625-2.625H5.25a3.009 3.009 0 0 0-3 3v10.125A2.633 2.633 0 0 0 4.875 18H6"></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
{isCopied && <div className="copy-notification">Peer ID скопирован</div>}
|
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<InputContainer
|
<InputContainer
|
||||||
callString={callString}
|
callString={callString}
|
||||||
@ -214,7 +152,6 @@ const ExploreContainer: React.FC = () => {
|
|||||||
<img src="/monkey-monkey-with-drone.gif" alt="Monkey with Drone" className="drone-gif" />
|
<img src="/monkey-monkey-with-drone.gif" alt="Monkey with Drone" className="drone-gif" />
|
||||||
<IonText className="call-info-text">Peer ID: {currentCallId}</IonText>
|
<IonText className="call-info-text">Peer ID: {currentCallId}</IonText>
|
||||||
<IonText className="call-duration-text">{Math.floor(callDuration / 60)}:{callDuration % 60}</IonText>
|
<IonText className="call-duration-text">{Math.floor(callDuration / 60)}:{callDuration % 60}</IonText>
|
||||||
<IonText className="connection-speed-text">Скорость соединения: {connectionSpeed}</IonText>
|
|
||||||
<button onClick={endCall} className="custom-hang-up-button">
|
<button onClick={endCall} className="custom-hang-up-button">
|
||||||
<svg width="51" height="51" fill="#cd1818" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg width="51" height="51" fill="#cd1818" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M18.327 22.5c-.915 0-2.2-.331-4.125-1.407-2.34-1.312-4.15-2.524-6.478-4.846-2.245-2.243-3.337-3.695-4.865-6.476C1.132 6.63 1.426 4.984 1.755 4.28c.392-.842.97-1.345 1.718-1.844a8.263 8.263 0 0 1 1.343-.712l.13-.057c.231-.105.583-.263 1.028-.094.297.112.562.34.978.75.852.84 2.015 2.71 2.445 3.63.288.619.479 1.028.48 1.486 0 .537-.27.95-.598 1.397l-.182.242c-.356.469-.435.604-.383.846.104.486.884 1.933 2.165 3.212 1.281 1.278 2.686 2.008 3.174 2.112.253.054.39-.027.875-.397.069-.053.14-.107.215-.162.5-.372.894-.635 1.418-.635h.003c.456 0 .847.198 1.493.524.844.426 2.771 1.575 3.616 2.427.412.415.64.679.753.976.169.447.01.797-.094 1.031l-.057.129a8.27 8.27 0 0 1-.716 1.34c-.499.745-1.004 1.322-1.846 1.714a3.16 3.16 0 0 1-1.386.304Z"></path>
|
<path d="M18.327 22.5c-.915 0-2.2-.331-4.125-1.407-2.34-1.312-4.15-2.524-6.478-4.846-2.245-2.243-3.337-3.695-4.865-6.476C1.132 6.63 1.426 4.984 1.755 4.28c.392-.842.97-1.345 1.718-1.844a8.263 8.263 0 0 1 1.343-.712l.13-.057c.231-.105.583-.263 1.028-.094.297.112.562.34.978.75.852.84 2.015 2.71 2.445 3.63.288.619.479 1.028.48 1.486 0 .537-.27.95-.598 1.397l-.182.242c-.356.469-.435.604-.383.846.104.486.884 1.933 2.165 3.212 1.281 1.278 2.686 2.008 3.174 2.112.253.054.39-.027.875-.397.069-.053.14-.107.215-.162.5-.372.894-.635 1.418-.635h.003c.456 0 .847.198 1.493.524.844.426 2.771 1.575 3.616 2.427.412.415.64.679.753.976.169.447.01.797-.094 1.031l-.057.129a8.27 8.27 0 0 1-.716 1.34c-.499.745-1.004 1.322-1.846 1.714a3.16 3.16 0 0 1-1.386.304Z"></path>
|
||||||
|
Loading…
Reference in New Issue
Block a user