/* eslint-disable @typescript-eslint/member-ordering */ import { Component, HostListener, inject, output, 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 { NgIcon, provideIcons } from '@ng-icons/core'; import { lucideChevronDown, lucideChevronUp } from '@ng-icons/lucide'; import { RoomsActions } from '../../../../store/rooms/rooms.actions'; import { ServerDirectoryFacade } from '../../application/facades/server-directory.facade'; import { ThemeNodeDirective } from '../../../theme'; import { ViewportService } from '../../../../core/platform'; import { BottomSheetComponent, ModalBackdropComponent } from '../../../../shared'; import { CATEGORY_PRESETS, ServerCategoryPreset } from '../create-server/create-server.component'; /** * Modal presentation of the server-creation form. Mirrors the dedicated * `/create-server` page but is rendered as a Toju modal (desktop) / bottom sheet * (mobile) so it can be opened straight from the servers rail. Emits `created` * once a room creation has been dispatched and `cancelled` when dismissed. */ @Component({ selector: 'app-create-server-dialog', standalone: true, imports: [ CommonModule, FormsModule, NgIcon, ThemeNodeDirective, BottomSheetComponent, ModalBackdropComponent ], viewProviders: [provideIcons({ lucideChevronDown, lucideChevronUp })], templateUrl: './create-server-dialog.component.html', host: { style: 'display: contents;' } }) export class CreateServerDialogComponent { private store = inject(Store); private router = inject(Router); private serverDirectory = inject(ServerDirectoryFacade); readonly isMobile = inject(ViewportService).isMobile; readonly created = output(); readonly cancelled = output(); readonly categories = CATEGORY_PRESETS; activeEndpoints = this.serverDirectory.activeServers; name = signal(''); description = signal(''); topic = signal(''); selectedCategoryId = signal(null); isPrivate = signal(false); password = signal(''); sourceId = signal(''); showAdvanced = signal(false); constructor() { this.sourceId.set(this.activeEndpoints()[0]?.id ?? ''); } /** True when the form has enough to create a server. */ get canCreate(): boolean { return this.name().trim().length > 0 && this.sourceId().length > 0; } selectCategory(category: ServerCategoryPreset): void { if (this.selectedCategoryId() === category.id) { this.selectedCategoryId.set(null); this.topic.set(''); return; } this.selectedCategoryId.set(category.id); this.topic.set(category.topic); } toggleAdvanced(): void { this.showAdvanced.update((shown) => !shown); } @HostListener('document:keydown.escape') cancel(): void { this.cancelled.emit(undefined); } create(): void { if (!this.canCreate) { return; } const currentUserId = localStorage.getItem('metoyou_currentUserId'); if (!currentUserId) { this.router.navigate(['/login']); return; } this.store.dispatch( RoomsActions.createRoom({ name: this.name().trim(), description: this.description().trim() || undefined, topic: this.topic().trim() || undefined, isPrivate: this.isPrivate(), password: this.password().trim() || undefined, sourceId: this.sourceId() || undefined }) ); this.created.emit(undefined); } }