/* eslint-disable @typescript-eslint/member-ordering */ import { Component, inject, computed, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Store } from '@ngrx/store'; import { NgIcon, provideIcons } from '@ng-icons/core'; import { lucideMinus, lucideSquare, lucideX, lucideChevronLeft, lucideHash, lucideMenu } from '@ng-icons/lucide'; import { Router } from '@angular/router'; import { selectCurrentRoom } from '../../store/rooms/rooms.selectors'; import { RoomsActions } from '../../store/rooms/rooms.actions'; import { selectCurrentUser } from '../../store/users/users.selectors'; import { ServerDirectoryService } from '../../core/services/server-directory.service'; import { WebRTCService } from '../../core/services/webrtc.service'; import { PlatformService } from '../../core/services/platform.service'; import { STORAGE_KEY_CURRENT_USER_ID } from '../../core/constants'; @Component({ selector: 'app-title-bar', standalone: true, imports: [CommonModule, NgIcon], viewProviders: [ provideIcons({ lucideMinus, lucideSquare, lucideX, lucideChevronLeft, lucideHash, lucideMenu }) ], templateUrl: './title-bar.component.html' }) /** * Electron-style title bar with window controls, navigation, and server menu. */ export class TitleBarComponent { private store = inject(Store); private serverDirectory = inject(ServerDirectoryService); private router = inject(Router); private webrtc = inject(WebRTCService); private platform = inject(PlatformService); isElectron = computed(() => this.platform.isElectron); showMenuState = computed(() => false); private currentUserSig = this.store.selectSignal(selectCurrentUser); username = computed(() => this.currentUserSig()?.displayName || 'Guest'); serverName = computed(() => this.serverDirectory.activeServer()?.name || 'No Server'); isConnected = computed(() => this.webrtc.isConnected()); isReconnecting = computed(() => !this.webrtc.isConnected() && this.webrtc.hasEverConnected()); isAuthed = computed(() => !!this.currentUserSig()); private currentRoomSig = this.store.selectSignal(selectCurrentRoom); inRoom = computed(() => !!this.currentRoomSig()); roomName = computed(() => this.currentRoomSig()?.name || ''); roomDescription = computed(() => this.currentRoomSig()?.description || ''); private _showMenu = signal(false); showMenu = computed(() => this._showMenu()); /** Minimize the Electron window. */ minimize() { const api = (window as any).electronAPI; if (api?.minimizeWindow) api.minimizeWindow(); } /** Maximize or restore the Electron window. */ maximize() { const api = (window as any).electronAPI; if (api?.maximizeWindow) api.maximizeWindow(); } /** Close the Electron window. */ close() { const api = (window as any).electronAPI; if (api?.closeWindow) api.closeWindow(); } /** Navigate to the login page. */ goLogin() { this.router.navigate(['/login']); } /** Leave the current room and navigate back to the server search. */ onBack() { // Leave room to ensure header switches to user/server view this.store.dispatch(RoomsActions.leaveRoom()); this.router.navigate(['/search']); } /** Toggle the server dropdown menu. */ toggleMenu() { this._showMenu.set(!this._showMenu()); } /** Leave the current server and navigate to the servers list. */ leaveServer() { this._showMenu.set(false); this.store.dispatch(RoomsActions.leaveRoom()); window.dispatchEvent(new CustomEvent('navigate:servers')); } /** Close the server dropdown menu. */ closeMenu() { this._showMenu.set(false); } /** Log out the current user, disconnect from signaling, and navigate to login. */ logout() { this._showMenu.set(false); // Disconnect from signaling server - this broadcasts "user_left" to all // servers the user was a member of, so other users see them go offline. this.webrtc.disconnect(); try { localStorage.removeItem(STORAGE_KEY_CURRENT_USER_ID); } catch {} this.router.navigate(['/login']); } }