diff --git a/apps/web/src/components/CallModal.tsx b/apps/web/src/components/CallModal.tsx index 660076d..ec06e13 100644 --- a/apps/web/src/components/CallModal.tsx +++ b/apps/web/src/components/CallModal.tsx @@ -114,6 +114,7 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi const [isVideoOff, setIsVideoOff] = useState(false); const [isScreenSharing, setIsScreenSharing] = useState(false); const [hasRemoteVideo, setHasRemoteVideo] = useState(false); + const hasRemoteVideoRef = useRef(false); const [isFullscreen, setIsFullscreen] = useState(false); const [isMinimized, setIsMinimized] = useState(false); const [duration, setDuration] = useState(0); @@ -211,6 +212,23 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi scheduleClose(); }, [cleanup, scheduleClose]); + // Ensure remote stream is bound to video element when it becomes available + useEffect(() => { + if (hasRemoteVideo && remoteVideoRef.current && remoteStreamRef.current) { + const video = remoteVideoRef.current; + const stream = remoteStreamRef.current; + + if (video.srcObject !== stream) { + console.log('[WebRTC] Effect: Binding stream to video element'); + video.srcObject = stream; + video.muted = false; + video.play().catch(e => { + if (e.name === 'NotAllowedError') setNeedsInteraction(true); + }); + } + } + }, [hasRemoteVideo]); + // Setup common peer connection event handlers const setupPeerHandlers = useCallback((pc: RTCPeerConnection) => { pc.onicecandidate = (e) => { @@ -255,7 +273,11 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi `${t.label} state=${t.readyState} enabled=${t.enabled} muted=${t.muted}` ), '→ hasRemoteVideo:', hasVideo); - setHasRemoteVideo(hasVideo); + if (hasVideo !== hasRemoteVideoRef.current) { + hasRemoteVideoRef.current = hasVideo; + setHasRemoteVideo(hasVideo); + } + if (hasVideo && callType !== 'video') { setCallType('video'); } @@ -1597,7 +1619,7 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi ref={remoteVideoRef} autoPlay playsInline - className="w-full h-full object-contain" + className={`w-full h-full object-contain transition-opacity duration-300 ${hasRemoteVideo ? 'opacity-100' : 'opacity-0'}`} onContextMenu={(e) => { e.preventDefault(); setShowVolumeSlider(true); }} /> @@ -1616,7 +1638,10 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi {displayName} - Соединение... +
+
+ Ожидание потока... +
)}