From 3587446042bbf294a5bc1c516c5184721587d81b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96zt=C3=BCrk?= Date: Sat, 30 Aug 2025 01:27:46 +0300 Subject: [PATCH] =?UTF-8?q?Classroom=20Videoplayer=20k=C4=B1s=C4=B1mlar?= =?UTF-8?q?=C4=B1=20d=C3=BCzeltildi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Classroom/ClassroomHub.cs | 4 +- ui/src/services/classroom/signalr.ts | 8 +- ui/src/views/classroom/RoomDetail.tsx | 85 ++++++++++++------- 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs b/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs index 4c9c59e6..c0b88149 100644 --- a/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs +++ b/api/src/Kurs.Platform.HttpApi.Host/Classroom/ClassroomHub.cs @@ -97,11 +97,11 @@ public class ClassroomHub : Hub await Clients.Caller.SendAsync("ExistingParticipants", others); + // 🔑 Grup üyelerine yeni katılanı öğretmen bilgisiyle bildir await Clients.Group(sessionId.ToString()) - .SendAsync("ParticipantJoined", userId, userName); + .SendAsync("ParticipantJoined", userId, userName, isTeacher); } - [HubMethodName("LeaveClass")] public async Task LeaveClassAsync(Guid sessionId) { diff --git a/ui/src/services/classroom/signalr.ts b/ui/src/services/classroom/signalr.ts index b75e0803..26713c9e 100644 --- a/ui/src/services/classroom/signalr.ts +++ b/ui/src/services/classroom/signalr.ts @@ -6,7 +6,7 @@ export class SignalRService { private connection!: signalR.HubConnection private isConnected: boolean = false private onAttendanceUpdate?: (record: ClassroomAttendanceDto) => void - private onParticipantJoined?: (userId: string, name: string) => void + private onParticipantJoined?: (userId: string, name: string, isTeacher: boolean) => void private onParticipantLeft?: (userId: string) => void private onChatMessage?: (message: ClassroomChatDto) => void private onParticipantMuted?: (userId: string, isMuted: boolean) => void @@ -39,8 +39,8 @@ export class SignalRService { this.onAttendanceUpdate?.(record) }) - this.connection.on('ParticipantJoined', (userId: string, name: string) => { - this.onParticipantJoined?.(userId, name) + this.connection.on('ParticipantJoined', (userId: string, name: string, isTeacher: boolean) => { + this.onParticipantJoined?.(userId, name, isTeacher) }) this.connection.on('ParticipantLeft', (userId: string) => { @@ -391,7 +391,7 @@ export class SignalRService { this.onAttendanceUpdate = callback } - setParticipantJoinHandler(callback: (userId: string, name: string) => void) { + setParticipantJoinHandler(callback: (userId: string, name: string, isTeacher: boolean) => void) { this.onParticipantJoined = callback } diff --git a/ui/src/views/classroom/RoomDetail.tsx b/ui/src/views/classroom/RoomDetail.tsx index 51bf638c..ad801ff7 100644 --- a/ui/src/views/classroom/RoomDetail.tsx +++ b/ui/src/views/classroom/RoomDetail.tsx @@ -265,48 +265,67 @@ const RoomDetail: React.FC = () => { }) // Setup SignalR event handlers - signalRServiceRef.current.setParticipantJoinHandler(async (userId, name) => { - if (userId === user.id) return + signalRServiceRef.current.setParticipantJoinHandler( + async (userId: string, name: string, isTeacher: boolean) => { + if (userId === user.id) return - console.log(`Participant joined: ${name}`) + console.log(`Participant joined: ${name}, isTeacher: ${isTeacher}`) - if (webRTCServiceRef.current) { - webRTCServiceRef.current.createPeerConnection(userId) + if (webRTCServiceRef.current) { + await webRTCServiceRef.current.createPeerConnection(userId) - // ✅ Sadece teacher offer gönderecek - if (user.role === 'teacher') { - const offer = await webRTCServiceRef.current.createOffer(userId) - await signalRServiceRef.current?.sendOffer(classSession.id, userId, offer) + // 🔑 Eğer ben öğrenci isem, öğretmen geldiğinde ben offer göndermeliyim + if (user.role === 'student' && isTeacher) { + const offer = await webRTCServiceRef.current.createOffer(userId) + await signalRServiceRef.current?.sendOffer(classSession.id, userId, offer) + } + + // 🔑 Eğer ben öğretmensem, öğrenci geldiğinde ben offer göndermeliyim + if (user.role === 'teacher' && !isTeacher) { + const offer = await webRTCServiceRef.current.createOffer(userId) + await signalRServiceRef.current?.sendOffer(classSession.id, userId, offer) + } } - } - setParticipants((prev) => { - const existing = prev.find((p) => p.id === userId) - if (existing) return prev - return [ - ...prev, - { - id: userId, - name, - isTeacher: false, - isAudioMuted: classSettings.autoMuteNewParticipants, - isVideoMuted: classSettings.defaultCameraState === 'off', - }, - ] - }) - }) + setParticipants((prev) => { + const existing = prev.find((p) => p.id === userId) + if (existing) return prev + return [ + ...prev, + { + id: userId, + name, + isTeacher, // ✅ artık backend’den gelen değer + isAudioMuted: classSettings.autoMuteNewParticipants, + isVideoMuted: classSettings.defaultCameraState === 'off', + }, + ] + }) + }, + ) + // Existing participants handler signalRServiceRef.current.setExistingParticipantsHandler(async (existing) => { console.log('Existing participants:', existing) if (webRTCServiceRef.current) { for (const p of existing) { - await webRTCServiceRef.current.createPeerConnection(p.userId) + const id = p.userId || p.UserId + const name = p.userName || p.UserName + const isTeacher = p.isTeacher ?? p.IsTeacher - // ✅ Eğer ben öğrenci isem → mevcut öğretmene offer gönderirim - if (user.role === 'student' && p.isTeacher) { - const offer = await webRTCServiceRef.current.createOffer(p.userId) - await signalRServiceRef.current?.sendOffer(classSession.id, p.userId, offer) + await webRTCServiceRef.current.createPeerConnection(id) + + // öğrenci → öğretmen + if (user.role === 'student' && isTeacher) { + const offer = await webRTCServiceRef.current.createOffer(id) + await signalRServiceRef.current?.sendOffer(classSession.id, id, offer) + } + + // öğretmen → öğrenci + if (user.role === 'teacher' && !isTeacher) { + const offer = await webRTCServiceRef.current.createOffer(id) + await signalRServiceRef.current?.sendOffer(classSession.id, id, offer) } } } @@ -314,9 +333,9 @@ const RoomDetail: React.FC = () => { setParticipants((prev) => [ ...prev, ...existing.map((p) => ({ - id: p.userId, - name: p.userName, - isTeacher: p.isTeacher, + id: p.userId || p.UserId, + name: p.userName || p.UserName, + isTeacher: p.isTeacher ?? p.IsTeacher, isAudioMuted: classSettings.autoMuteNewParticipants, isVideoMuted: classSettings.defaultCameraState === 'off', })),