Classroom video ve audio foreach
This commit is contained in:
parent
d8c4f39bd3
commit
277a5314cc
2 changed files with 36 additions and 86 deletions
|
|
@ -16,29 +16,24 @@ export class WebRTCService {
|
||||||
*/
|
*/
|
||||||
async initializeLocalStream(enableAudio: boolean, enableVideo: boolean): Promise<MediaStream> {
|
async initializeLocalStream(enableAudio: boolean, enableVideo: boolean): Promise<MediaStream> {
|
||||||
try {
|
try {
|
||||||
// Eğer kamera ve mikrofon kapalıysa, getUserMedia çağrısı yapmaya gerek yok
|
// her zaman hem ses hem video al
|
||||||
if (!enableAudio && !enableVideo) {
|
|
||||||
this.localStream = new MediaStream()
|
|
||||||
return this.localStream
|
|
||||||
}
|
|
||||||
|
|
||||||
this.localStream = await navigator.mediaDevices.getUserMedia({
|
this.localStream = await navigator.mediaDevices.getUserMedia({
|
||||||
video: enableVideo
|
video: {
|
||||||
? {
|
width: { ideal: 1280 },
|
||||||
width: { ideal: 1280 },
|
height: { ideal: 720 },
|
||||||
height: { ideal: 720 },
|
frameRate: { ideal: 30 },
|
||||||
frameRate: { ideal: 30 },
|
},
|
||||||
}
|
audio: {
|
||||||
: false,
|
echoCancellation: true,
|
||||||
audio: enableAudio
|
noiseSuppression: true,
|
||||||
? {
|
autoGainControl: true,
|
||||||
echoCancellation: true,
|
},
|
||||||
noiseSuppression: true,
|
|
||||||
autoGainControl: true,
|
|
||||||
}
|
|
||||||
: false,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// başlangıç ayarlarını uygula
|
||||||
|
this.localStream.getAudioTracks().forEach((track) => (track.enabled = enableAudio))
|
||||||
|
this.localStream.getVideoTracks().forEach((track) => (track.enabled = enableVideo))
|
||||||
|
|
||||||
return this.localStream
|
return this.localStream
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error accessing media devices:', error)
|
console.error('Error accessing media devices:', error)
|
||||||
|
|
|
||||||
|
|
@ -674,29 +674,6 @@ const RoomDetail: React.FC = () => {
|
||||||
setActiveSidePanel(activeSidePanel === panelType ? null : panelType)
|
setActiveSidePanel(activeSidePanel === panelType ? null : panelType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Demo: Simulate student joining
|
|
||||||
const simulateStudentJoin = async () => {
|
|
||||||
const studentNames = ['Ahmet Yılmaz', 'Fatma Demir', 'Mehmet Kaya', 'Ayşe Özkan', 'Ali Çelik']
|
|
||||||
const availableNames = studentNames.filter((name) => !participants.some((p) => p.name === name))
|
|
||||||
|
|
||||||
if (availableNames.length === 0) {
|
|
||||||
alert('Tüm demo öğrenciler zaten sınıfta!')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const randomName = availableNames[Math.floor(Math.random() * availableNames.length)]
|
|
||||||
const studentId = crypto.randomUUID() // Guid formatında id üretiliyor
|
|
||||||
|
|
||||||
// SignalR üzerinden joinClass çağrılıyor
|
|
||||||
await signalRServiceRef.current?.joinClass(
|
|
||||||
classSession.id,
|
|
||||||
studentId,
|
|
||||||
randomName,
|
|
||||||
false, // öğrenci
|
|
||||||
true, // aktif
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSettingsChange = (newSettings: Partial<ClassroomSettingsDto>) => {
|
const handleSettingsChange = (newSettings: Partial<ClassroomSettingsDto>) => {
|
||||||
setClassSettings((prev) => ({ ...prev, ...newSettings }))
|
setClassSettings((prev) => ({ ...prev, ...newSettings }))
|
||||||
}
|
}
|
||||||
|
|
@ -1040,15 +1017,17 @@ const RoomDetail: React.FC = () => {
|
||||||
setMobileMenuOpen(false)
|
setMobileMenuOpen(false)
|
||||||
setTimeout(() => toggleSidePanel('participants'), 200)
|
setTimeout(() => toggleSidePanel('participants'), 200)
|
||||||
}}
|
}}
|
||||||
className={`flex items-center space-x-2 p-3 rounded-lg transition-all text-base ${activeSidePanel === 'participants' ? 'bg-blue-100 text-blue-700' : 'hover:bg-gray-100 text-gray-700'}`}
|
className={`flex items-center space-x-2 p-3 rounded-lg transition-all text-base relative ${activeSidePanel === 'participants' ? 'bg-blue-100 text-blue-700' : 'hover:bg-gray-100 text-gray-700'}`}
|
||||||
>
|
>
|
||||||
<FaUserFriends />
|
<FaUserFriends />
|
||||||
<span>Katılımcılar</span>
|
<span>Katılımcılar</span>
|
||||||
<span className="absolute -top-1 -right-1 bg-blue-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
{/* Katılımcı adedi badge */}
|
||||||
{participants.length}
|
<span className="absolute top-2 right-3 bg-blue-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
||||||
|
{participants.length + 1}
|
||||||
</span>
|
</span>
|
||||||
|
{/* El kaldıran badge */}
|
||||||
{raisedHandsCount > 0 && (
|
{raisedHandsCount > 0 && (
|
||||||
<span className="absolute -top-1 -right-6 bg-yellow-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
<span className="absolute top-2 right-8 bg-yellow-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
||||||
{raisedHandsCount > 9 ? '9+' : raisedHandsCount}
|
{raisedHandsCount > 9 ? '9+' : raisedHandsCount}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1081,27 +1060,16 @@ const RoomDetail: React.FC = () => {
|
||||||
<FaWrench /> <span>Ayarlar</span>
|
<FaWrench /> <span>Ayarlar</span>
|
||||||
</button>
|
</button>
|
||||||
{user.role === 'teacher' && (
|
{user.role === 'teacher' && (
|
||||||
<>
|
<button
|
||||||
<button
|
onClick={() => {
|
||||||
onClick={() => {
|
setMobileMenuOpen(false)
|
||||||
setMobileMenuOpen(false)
|
setTimeout(() => handleMuteAll(), 200)
|
||||||
setTimeout(() => simulateStudentJoin(), 200)
|
}}
|
||||||
}}
|
className="flex items-center space-x-2 p-3 rounded-lg transition-all hover:bg-gray-100 text-gray-700 text-base"
|
||||||
className="flex items-center space-x-2 p-3 rounded-lg transition-all hover:bg-gray-100 text-gray-700 text-base"
|
>
|
||||||
>
|
{isAllMuted ? <FaVolumeUp /> : <FaVolumeMute />}{' '}
|
||||||
<FaUserPlus /> <span>Öğrenci Ekle (Demo)</span>
|
<span>{isAllMuted ? 'Hepsinin Sesini Aç' : 'Hepsini Sustur'}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setMobileMenuOpen(false)
|
|
||||||
setTimeout(() => handleMuteAll(), 200)
|
|
||||||
}}
|
|
||||||
className="flex items-center space-x-2 p-3 rounded-lg transition-all hover:bg-gray-100 text-gray-700 text-base"
|
|
||||||
>
|
|
||||||
{isAllMuted ? <FaVolumeUp /> : <FaVolumeMute />}{' '}
|
|
||||||
<span>{isAllMuted ? 'Hepsinin Sesini Aç' : 'Hepsini Sustur'}</span>
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
@ -1205,14 +1173,8 @@ const RoomDetail: React.FC = () => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right Side - Panel Controls & Participant Count */}
|
{/* Right Side - Panel Controls */}
|
||||||
<div className="flex items-center space-x-2 absolute right-0">
|
<div className="flex items-center space-x-2 absolute right-0">
|
||||||
{/* Participant Count */}
|
|
||||||
<div className="text-white text-sm mr-2">
|
|
||||||
<FaUsers size={14} className="inline mr-1" />
|
|
||||||
{participants.length + 1}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Fullscreen Toggle */}
|
{/* Fullscreen Toggle */}
|
||||||
<button
|
<button
|
||||||
onClick={toggleFullscreen}
|
onClick={toggleFullscreen}
|
||||||
|
|
@ -1262,7 +1224,7 @@ const RoomDetail: React.FC = () => {
|
||||||
{/* Participants */}
|
{/* Participants */}
|
||||||
<button
|
<button
|
||||||
onClick={() => toggleSidePanel('participants')}
|
onClick={() => toggleSidePanel('participants')}
|
||||||
className={`p-2 rounded-lg transition-all ${
|
className={`p-2 rounded-lg transition-all relative ${
|
||||||
activeSidePanel === 'participants'
|
activeSidePanel === 'participants'
|
||||||
? 'bg-blue-600 text-white'
|
? 'bg-blue-600 text-white'
|
||||||
: 'bg-gray-700 hover:bg-gray-600 text-white'
|
: 'bg-gray-700 hover:bg-gray-600 text-white'
|
||||||
|
|
@ -1270,9 +1232,11 @@ const RoomDetail: React.FC = () => {
|
||||||
title="Katılımcılar"
|
title="Katılımcılar"
|
||||||
>
|
>
|
||||||
<FaUserFriends size={14} />
|
<FaUserFriends size={14} />
|
||||||
|
{/* Katılımcı adedi badge */}
|
||||||
<span className="absolute -top-1 -right-1 bg-blue-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
<span className="absolute -top-1 -right-1 bg-blue-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
||||||
{participants.length}
|
{participants.length + 1}
|
||||||
</span>
|
</span>
|
||||||
|
{/* El kaldıran badge */}
|
||||||
{raisedHandsCount > 0 && (
|
{raisedHandsCount > 0 && (
|
||||||
<span className="absolute -top-1 -right-6 bg-yellow-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
<span className="absolute -top-1 -right-6 bg-yellow-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center text-[10px]">
|
||||||
{raisedHandsCount > 9 ? '9+' : raisedHandsCount}
|
{raisedHandsCount > 9 ? '9+' : raisedHandsCount}
|
||||||
|
|
@ -1304,15 +1268,6 @@ const RoomDetail: React.FC = () => {
|
||||||
>
|
>
|
||||||
{isAllMuted ? <FaVolumeUp size={14} /> : <FaVolumeMute size={14} />}
|
{isAllMuted ? <FaVolumeUp size={14} /> : <FaVolumeMute size={14} />}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Add Student Demo Button */}
|
|
||||||
<button
|
|
||||||
onClick={simulateStudentJoin}
|
|
||||||
className="p-2 rounded-lg transition-all bg-gray-700 hover:bg-gray-600 text-white"
|
|
||||||
title="Öğrenci Ekle (Demo)"
|
|
||||||
>
|
|
||||||
<FaUserPlus size={14} />
|
|
||||||
</button>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue