135 lines
4.1 KiB
TypeScript
135 lines
4.1 KiB
TypeScript
/* 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']);
|
|
}
|
|
}
|