feat(classroom): тумблер «Вызов на урок» в профиле + интеграция мелодии в LS.sfx

Мелодию-вызов перевёл с кастомного Web Audio на общий движок звуков LS.sfx:
- длинный вестминстерский бой теперь в sound.js (звук lesson_start);
- api.js лениво подгружает sound.js на любой странице и играет lesson_start
  по SSE classroom_started (вместо собственного синтезатора);
- отдельный pref lessonCall + тумблер «Вызов на урок» и кнопка прослушивания
  в профиле (Настройки → Звуки); уважает мастер-тумблер и громкость;
- lesson_start выведен из категории classroom (управляется своим тумблером);
- разблокировка AudioContext по первому жесту перенесена в sound.js.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-01 09:11:44 +03:00
parent 63ceeaabc2
commit ec2a207fb8
3 changed files with 107 additions and 75 deletions
+29 -1
View File
@@ -1183,7 +1183,7 @@
<div class="pref-row">
<div class="pref-row-info">
<div class="pref-row-label">Classroom</div>
<div class="pref-row-desc">Урок, участники, таймер, доска, файлы</div>
<div class="pref-row-desc">Участники, таймер, доска, файлы</div>
</div>
<label class="pref-toggle">
<input type="checkbox" id="pref-sfx-classroom" onchange="prefSfxCat('classroom',this.checked)">
@@ -1191,6 +1191,18 @@
</label>
</div>
<!-- Lesson call melody -->
<div class="pref-row">
<div class="pref-row-info">
<div class="pref-row-label">Вызов на урок</div>
<div class="pref-row-desc">Мелодия-перезвон, когда учитель начал онлайн-урок</div>
</div>
<label class="pref-toggle">
<input type="checkbox" id="pref-lesson-call" onchange="prefLessonCall(this.checked)">
<span class="pref-toggle-track"></span>
</label>
</div>
<!-- Gamification sounds -->
<div class="pref-row">
<div class="pref-row-info">
@@ -1218,6 +1230,10 @@
<!-- Preview buttons -->
<div class="pref-section-label" style="margin-top:14px">Прослушать</div>
<div style="display:flex;gap:8px;flex-wrap:wrap;margin-top:8px">
<button class="pref-test-btn" onclick="prefLessonTest()">
<i data-lucide="bell-ring" style="width:12px;height:12px;vertical-align:-2px"></i>
Вызов на урок
</button>
<button class="pref-test-btn" onclick="prefSfxTest('notification')">
<i data-lucide="bell" style="width:12px;height:12px;vertical-align:-2px"></i>
Уведомление
@@ -2068,6 +2084,7 @@
setChk('pref-sfx-classroom', sfx.prefs.classroom);
setChk('pref-sfx-gamification', sfx.prefs.gamification);
setChk('pref-sfx-quiz', sfx.prefs.quiz);
setChk('pref-lesson-call', sfx.lessonCall !== false);
const vol = Math.round(sfx.volume * 100);
const volEl = document.getElementById('pref-sfx-vol');
const volVal = document.getElementById('pref-sfx-vol-val');
@@ -2113,6 +2130,17 @@
LS.sfx.enabled = wasEnabled;
}
function prefLessonCall(v) {
if (!window.LS || !LS.sfx) return;
LS.sfx.setLessonCall(v);
if (v) LS.sfx.play('click'); // короткое подтверждение, не вся мелодия
}
function prefLessonTest() {
if (!window.LS || !LS.sfx) return;
LS.sfx.preview('lesson_start'); // прослушать в обход тумблеров
}
function prefAnim(v) {
localStorage.setItem('ls_anim', v ? 'on' : 'off');
LS.toast(v ? 'Анимации включены' : 'Анимации отключены', 'success');