This commit is contained in:
Халимов Рустам
2026-03-11 17:15:23 +03:00
parent 3cf56b62ca
commit 8c7ca3b869

View File

@@ -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
</div>
<VideoOff size={48} className="text-zinc-500 mb-2" />
<span className="text-xl text-white font-medium mb-1">{displayName}</span>
<span className="text-sm text-zinc-500 animate-pulse">Соединение...</span>
<div className="flex items-center gap-2 text-zinc-500">
<div className="w-2 h-2 rounded-full bg-vortex-500 animate-pulse" />
<span className="text-sm animate-pulse">Ожидание потока...</span>
</div>
</div>
)}