diff --git a/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs b/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs index b34dd59b..f577a41a 100644 --- a/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs +++ b/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs @@ -114,7 +114,8 @@ public class ClassroomHub : Hub } await Clients.Group(sessionId.ToString()) - .SendAsync("ParticipantLeft", _currentUser); + .SendAsync("ParticipantLeft", _currentUser.Id.ToString()); + _logger.LogInformation($"User {_currentUser} left class {sessionId}"); } diff --git a/ui/src/components/classroom/VideoPlayer.tsx b/ui/src/components/classroom/VideoPlayer.tsx index d5b2f1a2..793bb45e 100644 --- a/ui/src/components/classroom/VideoPlayer.tsx +++ b/ui/src/components/classroom/VideoPlayer.tsx @@ -1,7 +1,6 @@ import React, { useRef, useEffect } from 'react' import { FaMicrophoneSlash, FaVideoSlash } from 'react-icons/fa' -// VideoOff component replacement const VideoOff: React.FC<{ size?: number; className?: string }> = ({ size = 24, className = '', @@ -31,8 +30,19 @@ export const VideoPlayer: React.FC = ({ const videoRef = useRef(null) useEffect(() => { - if (videoRef.current && stream) { - videoRef.current.srcObject = stream + const videoEl = videoRef.current + if (!videoEl) return + + if (stream) { + videoEl.srcObject = stream + } else { + videoEl.srcObject = null // 🟢 ayrıldığında video siyaha düşer + } + + return () => { + if (videoEl) { + videoEl.srcObject = null // 🟢 cleanup + } } }, [stream]) diff --git a/ui/src/views/classroom/RoomDetail.tsx b/ui/src/views/classroom/RoomDetail.tsx index d2182997..5dd5c083 100644 --- a/ui/src/views/classroom/RoomDetail.tsx +++ b/ui/src/views/classroom/RoomDetail.tsx @@ -266,17 +266,15 @@ const RoomDetail: React.FC = () => { // Setup SignalR event handlers signalRServiceRef.current.setParticipantJoinHandler(async (userId, name) => { - // 🔑 Eğer gelen participant bizsek, listeye ekleme if (userId === user.id) return console.log(`Participant joined: ${name}`) - // Create WebRTC connection for new participant if (webRTCServiceRef.current) { webRTCServiceRef.current.createPeerConnection(userId) - // Eğer biz teacher isek offer oluşturup gönderelim - if (user.role === 'teacher') { + // ✅ Sadece teacher offer gönderecek + if (user.role === 'student') { const offer = await webRTCServiceRef.current.createOffer(userId) await signalRServiceRef.current?.sendOffer(classSession.id, userId, offer) } @@ -300,8 +298,12 @@ const RoomDetail: React.FC = () => { signalRServiceRef.current.setParticipantLeaveHandler((userId) => { console.log(`Participant left: ${userId}`) - setParticipants((prev) => prev.filter((p) => p.id !== userId)) + + // peer connection’ı kapat webRTCServiceRef.current?.closePeerConnection(userId) + + // katılımcıyı state’den sil + setParticipants((prev) => prev.filter((p) => p.id !== userId)) }) signalRServiceRef.current.setAttendanceUpdatedHandler((record) => {