Ф2
This commit is contained in:
@@ -114,6 +114,7 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
|
|||||||
const [isVideoOff, setIsVideoOff] = useState(false);
|
const [isVideoOff, setIsVideoOff] = useState(false);
|
||||||
const [isScreenSharing, setIsScreenSharing] = useState(false);
|
const [isScreenSharing, setIsScreenSharing] = useState(false);
|
||||||
const [hasRemoteVideo, setHasRemoteVideo] = useState(false);
|
const [hasRemoteVideo, setHasRemoteVideo] = useState(false);
|
||||||
|
const hasRemoteVideoRef = useRef(false);
|
||||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
const [isMinimized, setIsMinimized] = useState(false);
|
const [isMinimized, setIsMinimized] = useState(false);
|
||||||
const [duration, setDuration] = useState(0);
|
const [duration, setDuration] = useState(0);
|
||||||
@@ -211,6 +212,23 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
|
|||||||
scheduleClose();
|
scheduleClose();
|
||||||
}, [cleanup, 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
|
// Setup common peer connection event handlers
|
||||||
const setupPeerHandlers = useCallback((pc: RTCPeerConnection) => {
|
const setupPeerHandlers = useCallback((pc: RTCPeerConnection) => {
|
||||||
pc.onicecandidate = (e) => {
|
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}`
|
`${t.label} state=${t.readyState} enabled=${t.enabled} muted=${t.muted}`
|
||||||
), '→ hasRemoteVideo:', hasVideo);
|
), '→ hasRemoteVideo:', hasVideo);
|
||||||
|
|
||||||
setHasRemoteVideo(hasVideo);
|
if (hasVideo !== hasRemoteVideoRef.current) {
|
||||||
|
hasRemoteVideoRef.current = hasVideo;
|
||||||
|
setHasRemoteVideo(hasVideo);
|
||||||
|
}
|
||||||
|
|
||||||
if (hasVideo && callType !== 'video') {
|
if (hasVideo && callType !== 'video') {
|
||||||
setCallType('video');
|
setCallType('video');
|
||||||
}
|
}
|
||||||
@@ -1597,7 +1619,7 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
|
|||||||
ref={remoteVideoRef}
|
ref={remoteVideoRef}
|
||||||
autoPlay
|
autoPlay
|
||||||
playsInline
|
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); }}
|
onContextMenu={(e) => { e.preventDefault(); setShowVolumeSlider(true); }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -1616,7 +1638,10 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
|
|||||||
</div>
|
</div>
|
||||||
<VideoOff size={48} className="text-zinc-500 mb-2" />
|
<VideoOff size={48} className="text-zinc-500 mb-2" />
|
||||||
<span className="text-xl text-white font-medium mb-1">{displayName}</span>
|
<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>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user