123 lines
3.5 KiB
TypeScript
123 lines
3.5 KiB
TypeScript
/* 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<undefined>();
|
|
readonly cancelled = output<undefined>();
|
|
|
|
readonly categories = CATEGORY_PRESETS;
|
|
activeEndpoints = this.serverDirectory.activeServers;
|
|
|
|
name = signal('');
|
|
description = signal('');
|
|
topic = signal('');
|
|
selectedCategoryId = signal<string | null>(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);
|
|
}
|
|
}
|