import {Component, OnInit} from '@angular/core'; import {HeaderComponent} from "../header/header.component"; import {HistoryComponent} from './history/history.component'; import {HistoryCount, HistoryService} from '../../api'; import {NgClass, NgForOf, NgIf} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {catchError, map, Observable} from 'rxjs'; @Component({ selector: 'app-bans', imports: [ HeaderComponent, HistoryComponent, NgIf, FormsModule, NgForOf, NgClass ], templateUrl: './bans.component.html', styleUrl: './bans.component.scss' }) export class BansComponent implements OnInit { constructor(public historyApi: HistoryService) { } private PAGE_SIZE: number = 10; private uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; private actualPage: number = 0; private totalSearchResults: number = -1; public active: string = ''; public userType: 'player' | 'staff' = "player"; public punishmentType: 'all' | 'ban' | 'mute' | 'kick' | 'warn' = "all"; public page: number = 0; public names: string[] = []; public finalSearchTerm: string = ''; public searchTerm: string = ''; public filteredNames: string[] = []; public pageSize = 10; public historyCount: HistoryCount = { bans: 0, mutes: 0, kicks: 0, warnings: 0 } ngOnInit() { this.historyApi.getUserNames(this.userType, this.punishmentType).subscribe(names => { this.names = names; }); this.historyApi.getTotalPunishments().subscribe(totalPunishments => { this.historyCount = totalPunishments; }) this.pushState(); window.addEventListener('popstate', (event) => { if (event.state && event.state.searchTerm !== undefined) { this.searchTerm = event.state.searchTerm; this.finalSearchTerm = event.state.searchTerm; this.page = event.state.page; this.userType = event.state.userType; this.punishmentType = event.state.punishmentType; } }); } public getCurrentButtonId(options: 'all' | 'ban' | 'mute' | 'kick' | 'warn') { if (options == this.punishmentType) { return 'currentButton' } return null; } public getCurrentUserTypeButtonId(options: 'player' | 'staff') { if (options == this.userType) { return 'currentButton' } return null; } public filterNames() { if (!this.searchTerm) { this.filteredNames = []; return; } this.filteredNames = this.names.filter(name => name.toLowerCase().startsWith(this.searchTerm.toLowerCase()) ).slice(0, 10); } public selectName(name: string) { this.searchTerm = name; this.filteredNames = []; this.search(); } public search() { this.pushState() this.finalSearchTerm = this.searchTerm; this.page = 0; if (this.finalSearchTerm.length === 0) { this.totalSearchResults = -1 return } let totalSearchResultsObservable: Observable; if (this.uuidRegex.test(this.finalSearchTerm)) { totalSearchResultsObservable = this.historyApi.getTotalResultsForUuidSearch(this.userType, this.punishmentType, this.finalSearchTerm); } else { totalSearchResultsObservable = this.historyApi.getTotalResultsForUserSearch(this.userType, this.punishmentType, this.finalSearchTerm); } totalSearchResultsObservable.pipe( map(totalSearchResults => { this.totalSearchResults = totalSearchResults; }), catchError(err => { console.error(err); return []; }) ).subscribe(); } public changeUserType(type: 'player' | 'staff') { this.pushState(); this.userType = type; this.page = 0; this.finalSearchTerm = ''; this.searchTerm = ''; this.filteredNames = []; } public changeHistoryPunishment(type: 'all' | 'ban' | 'mute' | 'kick' | 'warn') { this.pushState(); this.punishmentType = type; this.page = 0; } public nextPage() { if (this.page === this.getMaxPage()) { return; } this.setPage(this.page + 1) } public previousPage() { if (this.page === 0) { return; } this.setPage(this.page - 1) } public setPage(page: number) { if (this.actualPage !== this.page) { console.warn('Changing page too quickly, the previous page change has not loaded yet'); return; } this.pushState(); this.page = page } private pushState() { const state = { searchTerm: this.searchTerm, page: this.page, userType: this.userType, punishmentType: this.punishmentType }; const title = 'Altitude Bans'; const url = window.location.href; window.history.pushState(state, title, url); } public getMaxPage() { const all = this.historyCount.bans + this.historyCount.mutes + this.historyCount.warnings; if (this.finalSearchTerm.length !== 0) { return Math.floor(this.totalSearchResults / this.PAGE_SIZE); } switch (this.punishmentType) { case 'all': return Math.floor(all / this.PAGE_SIZE); case 'ban': return Math.floor(this.historyCount.bans / this.PAGE_SIZE); case 'mute': return Math.floor(this.historyCount.mutes / this.PAGE_SIZE); case 'kick': return Math.floor(this.historyCount.kicks / this.PAGE_SIZE); case 'warn': return Math.floor(this.historyCount.warnings / this.PAGE_SIZE); default: return 0; } } public buttonActive(compare: number): boolean { if (compare !== 0 && this.pageSize < this.PAGE_SIZE) { return false; } return this.page !== compare; } public updatePageSize(pageSize: number) { if (pageSize < 0) { return; } else { this.pageSize = pageSize; this.actualPage = this.page; } } }