/* eslint-disable @typescript-eslint/member-ordering */ import { Component, inject, OnInit, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { debounceTime, distinctUntilChanged, Subject } from 'rxjs'; import { NgIcon, provideIcons } from '@ng-icons/core'; import { lucideSearch, lucideUsers, lucideLock, lucideGlobe, lucidePlus, lucideSettings } from '@ng-icons/lucide'; import { RoomsActions } from '../../store/rooms/rooms.actions'; import { selectSearchResults, selectIsSearching, selectRoomsError, selectSavedRooms } from '../../store/rooms/rooms.selectors'; import { Room } from '../../core/models'; import { ServerInfo } from '../../core/models'; import { SettingsModalService } from '../../core/services/settings-modal.service'; @Component({ selector: 'app-server-search', standalone: true, imports: [CommonModule, FormsModule, NgIcon], viewProviders: [ provideIcons({ lucideSearch, lucideUsers, lucideLock, lucideGlobe, lucidePlus, lucideSettings }) ], templateUrl: './server-search.component.html' }) /** * Server search and discovery view with server creation dialog. * Allows users to search for, join, and create new servers. */ export class ServerSearchComponent implements OnInit { private store = inject(Store); private router = inject(Router); private settingsModal = inject(SettingsModalService); private searchSubject = new Subject(); searchQuery = ''; searchResults = this.store.selectSignal(selectSearchResults); isSearching = this.store.selectSignal(selectIsSearching); error = this.store.selectSignal(selectRoomsError); savedRooms = this.store.selectSignal(selectSavedRooms); // Create dialog state showCreateDialog = signal(false); newServerName = signal(''); newServerDescription = signal(''); newServerTopic = signal(''); newServerPrivate = signal(false); newServerPassword = signal(''); /** Initialize server search, load saved rooms, and set up debounced search. */ ngOnInit(): void { // Initial load this.store.dispatch(RoomsActions.searchServers({ query: '' })); this.store.dispatch(RoomsActions.loadRooms()); // Setup debounced search this.searchSubject.pipe(debounceTime(300), distinctUntilChanged()).subscribe((query) => { this.store.dispatch(RoomsActions.searchServers({ query })); }); } /** Emit a search query to the debounced search subject. */ onSearchChange(query: string): void { this.searchSubject.next(query); } /** Join a server from the search results. Redirects to login if unauthenticated. */ joinServer(server: ServerInfo): void { const currentUserId = localStorage.getItem('metoyou_currentUserId'); if (!currentUserId) { this.router.navigate(['/login']); return; } this.store.dispatch( RoomsActions.joinRoom({ roomId: server.id, serverInfo: { name: server.name, description: server.description, hostName: server.hostName } }) ); } /** Open the create-server dialog. */ openCreateDialog(): void { this.showCreateDialog.set(true); } /** Close the create-server dialog and reset the form. */ closeCreateDialog(): void { this.showCreateDialog.set(false); this.resetCreateForm(); } /** Submit the new server creation form and dispatch the create action. */ createServer(): void { if (!this.newServerName()) return; const currentUserId = localStorage.getItem('metoyou_currentUserId'); if (!currentUserId) { this.router.navigate(['/login']); return; } this.store.dispatch( RoomsActions.createRoom({ name: this.newServerName(), description: this.newServerDescription() || undefined, topic: this.newServerTopic() || undefined, isPrivate: this.newServerPrivate(), password: this.newServerPrivate() ? this.newServerPassword() : undefined }) ); this.closeCreateDialog(); } /** Open the unified settings modal to the Network page. */ openSettings(): void { this.settingsModal.open('network'); } /** Join a previously saved room by converting it to a ServerInfo payload. */ joinSavedRoom(room: Room): void { this.joinServer(this.toServerInfo(room)); } private toServerInfo(room: Room): ServerInfo { return { id: room.id, name: room.name, description: room.description, hostName: room.hostId || 'Unknown', userCount: room.userCount, maxUsers: room.maxUsers ?? 50, isPrivate: !!room.password, createdAt: room.createdAt }; } private resetCreateForm(): void { this.newServerName.set(''); this.newServerDescription.set(''); this.newServerTopic.set(''); this.newServerPrivate.set(false); this.newServerPassword.set(''); } }