Files
Toju/src/app/features/settings/settings.component.ts

210 lines
5.7 KiB
TypeScript

/* eslint-disable @typescript-eslint/member-ordering */
import {
Component,
inject,
signal,
OnInit
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
lucideServer,
lucidePlus,
lucideTrash2,
lucideCheck,
lucideX,
lucideSettings,
lucideRefreshCw,
lucideGlobe,
lucideArrowLeft,
lucideAudioLines
} from '@ng-icons/lucide';
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({
selector: 'app-settings',
standalone: true,
imports: [
CommonModule,
FormsModule,
NgIcon
],
viewProviders: [
provideIcons({
lucideServer,
lucidePlus,
lucideTrash2,
lucideCheck,
lucideX,
lucideSettings,
lucideRefreshCw,
lucideGlobe,
lucideArrowLeft,
lucideAudioLines
})
],
templateUrl: './settings.component.html'
})
/**
* Settings page for managing signaling servers and connection preferences.
*/
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);
addError = signal<string | null>(null);
newServerName = '';
newServerUrl = '';
autoReconnect = true;
searchAllServers = true;
noiseReduction = true;
/** Load persisted connection settings on component init. */
ngOnInit(): void {
this.loadConnectionSettings();
this.loadVoiceSettings();
}
/** Add a new signaling server after URL validation and duplicate checking. */
addServer(): void {
this.addError.set(null);
// Validate URL
try {
new URL(this.newServerUrl);
} catch {
this.addError.set('Please enter a valid URL');
return;
}
// Check for duplicates
if (this.servers().some((server) => server.url === this.newServerUrl)) {
this.addError.set('This server URL already exists');
return;
}
this.serverDirectory.addServer({
name: this.newServerName.trim(),
url: this.newServerUrl.trim().replace(/\/$/, '') // Remove trailing slash
});
// Clear form
this.newServerName = '';
this.newServerUrl = '';
// Test the new server
const servers = this.servers();
const newServer = servers[servers.length - 1];
if (newServer) {
this.serverDirectory.testServer(newServer.id);
}
}
/** Remove a signaling server by its ID. */
removeServer(id: string): void {
this.serverDirectory.removeServer(id);
}
/** Set the active signaling server used for connections. */
setActiveServer(id: string): void {
this.serverDirectory.setActiveServer(id);
}
/** Test connectivity to all configured servers. */
async testAllServers(): Promise<void> {
this.isTesting.set(true);
await this.serverDirectory.testAllServers();
this.isTesting.set(false);
}
/** Load connection settings (auto-reconnect, search scope) from localStorage. */
loadConnectionSettings(): void {
const settings = localStorage.getItem(STORAGE_KEY_CONNECTION_SETTINGS);
if (settings) {
const parsed = JSON.parse(settings);
this.autoReconnect = parsed.autoReconnect ?? true;
this.searchAllServers = parsed.searchAllServers ?? true;
this.serverDirectory.setSearchAllServers(this.searchAllServers);
}
}
/** Persist current connection settings to localStorage. */
saveConnectionSettings(): void {
localStorage.setItem(
STORAGE_KEY_CONNECTION_SETTINGS,
JSON.stringify({
autoReconnect: this.autoReconnect,
searchAllServers: this.searchAllServers
})
);
this.serverDirectory.setSearchAllServers(this.searchAllServers);
}
/** Navigate back to the main page. */
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);
}
}
/** 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
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);
}
}