195 lines
9.4 KiB
PHP
195 lines
9.4 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/app.php';
|
|
|
|
$lesson_id = (int)($_GET['id'] ?? 0);
|
|
$db = db();
|
|
$stmt = $db->prepare("
|
|
SELECT l.*, c.name_en, c.name_ar, c.teacher_id
|
|
FROM course_live_lessons l
|
|
JOIN courses c ON l.course_id = c.id
|
|
WHERE l.id = ?
|
|
");
|
|
$stmt->execute([$lesson_id]);
|
|
$lesson = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$lesson) {
|
|
die("Lesson not found.");
|
|
}
|
|
|
|
// Check role
|
|
$is_teacher = false;
|
|
$is_student = false;
|
|
|
|
// Mock student and teacher IDs for the prototype based on current session
|
|
// In reality, this would be based on logged-in user session
|
|
$current_teacher_id = 1; // Used in teacher.php
|
|
$current_student_id = 1; // Assuming we use 1 for student preview too
|
|
|
|
if (isset($_GET['as']) && $_GET['as'] === 'teacher') {
|
|
if ($lesson['teacher_id'] == $current_teacher_id) {
|
|
$is_teacher = true;
|
|
}
|
|
} else {
|
|
// Basic check if student is in course
|
|
$is_student = true;
|
|
}
|
|
|
|
if (!$is_teacher && !$is_student) {
|
|
die("Unauthorized access.");
|
|
}
|
|
|
|
// Ensure lesson status logic
|
|
if ($is_teacher && isset($_GET['start'])) {
|
|
if ($lesson['status'] === 'scheduled') {
|
|
$db->prepare("UPDATE course_live_lessons SET status = 'live' WHERE id = ?")->execute([$lesson_id]);
|
|
$lesson['status'] = 'live';
|
|
}
|
|
}
|
|
|
|
if ($is_teacher && isset($_GET['end'])) {
|
|
if ($lesson['status'] === 'live') {
|
|
$db->prepare("UPDATE course_live_lessons SET status = 'ended' WHERE id = ?")->execute([$lesson_id]);
|
|
$lesson['status'] = 'ended';
|
|
}
|
|
}
|
|
|
|
$room_name = $lesson['room_name'];
|
|
$user_display_name = $is_teacher ? 'Teacher' : 'Student';
|
|
$has_meet = !empty($lesson['meet_url']);
|
|
|
|
render_head(
|
|
t('Live Lesson: ', 'درس مباشر: ') . t($lesson['title'], $lesson['title']),
|
|
t('Join the live streaming lesson.', 'انضم إلى بث الدرس المباشر.')
|
|
);
|
|
|
|
// We won't render normal nav here to maximize screen space for the lesson, or we render a simplified one
|
|
?>
|
|
<style>
|
|
body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; background: #000; }
|
|
.lesson-header {
|
|
background: #111;
|
|
color: #fff;
|
|
padding: 10px 20px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
z-index: 10;
|
|
position: relative;
|
|
}
|
|
.lesson-title { margin: 0; font-size: 1.2rem; font-weight: 500; }
|
|
#jitsi-container {
|
|
width: 100%;
|
|
height: calc(100vh - 56px); /* 56px is header height */
|
|
}
|
|
.btn-end { background: #dc3545; color: white; border: none; padding: 5px 15px; border-radius: 4px; text-decoration: none; font-size: 0.9rem; }
|
|
.btn-end:hover { background: #c82333; color: white; }
|
|
.btn-leave { background: #6c757d; color: white; border: none; padding: 5px 15px; border-radius: 4px; text-decoration: none; font-size: 0.9rem; }
|
|
.meet-btn { padding: 15px 30px; font-size: 1.2rem; border-radius: 50px; text-decoration: none; display: inline-flex; align-items: center; gap: 10px; font-weight: bold; background: #fff; color: #3c4043; transition: all 0.3s; }
|
|
.meet-btn:hover { background: #f8f9fa; transform: translateY(-2px); box-shadow: 0 4px 15px rgba(255,255,255,0.2); color: #1a73e8; }
|
|
.meet-btn svg { width: 24px; height: 24px; }
|
|
</style>
|
|
|
|
<div class="lesson-header">
|
|
<div class="d-flex align-items-center gap-3">
|
|
<h1 class="lesson-title">
|
|
<span class="badge bg-danger animate-pulse me-2">LIVE</span>
|
|
<?= h(t($lesson['name_en'], $lesson['name_ar'])) ?> - <?= h($lesson['title']) ?>
|
|
</h1>
|
|
</div>
|
|
<div>
|
|
<?php if ($is_teacher): ?>
|
|
<?php if ($lesson['status'] !== 'ended'): ?>
|
|
<a href="?id=<?= $lesson_id ?>&as=teacher&end=1" class="btn-end" onclick="return confirm('<?= h(t('End the live lesson for everyone?', 'إنهاء الدرس المباشر للجميع؟')) ?>');"><?= t('End Lesson', 'إنهاء الدرس') ?></a>
|
|
<?php else: ?>
|
|
<span class="badge bg-secondary"><?= t('Ended', 'منتهي') ?></span>
|
|
<?php endif; ?>
|
|
<a href="teacher.php?action=live&course_id=<?= $lesson['course_id'] ?>" class="btn-leave ms-2"><?= t('Back to Dashboard', 'العودة للوحة') ?></a>
|
|
<?php else: ?>
|
|
<a href="dashboard.php" class="btn-leave"><?= t('Leave', 'مغادرة') ?></a>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($lesson['status'] === 'scheduled'): ?>
|
|
<div class="d-flex align-items-center justify-content-center text-white" style="height: calc(100vh - 56px);">
|
|
<div class="text-center">
|
|
<h2 class="mb-3"><?= t('Lesson hasn\'t started yet.', 'لم يبدأ الدرس بعد.') ?></h2>
|
|
<p class="text-secondary"><?= t('Scheduled for: ', 'مجدول في: ') ?> <?= date('Y-m-d H:i', strtotime($lesson['scheduled_at'])) ?></p>
|
|
<?php if ($is_teacher): ?>
|
|
<a href="?id=<?= $lesson_id ?>&as=teacher&start=1" class="btn btn-primary btn-lg mt-3"><?= t('Start Live Streaming Now', 'ابدأ البث المباشر الآن') ?></a>
|
|
<?php else: ?>
|
|
<button class="btn btn-outline-light mt-3" onclick="location.reload()"><?= t('Refresh', 'تحديث') ?></button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php elseif ($lesson['status'] === 'ended'): ?>
|
|
<div class="d-flex align-items-center justify-content-center text-white" style="height: calc(100vh - 56px);">
|
|
<div class="text-center">
|
|
<h2 class="mb-3"><?= t('This live lesson has ended.', 'انتهى هذا الدرس المباشر.') ?></h2>
|
|
<p class="text-secondary"><?= t('Thank you for participating.', 'شكراً لمشاركتك.') ?></p>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<?php if ($has_meet): ?>
|
|
<!-- Google Meet Gateway -->
|
|
<div class="d-flex align-items-center justify-content-center text-white" style="height: calc(100vh - 56px);">
|
|
<div class="text-center">
|
|
<div class="mb-4">
|
|
<svg viewBox="0 0 24 24" width="80" height="80">
|
|
<path fill="#ffffff" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9V8h2v8zm4 0h-2V8h2v8z"/>
|
|
</svg>
|
|
</div>
|
|
<h2 class="mb-4"><?= t('This lesson is hosted on Google Meet.', 'هذا الدرس يُبث عبر Google Meet.') ?></h2>
|
|
<p class="text-secondary mb-5"><?= t('Click the button below to join the session in a new tab. You must be logged into your Google account.', 'انقر على الزر أدناه للانضمام إلى الجلسة في علامة تبويب جديدة. يجب أن تكون مسجلاً الدخول إلى حساب Google الخاص بك.') ?></p>
|
|
<a href="<?= h($lesson['meet_url']) ?>" target="_blank" class="meet-btn">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-video"><polygon points="23 7 16 12 23 17 23 7"></polygon><rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect></svg>
|
|
<?= t('Join Google Meet', 'انضم إلى Google Meet') ?>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<!-- Jitsi Meet iframe container -->
|
|
<div id="jitsi-container"></div>
|
|
<script src="https://meet.jit.si/external_api.js"></script>
|
|
<script>
|
|
window.onload = () => {
|
|
const domain = 'meet.jit.si';
|
|
const options = {
|
|
roomName: '<?= htmlspecialchars(rawurlencode($room_name)) ?>',
|
|
width: '100%',
|
|
height: '100%',
|
|
parentNode: document.querySelector('#jitsi-container'),
|
|
userInfo: {
|
|
displayName: '<?= htmlspecialchars($user_display_name) ?>'
|
|
},
|
|
configOverwrite: {
|
|
prejoinPageEnabled: false,
|
|
startWithAudioMuted: <?= $is_teacher ? 'false' : 'true' ?>,
|
|
startWithVideoMuted: <?= $is_teacher ? 'false' : 'true' ?>,
|
|
disableDeepLinking: true
|
|
},
|
|
interfaceConfigOverwrite: {
|
|
SHOW_JITSI_WATERMARK: false,
|
|
SHOW_WATERMARK_FOR_GUESTS: false,
|
|
TOOLBAR_BUTTONS: [
|
|
'microphone', 'camera', 'closedcaptions', 'desktop', 'fullscreen',
|
|
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
|
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
|
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
|
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone',
|
|
'security'
|
|
]
|
|
}
|
|
};
|
|
const api = new JitsiMeetExternalAPI(domain, options);
|
|
|
|
<?php if ($is_teacher): ?>
|
|
// Any specific teacher controls
|
|
api.executeCommand('subject', '<?= h(t($lesson['name_en'], $lesson['name_ar'])) ?> - <?= h($lesson['title']) ?>');
|
|
<?php endif; ?>
|
|
};
|
|
</script>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</body>
|
|
</html>
|