Add notification sounds

This commit is contained in:
2026-03-03 04:07:33 +01:00
parent 8315df42fc
commit 94f9a9f2ed
12 changed files with 283 additions and 45 deletions

View File

@@ -74,6 +74,32 @@
class="w-full h-1.5 bg-secondary rounded-lg appearance-none cursor-pointer accent-primary"
/>
</div>
<div>
<label class="block text-xs font-medium text-muted-foreground mb-1">
Notification Volume: {{ audioService.notificationVolume() * 100 | number: '1.0-0' }}%
</label>
<div class="flex items-center gap-2">
<input
type="range"
[value]="audioService.notificationVolume()"
(input)="onNotificationVolumeChange($event)"
min="0"
max="1"
step="0.01"
class="flex-1 h-1.5 bg-secondary rounded-lg appearance-none cursor-pointer accent-primary"
/>
<button
(click)="previewNotificationSound()"
class="px-2.5 py-1 text-xs bg-secondary text-foreground rounded-lg hover:bg-secondary/80 transition-colors flex-shrink-0"
title="Preview notification sound"
>
Test
</button>
</div>
<p class="text-[10px] text-muted-foreground/60 mt-1">
Controls join, leave &amp; notification sounds
</p>
</div>
</div>
</section>
@@ -157,9 +183,7 @@
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-foreground">Voice Leveling</p>
<p class="text-xs text-muted-foreground">
Automatically equalise volume across speakers
</p>
<p class="text-xs text-muted-foreground">Automatically equalise volume across speakers</p>
</div>
<label class="relative inline-flex items-center cursor-pointer">
<input
@@ -248,9 +272,7 @@
<option value="slow" [selected]="voiceLeveling.speed() === 'slow'">
Slow (natural)
</option>
<option value="medium" [selected]="voiceLeveling.speed() === 'medium'">
Medium
</option>
<option value="medium" [selected]="voiceLeveling.speed() === 'medium'">Medium</option>
<option value="fast" [selected]="voiceLeveling.speed() === 'fast'">
Fast (aggressive)
</option>

View File

@@ -6,6 +6,10 @@ import { lucideMic, lucideHeadphones, lucideAudioLines, lucideActivity } from '@
import { WebRTCService } from '../../../../core/services/webrtc.service';
import { VoiceLevelingService } from '../../../../core/services/voice-leveling.service';
import {
NotificationAudioService,
AppSound,
} from '../../../../core/services/notification-audio.service';
import { STORAGE_KEY_VOICE_SETTINGS } from '../../../../core/constants';
interface AudioDevice {
@@ -30,6 +34,7 @@ interface AudioDevice {
export class VoiceSettingsComponent {
private webrtcService = inject(WebRTCService);
readonly voiceLeveling = inject(VoiceLevelingService);
readonly audioService = inject(NotificationAudioService);
inputDevices = signal<AudioDevice[]>([]);
outputDevices = signal<AudioDevice[]>([]);
@@ -184,4 +189,13 @@ export class VoiceSettingsComponent {
onNoiseGateToggle(): void {
this.voiceLeveling.setNoiseGate(!this.voiceLeveling.noiseGate());
}
onNotificationVolumeChange(event: Event): void {
const input = event.target as HTMLInputElement;
this.audioService.setNotificationVolume(parseFloat(input.value));
}
previewNotificationSound(): void {
this.audioService.play(AppSound.Notification);
}
}

View File

@@ -190,6 +190,39 @@
</div>
<div class="space-y-4">
<!-- Notification Volume -->
<div>
<div class="flex items-center justify-between mb-2">
<div>
<p class="font-medium text-foreground">Notification volume</p>
<p class="text-sm text-muted-foreground">
Volume for join, leave, and notification sounds
</p>
</div>
<span class="text-sm font-medium text-muted-foreground tabular-nums w-10 text-right">
{{ audioService.notificationVolume() * 100 | number: '1.0-0' }}%
</span>
</div>
<div class="flex items-center gap-3">
<input
type="range"
min="0"
max="1"
step="0.01"
[ngModel]="audioService.notificationVolume()"
(ngModelChange)="onNotificationVolumeChange($event)"
class="flex-1 h-2 rounded-full appearance-none bg-secondary accent-primary cursor-pointer"
/>
<button
(click)="previewNotificationSound()"
class="px-3 py-1.5 text-sm bg-secondary text-foreground rounded-lg hover:bg-secondary/80 transition-colors"
title="Preview sound"
>
Test
</button>
</div>
</div>
<div class="flex items-center justify-between">
<div>
<p class="font-medium text-foreground">Noise reduction</p>

View File

@@ -18,6 +18,7 @@ import {
import { ServerDirectoryService } from '../../core/services/server-directory.service';
import { WebRTCService } from '../../core/services/webrtc.service';
import { NotificationAudioService, AppSound } from '../../core/services/notification-audio.service';
import { STORAGE_KEY_CONNECTION_SETTINGS, STORAGE_KEY_VOICE_SETTINGS } from '../../core/constants';
@Component({
@@ -47,6 +48,7 @@ export class SettingsComponent implements OnInit {
private serverDirectory = inject(ServerDirectoryService);
private webrtcService = inject(WebRTCService);
private router = inject(Router);
audioService = inject(NotificationAudioService);
servers = this.serverDirectory.servers;
isTesting = signal(false);
@@ -157,6 +159,16 @@ export class SettingsComponent implements OnInit {
}
}
/** Called when the notification volume slider changes. */
onNotificationVolumeChange(value: number): void {
this.audioService.setNotificationVolume(value);
}
/** Play a preview of the notification sound at the current volume. */
previewNotificationSound(): void {
this.audioService.play(AppSound.Notification);
}
/** Persist noise reduction preference (merged into existing voice settings) and apply immediately. */
async saveVoiceSettings(): Promise<void> {
// Merge into existing voice settings so we don't overwrite device/volume prefs