Noise reduction beta

This commit is contained in:
2026-03-03 02:01:42 +01:00
parent 50e7a66812
commit d684fc5632
14 changed files with 1516 additions and 159 deletions

View File

@@ -29,8 +29,8 @@
</div>
<p class="text-sm text-muted-foreground mb-4">
Add multiple server directories to search for rooms across different networks.
The active server will be used for creating and registering new rooms.
Add multiple server directories to search for rooms across different networks. The active
server will be used for creating and registering new rooms.
</p>
<!-- Server List -->
@@ -58,7 +58,9 @@
<div class="flex items-center gap-2">
<span class="font-medium text-foreground truncate">{{ server.name }}</span>
@if (server.isActive) {
<span class="text-xs bg-primary text-primary-foreground px-2 py-0.5 rounded-full">Active</span>
<span class="text-xs bg-primary text-primary-foreground px-2 py-0.5 rounded-full"
>Active</span
>
}
</div>
<p class="text-sm text-muted-foreground truncate">{{ server.url }}</p>
@@ -75,7 +77,10 @@
class="p-2 hover:bg-secondary rounded-lg transition-colors"
title="Set as active"
>
<ng-icon name="lucideCheck" class="w-4 h-4 text-muted-foreground hover:text-primary" />
<ng-icon
name="lucideCheck"
class="w-4 h-4 text-muted-foreground hover:text-primary"
/>
</button>
}
@if (!server.isDefault) {
@@ -84,7 +89,10 @@
class="p-2 hover:bg-destructive/10 rounded-lg transition-colors"
title="Remove server"
>
<ng-icon name="lucideTrash2" class="w-4 h-4 text-muted-foreground hover:text-destructive" />
<ng-icon
name="lucideTrash2"
class="w-4 h-4 text-muted-foreground hover:text-destructive"
/>
</button>
}
</div>
@@ -125,7 +133,7 @@
</div>
<!-- Connection Settings -->
<div class="bg-card border border-border rounded-lg p-6">
<div class="bg-card border border-border rounded-lg p-6 mb-6">
<div class="flex items-center gap-2 mb-4">
<ng-icon name="lucideServer" class="w-5 h-5 text-muted-foreground" />
<h2 class="text-lg font-semibold text-foreground">Connection Settings</h2>
@@ -135,7 +143,9 @@
<div class="flex items-center justify-between">
<div>
<p class="font-medium text-foreground">Auto-reconnect</p>
<p class="text-sm text-muted-foreground">Automatically reconnect when connection is lost</p>
<p class="text-sm text-muted-foreground">
Automatically reconnect when connection is lost
</p>
</div>
<label class="relative inline-flex items-center cursor-pointer">
<input
@@ -144,14 +154,18 @@
(change)="saveConnectionSettings()"
class="sr-only peer"
/>
<div class="w-11 h-6 bg-secondary rounded-full peer peer-checked:bg-primary peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all"></div>
<div
class="w-11 h-6 bg-secondary rounded-full peer peer-checked:bg-primary peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all"
></div>
</label>
</div>
<div class="flex items-center justify-between">
<div>
<p class="font-medium text-foreground">Search all servers</p>
<p class="text-sm text-muted-foreground">Search across all configured server directories</p>
<p class="text-sm text-muted-foreground">
Search across all configured server directories
</p>
</div>
<label class="relative inline-flex items-center cursor-pointer">
<input
@@ -160,7 +174,39 @@
(change)="saveConnectionSettings()"
class="sr-only peer"
/>
<div class="w-11 h-6 bg-secondary rounded-full peer peer-checked:bg-primary peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all"></div>
<div
class="w-11 h-6 bg-secondary rounded-full peer peer-checked:bg-primary peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all"
></div>
</label>
</div>
</div>
</div>
<!-- Voice Settings -->
<div class="bg-card border border-border rounded-lg p-6">
<div class="flex items-center gap-2 mb-4">
<ng-icon name="lucideAudioLines" class="w-5 h-5 text-muted-foreground" />
<h2 class="text-lg font-semibold text-foreground">Voice Settings</h2>
</div>
<div class="space-y-4">
<div class="flex items-center justify-between">
<div>
<p class="font-medium text-foreground">Noise reduction</p>
<p class="text-sm text-muted-foreground">
Use RNNoise to suppress background noise from your microphone
</p>
</div>
<label class="relative inline-flex items-center cursor-pointer">
<input
type="checkbox"
[(ngModel)]="noiseReduction"
(change)="saveVoiceSettings()"
class="sr-only peer"
/>
<div
class="w-11 h-6 bg-secondary rounded-full peer peer-checked:bg-primary peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all"
></div>
</label>
</div>
</div>

