import { CommonModule } from '@angular/common'; import { Component, effect, inject, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { Router, RouterLink } from '@angular/router'; import { ChatSessionService } from './chat-session.service'; import type { AdminUserSummary } from './models'; import { ThemeService } from './theme.service'; @Component({ selector: 'app-home-page', imports: [CommonModule, FormsModule, RouterLink], templateUrl: './home-page.component.html', styleUrl: './home-page.component.scss', }) export class HomePageComponent { private readonly router = inject(Router); readonly theme = inject(ThemeService); authMode: 'login' | 'register' = 'login'; readonly embeddedMode = typeof window !== 'undefined' && window.localStorage.getItem('privatechat.embeddedMode') === '1'; serverUrl = ''; displayName = ''; username = ''; password = ''; accessKeyLabel = ''; readonly adminUsers = signal([]); readonly loadingAdminUsers = signal(false); readonly deletingUserId = signal(null); readonly adminUsersError = signal(null); constructor(readonly session: ChatSessionService) { this.serverUrl = session.serverUrl(); if (this.embeddedMode) { effect(() => { const currentUser = this.session.currentUser(); const activePeerId = this.session.activePeerId(); if (!currentUser || !activePeerId) { return; } void this.router.navigate(['/chat', activePeerId], { replaceUrl: true }); }); } effect(() => { const currentUser = this.session.currentUser(); if (!currentUser || !this.session.isApprovalAdmin()) { this.adminUsers.set([]); this.adminUsersError.set(null); this.loadingAdminUsers.set(false); return; } void this.reloadAdminUsers(); }); } async submitAuth(): Promise { this.applyServerUrl(); if (this.authMode === 'register') { const authenticated = await this.session.register(this.username, this.password, this.displayName); this.password = ''; if (!authenticated) { this.authMode = 'login'; } return; } await this.session.login(this.username, this.password); } applyServerUrl(): void { this.session.setServerUrl(this.serverUrl); } async logout(): Promise { await this.session.logout(); this.authMode = 'login'; this.displayName = ''; this.password = ''; } async loginWithAccessKey(): Promise { this.applyServerUrl(); await this.session.loginWithAccessKey(this.username); this.password = ''; } async registerAccessKey(): Promise { await this.session.registerAccessKey(this.accessKeyLabel); this.accessKeyLabel = ''; } async reloadAdminUsers(): Promise { this.loadingAdminUsers.set(true); this.adminUsersError.set(null); try { this.adminUsers.set(await this.session.loadAdminUsers()); } catch (error) { this.adminUsersError.set( error instanceof Error ? error.message : 'Could not load users.', ); } finally { this.loadingAdminUsers.set(false); } } async deleteUser(user: AdminUserSummary): Promise { if ( typeof window !== 'undefined' && !window.confirm(`Delete user ${user.username}? This removes the account from SQLite.`) ) { return; } this.deletingUserId.set(user.id); this.adminUsersError.set(null); try { await this.session.deleteUserAccount(user.id); this.adminUsers.update((users) => users.filter((candidate) => candidate.id !== user.id)); } catch (error) { this.adminUsersError.set( error instanceof Error ? error.message : 'Could not delete that user.', ); } finally { this.deletingUserId.set(null); } } async openChatUi(): Promise { const peerId = this.session.activePeerId() ?? this.session.peers()[0]?.id; if (peerId) { this.session.selectPeer(peerId); await this.router.navigate(['/chat', peerId]); return; } this.session.error.set(null); await this.router.navigate(['/chat']); } cycleTheme(): void { this.theme.cycleMode(); } }