136 lines
6.6 KiB
HTML
136 lines
6.6 KiB
HTML
<div class="main term">
|
|
<h1><span class="board">/sus/</span> - Suspicious Scores</h1>
|
|
<div class="alert mb-2">
|
|
This includes all replays with <35 cvUR. Low values can indicate cheating but always manually review users and
|
|
replays before making judgements.
|
|
</div>
|
|
|
|
<fieldset>
|
|
<legend>
|
|
Filter results
|
|
<button [disabled]="!this.filterManager.hasValueChanged()" (click)="this.resetValues()">Clear filters</button>
|
|
<button [disabled]="!this.filterManager.hasValueChanged() || this.isUrlFilters" (click)="this.getFiltersUrl()" title="Get a permanent link to the filters. Share or save it to your bookmarks!">Share filters</button>
|
|
</legend>
|
|
<!-- Min PP -->
|
|
<p>
|
|
<label for="minPP" class="form-label">Min PP</label>
|
|
<input class="form-control" type="number" id="minPP" [(ngModel)]="this.filterManager.filters.minPP" (input)="filterScores()"
|
|
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
|
|
</p>
|
|
|
|
<!-- Max PP -->
|
|
<p>
|
|
<label for="maxPP" class="form-label">Max PP</label>
|
|
<input class="form-control" type="number" id="maxPP" [(ngModel)]="this.filterManager.filters.maxPP" (input)="filterScores()"
|
|
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
|
|
</p>
|
|
`
|
|
<!-- Min cvUR -->
|
|
<p>
|
|
<label for="minUR" class="form-label">Min cvUR</label>
|
|
<input class="form-control" type="number" id="minUR" [(ngModel)]="this.filterManager.filters.minUR" (input)="filterScores()"
|
|
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
|
|
</p>
|
|
|
|
<!-- Max cvUR -->
|
|
<p>
|
|
<label for="maxUR" class="form-label">Max cvUR</label>
|
|
<input class="form-control" type="number" id="maxUR" [(ngModel)]="this.filterManager.filters.maxUR" (input)="filterScores()"
|
|
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
|
|
</p>
|
|
|
|
<!-- Search Username -->
|
|
<p>
|
|
<label for="searchUsername" class="form-label">Username</label>
|
|
<input class="form-control" type="text" id="searchUsername" [(ngModel)]="this.filterManager.filters.searchUsername" (input)="filterScores()"
|
|
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
|
|
</p>
|
|
|
|
<!-- Search Beatmap -->
|
|
<p>
|
|
<label for="searchBeatmap" class="form-label">Beatmap</label>
|
|
<input class="form-control" type="text" id="searchBeatmap" [(ngModel)]="this.filterManager.filters.searchBeatmap" (input)="filterScores()"
|
|
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
|
|
</p>
|
|
</fieldset>
|
|
|
|
<div *ngIf="getTotalPages() > 1" style="padding: 20px">
|
|
<p class="text-center">
|
|
Page: {{ this.currentPage }} / {{ this.getTotalPages() }}
|
|
</p>
|
|
<div>
|
|
<button (click)="currentPage = currentPage - 1" [disabled]="currentPage === 1" style="float: left">Previous page</button>
|
|
<button (click)="currentPage = currentPage + 1" [disabled]="currentPage === getTotalPages()" style="float: right">Next page</button>
|
|
</div>
|
|
</div>
|
|
<table class="table mt-4">
|
|
<thead class="text-center">
|
|
<tr>
|
|
<th>User</th>
|
|
<th>Beatmap</th>
|
|
<th>Date</th>
|
|
<th>cvUR</th>
|
|
<th>PP</th>
|
|
<th></th>
|
|
</tr>
|
|
<tr class="filters">
|
|
<th>
|
|
</th>
|
|
<th>
|
|
<span title="Sort by beatmap star rating (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'beatmap_star_rating-asc'" (click)="sortScores('beatmap_star_rating', 'asc')">▲</span>
|
|
<span title="Sort by beatmap star rating (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'beatmap_star_rating-desc'" (click)="sortScores('beatmap_star_rating', 'desc')">▼</span>
|
|
</th>
|
|
<th>
|
|
<span title="Sort by date (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'date-asc'" (click)="sortScores('date', 'asc')">▲</span>
|
|
<span title="Sort by date (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'date-desc'" (click)="sortScores('date', 'desc')">▼</span>
|
|
</th>
|
|
<th>
|
|
<span title="Sort by cvUR (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'ur-asc'" (click)="sortScores('ur', 'asc')">▲</span>
|
|
<span title="Sort by cvUR (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'ur-desc'" (click)="sortScores('ur', 'desc')">▼</span>
|
|
</th>
|
|
<th>
|
|
<span title="Sort by PP (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'pp-asc'" (click)="sortScores('pp', 'asc')">▲️</span>
|
|
<span title="Sort by PP (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'pp-desc'" (click)="sortScores('pp', 'desc')">▼</span>
|
|
</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody style="font-size: 14px;">
|
|
<tr *ngFor="let score of this.getCurrentPage()">
|
|
<td>
|
|
<a [routerLink]="['/u/' + score.user_id]">
|
|
{{ score.username }}
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<div class="image-container">
|
|
<a href="https://osu.ppy.sh/beatmaps/{{ score.beatmap_id }}?mode=osu" target="_blank">
|
|
<img ngSrc="https://assets.ppy.sh/beatmaps/{{ score.beatmap_beatmapset_id }}/covers/cover.jpg" width="260" height="72"
|
|
alt="Beatmap Cover" loading="lazy">
|
|
<div class="overlay">
|
|
{{ score.beatmap_title }}
|
|
{{ score.beatmap_star_rating | number: '1.0-1' }}★
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</td>
|
|
<td>{{ score.date }}</td>
|
|
<td class="text-center">{{ score.ur | number: '1.2-2' }}</td>
|
|
<td class="text-center">{{ score.pp | number: '1.0-0' }}</td>
|
|
<td>
|
|
<a [routerLink]="['/s/' + score.replay_id]" class="btn mr-1">
|
|
Details
|
|
</a>
|
|
<a [href]="'https://osu.ppy.sh/scores/osu/' + score.replay_id" class="btn" target="_blank">
|
|
osu!web
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div *ngIf="getTotalPages() > 1" style="padding: 30px">
|
|
<button (click)="currentPage = currentPage - 1" [disabled]="currentPage === 1" style="float: left">Previous page</button>
|
|
<button (click)="currentPage = currentPage + 1" [disabled]="currentPage === getTotalPages()" style="float: right">Next page</button>
|
|
</div>
|
|
</div>
|