View File

@@ -13,10 +13,12 @@ import {
lucideRefreshCw,
lucideGlobe,
lucideArrowLeft,
lucideAudioLines,
} from '@ng-icons/lucide';
import { ServerDirectoryService } from '../../core/services/server-directory.service';
import { STORAGE_KEY_CONNECTION_SETTINGS } from '../../core/constants';
import { WebRTCService } from '../../core/services/webrtc.service';
import { STORAGE_KEY_CONNECTION_SETTINGS, STORAGE_KEY_VOICE_SETTINGS } from '../../core/constants';
@Component({
selector: 'app-settings',
@@ -33,6 +35,7 @@ import { STORAGE_KEY_CONNECTION_SETTINGS } from '../../core/constants';
lucideRefreshCw,
lucideGlobe,
lucideArrowLeft,
lucideAudioLines,
}),
],
templateUrl: './settings.component.html',
@@ -42,6 +45,7 @@ import { STORAGE_KEY_CONNECTION_SETTINGS } from '../../core/constants';
*/
export class SettingsComponent implements OnInit {
private serverDirectory = inject(ServerDirectoryService);
private webrtcService = inject(WebRTCService);
private router = inject(Router);
servers = this.serverDirectory.servers;
@@ -52,10 +56,12 @@ export class SettingsComponent implements OnInit {
newServerUrl = '';
autoReconnect = true;
searchAllServers = true;
noiseReduction = false;
/** Load persisted connection settings on component init. */
ngOnInit(): void {
this.loadConnectionSettings();
this.loadVoiceSettings();
}
/** Add a new signaling server after URL validation and duplicate checking. */
@@ -128,7 +134,7 @@ export class SettingsComponent implements OnInit {
JSON.stringify({
autoReconnect: this.autoReconnect,
searchAllServers: this.searchAllServers,
})
}),
);
this.serverDirectory.setSearchAllServers(this.searchAllServers);
}
@@ -137,4 +143,32 @@ export class SettingsComponent implements OnInit {
goBack(): void {
this.router.navigate(['/']);
}
/** Load voice settings (noise reduction) from localStorage. */
loadVoiceSettings(): void {
const settings = localStorage.getItem(STORAGE_KEY_VOICE_SETTINGS);
if (settings) {
const parsed = JSON.parse(settings);
this.noiseReduction = parsed.noiseReduction ?? false;
}
// Sync the live WebRTC state with the persisted preference
if (this.noiseReduction !== this.webrtcService.isNoiseReductionEnabled()) {
this.webrtcService.toggleNoiseReduction(this.noiseReduction);
}
}
/** 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
let existing: Record<string, unknown> = {};
try {
const raw = localStorage.getItem(STORAGE_KEY_VOICE_SETTINGS);
if (raw) existing = JSON.parse(raw);
} catch {}
localStorage.setItem(
STORAGE_KEY_VOICE_SETTINGS,
JSON.stringify({ ...existing, noiseReduction: this.noiseReduction }),
);
await this.webrtcService.toggleNoiseReduction(this.noiseReduction);
}
}