import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; import {BASE_PATH, HistoryService, PunishmentHistory} from '../../../api'; import {catchError, map, Observable, shareReplay} from 'rxjs'; import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common'; import {CookieService} from 'ngx-cookie-service'; import {RemoveTrailingPeriodPipe} from '../../util/RemoveTrailingPeriodPipe'; import {HttpErrorResponse} from '@angular/common/http'; import {environment} from '../../../environments/environment'; import {HistoryFormatService} from '../history-format.service'; import {SearchParams} from '../search-terms'; import {Router} from '@angular/router'; @Component({ selector: 'app-history', imports: [ NgIf, NgForOf, NgOptimizedImage, RemoveTrailingPeriodPipe ], templateUrl: './history.component.html', styleUrl: './history.component.scss', providers: [ CookieService, {provide: BASE_PATH, useValue: environment.apiUrl} ], }) export class HistoryComponent implements OnInit, OnChanges { @Input() userType: 'player' | 'staff' = "player"; @Input() punishmentType: 'all' | 'ban' | 'mute' | 'kick' | 'warn' = "all"; @Input() page: number = 0; @Input() searchTerm: string = ''; @Output() pageChange = new EventEmitter(); @Output() selectItem = new EventEmitter(); 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}$/; public history: PunishmentHistory[] = [] constructor(private historyApi: HistoryService, public historyFormat: HistoryFormatService, private router: Router) { } ngOnChanges(): void { this.reloadHistory(); } ngOnInit(): void { this.reloadHistory(); } private reloadHistory(): void { let historyObservable: Observable; if (this.searchTerm.length === 0) { historyObservable = this.historyApi.getHistoryForAll(this.userType, this.punishmentType, this.page); } else { if (this.uuidRegex.test(this.searchTerm)) { historyObservable = this.historyApi.getHistoryForUuid(this.userType, this.punishmentType, this.searchTerm, this.page); } else { historyObservable = this.historyApi.getHistoryForUsers(this.userType, this.punishmentType, this.searchTerm, this.page); } } historyObservable.pipe( map(history => { this.history = history; this.pageChange.emit(this.history.length); }), catchError(err => { this.pageChange.emit(-1); let retrySeconds = 5; if (err instanceof HttpErrorResponse) { if (err.status !== 429) { return this.history; } const headers = err.headers; const retryAfterHeader = headers.get('Retry-After'); console.warn(err.error); if (retryAfterHeader) { const retryAfter = parseInt(retryAfterHeader || '0', 10); if (!isNaN(retryAfter) && retryAfter > 0) { retrySeconds = retryAfter + 1; } } } else { console.error(err); } setTimeout(() => this.reloadHistory(), retrySeconds * 1000); return this.history; }), shareReplay(1) ).subscribe(); } setSearch(name: string, userType: 'player' | 'staff') { let searchParams: SearchParams = { userType: userType, punishmentType: 'all', searchTerm: name } this.selectItem.emit(searchParams); } public showDetailedPunishment(entry: PunishmentHistory) { this.router.navigate([`bans/${entry.type}/${entry.id}`]).then(); } }