feat(dashboard): статус «идёт онлайн-урок» с присоединением
На дашборде ученика/учителя — баннер активной classroom-сессии: заголовок урока, для учителя «N онлайн», для ученика «Присоединиться/Вернуться», ссылка на /classroom (там сессия подхватывается автоматически). Данные — LS.crGetMySession (учитель → своя сессия, ученик → сессия его класса/приглашения). Нет активной сессии → баннер скрыт. Доска работает по WebSocket, дашборд — по SSE, поэтому добавлен отдельный SSE-сигнал classroom_live (state started/ended) ученикам класса/приглашённым/учителю в createSession и endSession (аддитивно, в try/catch — не ломает создание/завершение сессии). Баннер живо появляется/исчезает по этому событию + обновляется при возврате на вкладку. Verified: рендер баннера 10/10 (ученик/учитель/нет сессии, online-счёт без вышедших, пустой title→«Онлайн-урок»); node --check sessions.js + инлайна dashboard; sse-путь резолвится. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,15 @@ function createSession(req, res) {
|
||||
|
||||
const session = db.prepare('SELECT * FROM classroom_sessions WHERE id=?').get(sessionId);
|
||||
emitToSession(sessionId, { type: 'classroom_started', sessionId, title, classId: class_id || null, teacherName: teacher.name });
|
||||
// Баннер «идёт онлайн-урок» на дашбордах — через SSE-канал (доска работает по WS,
|
||||
// дашборд по SSE, поэтому нужен отдельный сигнал ученикам класса / приглашённым / учителю).
|
||||
try {
|
||||
const sse = require('../../sse');
|
||||
const payload = { type: 'classroom_live', state: 'started', sessionId, title, classId: class_id || null };
|
||||
if (class_id) sse.emitToClass(class_id, payload);
|
||||
else if (user_ids) for (const uid of user_ids) sse.emit(uid, payload);
|
||||
sse.emit(teacher.id, payload);
|
||||
} catch { /* SSE недоступен — не критично */ }
|
||||
res.json(session);
|
||||
}
|
||||
|
||||
@@ -74,6 +83,17 @@ function endSession(req, res) {
|
||||
db.prepare('DELETE FROM classroom_draw_permissions WHERE session_id=?').run(sessionId);
|
||||
db.prepare('DELETE FROM classroom_muted WHERE session_id=?').run(sessionId);
|
||||
emitToSession(sessionId, { type: 'classroom_ended', sessionId });
|
||||
// Снять баннер «идёт онлайн-урок» с дашбордов (SSE-канал).
|
||||
try {
|
||||
const sse = require('../../sse');
|
||||
const payload = { type: 'classroom_live', state: 'ended', sessionId };
|
||||
if (session.class_id) sse.emitToClass(session.class_id, payload);
|
||||
else {
|
||||
const invited = db.prepare('SELECT user_id FROM classroom_invites WHERE session_id=?').all(sessionId);
|
||||
for (const r of invited) sse.emit(r.user_id, payload);
|
||||
}
|
||||
sse.emit(session.teacher_id, payload);
|
||||
} catch { /* SSE недоступен — не критично */ }
|
||||
res.json({ ok: true });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user