feat: sound system — 12 new sounds + navigation category; dashboard FAB widget button

Sounds:
- UI: modal_open, modal_close, tab_switch, delete
- Navigation (new category): page_enter, section_reveal
- Classroom: timer_warning, wb_clear, file_shared
- Gamification: challenge_complete, daily_login
- Quiz: time_up, quiz_bonus

Dashboard:
- Widget configurator moved from header to fixed FAB (bottom-right)
  no longer pushed off-screen by wide sidebar

Profile settings:
- Added Navigation category toggle
- Expanded preview section: 12 test buttons covering all categories

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-04-14 20:26:04 +03:00
parent 89ba25cd20
commit f3c9ab860e
3 changed files with 169 additions and 45 deletions
+82 -1
View File
@@ -134,6 +134,36 @@
_tone(880, 80, 'sine', 0.13, 5, 50);
setTimeout(function () { _tone(1108, 120, 'sine', 0.15, 5, 80); }, 90);
},
modal_open: function () {
// Soft sweep in — airy whoosh up
_sweep(300, 520, 180, 'sine', 0.09);
setTimeout(function () { _tone(660, 100, 'sine', 0.08, 5, 70); }, 160);
},
modal_close: function () {
// Sweep down — gentle dismiss
_sweep(520, 300, 150, 'sine', 0.08);
},
tab_switch: function () {
// Double-click feel
_tone(900, 35, 'sine', 0.09, 2, 25);
setTimeout(function () { _tone(1100, 35, 'sine', 0.09, 2, 25); }, 45);
},
delete: function () {
// Descending soft thud
_sweep(400, 180, 120, 'triangle', 0.10);
_noise(80, 0.04);
},
// ── Navigation ────────────────────────────────────────────────────────
page_enter: function () {
// Subtle arrival chime
_tone(784, 80, 'sine', 0.08, 5, 55);
setTimeout(function () { _tone(1047, 120, 'sine', 0.07, 5, 80); }, 75);
},
section_reveal: function () {
// Very quiet rising whoosh
_sweep(250, 420, 200, 'sine', 0.07);
},
// ── Classroom ─────────────────────────────────────────────────────────
hand_raise: function () {
@@ -173,6 +203,23 @@
setTimeout(function () { _tone(330, 160, 'sine', 0.14, 10, 100); }, 140);
setTimeout(function () { _tone(261, 350, 'sine', 0.13, 10, 220); }, 280);
},
timer_warning: function () {
// Urgent triple beep — last 10 seconds
_tone(880, 60, 'square', 0.12, 2, 40);
setTimeout(function () { _tone(880, 60, 'square', 0.13, 2, 40); }, 200);
setTimeout(function () { _tone(1108, 100, 'square', 0.15, 2, 70); }, 400);
},
wb_clear: function () {
// Erasing noise sweep
_noise(220, 0.08);
_sweep(600, 200, 220, 'triangle', 0.06);
},
file_shared: function () {
// Paper rustle + chime
_noise(80, 0.05);
setTimeout(function () { _tone(784, 100, 'sine', 0.12, 5, 70); }, 60);
setTimeout(function () { _tone(1047, 120, 'sine', 0.10, 5, 80); }, 160);
},
// ── Gamification ──────────────────────────────────────────────────────
xp_gain: function () {
@@ -218,6 +265,21 @@
setTimeout(function () { _tone(659, 80, 'sine', 0.14, 5, 55); }, 80);
setTimeout(function () { _tone(784, 160, 'sine', 0.16, 5, 100); }, 160);
},
challenge_complete: function () {
// Heroic: E4-G4-B4-E5 arpeggio
_tone(330, 140, 'sine', 0.15, 8, 90);
setTimeout(function () { _tone(392, 140, 'sine', 0.16, 8, 90); }, 130);
setTimeout(function () { _tone(494, 140, 'sine', 0.17, 8, 90); }, 260);
setTimeout(function () { _tone(659, 400, 'sine', 0.20, 8, 260); }, 390);
// Sparkle on top
setTimeout(function () { _tone(1319, 200, 'triangle', 0.07); }, 450);
},
daily_login: function () {
// Morning chime: G-A-B
_tone(392, 120, 'sine', 0.12, 8, 80);
setTimeout(function () { _tone(440, 120, 'sine', 0.13, 8, 80); }, 110);
setTimeout(function () { _tone(494, 250, 'sine', 0.15, 8, 160); }, 220);
},
// ── Quiz ──────────────────────────────────────────────────────────────
quiz_start: function () {
@@ -244,6 +306,20 @@
quiz_tick: function () {
_tone(660, 40, 'square', 0.08, 2, 25);
},
time_up: function () {
// Buzzer — descending sawtooth alarm
_tone(440, 120, 'sawtooth', 0.14, 3, 80);
_noise(120, 0.06);
setTimeout(function () { _tone(330, 160, 'sawtooth', 0.12, 3, 110); }, 110);
setTimeout(function () { _tone(220, 220, 'sawtooth', 0.10, 3, 160); }, 240);
},
quiz_bonus: function () {
// Golden sparkle — high twinkling
_tone(1047, 60, 'sine', 0.14, 2, 45);
setTimeout(function () { _tone(1319, 60, 'sine', 0.16, 2, 45); }, 65);
setTimeout(function () { _tone(1568, 60, 'sine', 0.17, 2, 45); }, 130);
setTimeout(function () { _tone(2093, 180, 'sine', 0.18, 2, 120); }, 195);
},
};
// ── Persistence ───────────────────────────────────────────────────────────
@@ -272,6 +348,7 @@
volume : 0.75,
prefs : {
ui : true,
navigation : true,
classroom : true,
gamification : true,
quiz : true,
@@ -280,14 +357,18 @@
// Category map — which prefs key each sound belongs to
_cats: {
click: 'ui', success: 'ui', error: 'ui', notification: 'ui',
modal_open: 'ui', modal_close: 'ui', tab_switch: 'ui', delete: 'ui',
page_enter: 'navigation', section_reveal: 'navigation',
hand_raise: 'classroom', chat_message: 'classroom',
user_joined: 'classroom', user_left: 'classroom',
muted: 'classroom', draw_permitted: 'classroom',
lesson_start: 'classroom', lesson_end: 'classroom',
timer_warning: 'classroom', wb_clear: 'classroom', file_shared: 'classroom',
xp_gain: 'gamification', level_up: 'gamification',
achievement: 'gamification', coin: 'gamification', streak: 'gamification',
challenge_complete: 'gamification', daily_login: 'gamification',
quiz_start: 'quiz', quiz_correct: 'quiz', quiz_wrong: 'quiz',
quiz_end: 'quiz', quiz_tick: 'quiz',
quiz_end: 'quiz', quiz_tick: 'quiz', time_up: 'quiz', quiz_bonus: 'quiz',
},
play: function (name) {