mirror of
https://github.com/Myxelium/Bridge-Multi.git
synced 2026-04-11 14:19:38 +00:00
- Update API
- Add Chart Preview - Add Drum Type dropdown when the "drums" instrument is selected - Add Min/Max Year to advanced search - Add Track Hash to advanced search - Add "Download Video Backgrounds" setting - Updated and improved detected chart issues
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
<div class="dropdown">
|
||||
<label tabindex="0" class="btn btn-neutral rounded-btn rounded-r-none uppercase">
|
||||
@if (instrument) {
|
||||
<img class="w-8 hidden sm:block" src="assets/images/instruments/{{ instrument }}.png" />
|
||||
<img class="w-8 hidden sm:block" src="https://static.enchor.us/instrument-{{ instrument }}.png" />
|
||||
}
|
||||
{{ instrumentDisplay(instrument) }}
|
||||
</label>
|
||||
@@ -29,7 +29,7 @@
|
||||
@for (instrument of instruments; track $index) {
|
||||
<li>
|
||||
<a (click)="setInstrument(instrument, $event)">
|
||||
<img class="w-8" src="assets/images/instruments/{{ instrument }}.png" />
|
||||
<img class="w-8" src="https://static.enchor.us/instrument-{{ instrument }}.png" />
|
||||
{{ instrumentDisplay(instrument) }}
|
||||
</a>
|
||||
</li>
|
||||
@@ -38,7 +38,9 @@
|
||||
</div>
|
||||
<!-- Difficulty Dropdown -->
|
||||
<div class="dropdown">
|
||||
<label tabindex="0" class="btn btn-neutral rounded-btn rounded-l-none uppercase">{{ difficultyDisplay(difficulty) }}</label>
|
||||
<label tabindex="0" class="btn btn-neutral rounded-btn rounded-l-none uppercase" [class.rounded-r-none]="instrument === 'drums'">{{
|
||||
difficultyDisplay(difficulty)
|
||||
}}</label>
|
||||
<ul tabindex="0" class="menu dropdown-content z-[2] p-2 shadow bg-neutral text-neutral-content rounded-box w-40">
|
||||
<li>
|
||||
<a (click)="setDifficulty(null, $event)">{{ difficultyDisplay(null) }}</a>
|
||||
@@ -50,6 +52,22 @@
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
@if (instrument === 'drums') {
|
||||
<!-- Drum Type Dropdown -->
|
||||
<div class="dropdown">
|
||||
<label tabindex="0" class="btn btn-neutral rounded-btn rounded-l-none uppercase">{{ drumTypeDisplay(drumType) }}</label>
|
||||
<ul tabindex="0" class="menu dropdown-content z-[2] p-2 shadow bg-neutral text-neutral-content rounded-box w-40">
|
||||
<li>
|
||||
<a (click)="setDrumType(null, $event)">{{ drumTypeDisplay(null) }}</a>
|
||||
</li>
|
||||
@for (drumType of drumTypes; track $index) {
|
||||
<li>
|
||||
<a (click)="setDrumType(drumType, $event)">{{ drumTypeDisplay(drumType) }}</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="flex-1 flex-grow-[3] h-0"></div>
|
||||
<!-- Advanced Search -->
|
||||
@@ -125,88 +143,117 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 justify-end">
|
||||
<table class="table table-xs">
|
||||
<tbody>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">Length (minutes)</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minLength" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxLength" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">
|
||||
<span
|
||||
class="label-text underline decoration-dotted cursor-help tooltip [text-wrap:balance]"
|
||||
data-tip="Also known as chart difficulty. Typically a number between 0 and 6.">
|
||||
Intensity
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minIntensity" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxIntensity" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">Average NPS</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minAverageNPS" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxAverageNPS" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">Max NPS</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minMaxNPS" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxMaxNPS" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">
|
||||
<span
|
||||
class="label-text underline decoration-dotted cursor-help tooltip [text-wrap:balance]"
|
||||
data-tip="The date of the last time this chart was modified in Google Drive.">
|
||||
Modified After
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="date"
|
||||
min="2012-01-01"
|
||||
[max]="todayDate"
|
||||
placeholder="YYYY/MM/DD"
|
||||
class="input input-bordered join-item input-sm w-32"
|
||||
formControlName="modifiedAfter"
|
||||
(blur)="startValidation = true"
|
||||
[class.input-error]="advancedSearchForm.invalid && startValidation" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">
|
||||
<span
|
||||
class="label-text underline decoration-dotted cursor-help tooltip [text-wrap:balance]"
|
||||
data-tip="The MD5 hash of the chart folder or .sng file. You can enter multiple values if they are separated by commas.">
|
||||
Hash
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="input input-bordered join-item input-sm w-32" formControlName="hash" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between">
|
||||
<div class="flex gap-2">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-wrap justify-center gap-5">
|
||||
<div class="flex flex-col gap-2 justify-end">
|
||||
<table class="table table-xs">
|
||||
<tbody>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">Length (minutes)</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minLength" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxLength" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">
|
||||
<span
|
||||
class="label-text underline decoration-dotted cursor-help tooltip [text-wrap:balance]"
|
||||
data-tip="Also known as chart difficulty. Typically a number between 0 and 6.">
|
||||
Intensity
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minIntensity" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxIntensity" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">Average NPS</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minAverageNPS" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxAverageNPS" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">Max NPS</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minMaxNPS" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxMaxNPS" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 justify-end">
|
||||
<table class="table table-xs">
|
||||
<tbody>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">Year</td>
|
||||
<td>
|
||||
<div class="join">
|
||||
<input type="number" placeholder="Min" class="input input-bordered join-item input-sm w-16" formControlName="minYear" />
|
||||
<input type="number" placeholder="Max" class="input input-bordered join-item input-sm w-16" formControlName="maxYear" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">
|
||||
<span
|
||||
class="label-text underline decoration-dotted cursor-help tooltip [text-wrap:balance]"
|
||||
data-tip="The date of the last time this chart was modified in Google Drive.">
|
||||
Modified After
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="date"
|
||||
min="2012-01-01"
|
||||
[max]="todayDate"
|
||||
placeholder="YYYY/MM/DD"
|
||||
class="input input-bordered join-item input-sm w-32"
|
||||
formControlName="modifiedAfter"
|
||||
(blur)="startValidation = true"
|
||||
[class.input-error]="advancedSearchForm.invalid && startValidation" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">
|
||||
<span
|
||||
class="label-text underline decoration-dotted cursor-help tooltip [text-wrap:balance]"
|
||||
data-tip="The MD5 hash of the chart folder or .sng file. You can enter multiple values if they are separated by commas.">
|
||||
Hash
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="input input-bordered join-item input-sm w-32" formControlName="hash" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b-0">
|
||||
<td class="text-sm">
|
||||
<span
|
||||
class="label-text tooltip cursor-help underline decoration-dotted [text-wrap:balance]"
|
||||
data-tip="The hash of only things that impact scoring on a specific track. You can enter multiple values if they are separated by commas. (this is used by leaderboards to distinguish charts)">
|
||||
Track Hash
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="input join-item input-bordered input-sm w-32" formControlName="trackHash" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap justify-center gap-2">
|
||||
<div class="flex flex-col">
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-normal gap-2">
|
||||
@@ -247,6 +294,8 @@
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-normal gap-2">
|
||||
<input
|
||||
@@ -278,27 +327,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-normal gap-2">
|
||||
<input
|
||||
#hasRollLanes
|
||||
type="checkbox"
|
||||
class="toggle toggle-sm"
|
||||
[indeterminate]="true"
|
||||
(click)="clickCheckbox('hasRollLanes', $event)" />
|
||||
<span class="label-text" [class.text-opacity-70]="formValue('hasRollLanes') === null">
|
||||
{{ formValue('hasRollLanes') === false ? 'No ' : '' }}Roll Lanes
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-normal gap-2">
|
||||
<input #has2xKick type="checkbox" class="toggle toggle-sm" [indeterminate]="true" (click)="clickCheckbox('has2xKick', $event)" />
|
||||
<span class="label-text" [class.text-opacity-70]="formValue('has2xKick') === null">
|
||||
{{ formValue('has2xKick') === false ? 'No ' : '' }}2x Kick
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-normal gap-2">
|
||||
<input type="checkbox" class="toggle toggle-sm" [indeterminate]="true" (click)="clickCheckbox('hasIssues', $event)" />
|
||||
@@ -324,13 +352,36 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-normal gap-2">
|
||||
<input
|
||||
#hasRollLanes
|
||||
type="checkbox"
|
||||
class="toggle toggle-sm"
|
||||
[indeterminate]="true"
|
||||
(click)="clickCheckbox('hasRollLanes', $event)" />
|
||||
<span class="label-text" [class.text-opacity-70]="formValue('hasRollLanes') === null">
|
||||
{{ formValue('hasRollLanes') === false ? 'No ' : '' }}Roll Lanes
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-normal gap-2">
|
||||
<input #has2xKick type="checkbox" class="toggle toggle-sm" [indeterminate]="true" (click)="clickCheckbox('has2xKick', $event)" />
|
||||
<span class="label-text" [class.text-opacity-70]="formValue('has2xKick') === null">
|
||||
{{ formValue('has2xKick') === false ? 'No ' : '' }}2x Kick
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-sm btn-primary uppercase"
|
||||
[class.btn-disabled]="advancedSearchForm.invalid && startValidation"
|
||||
(click)="searchAdvanced()">
|
||||
Search{{ advancedSearchForm.invalid && startValidation ? ' ("Modified After" is invalid)' : '' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-sm btn-primary uppercase"
|
||||
[class.btn-disabled]="advancedSearchForm.invalid && startValidation"
|
||||
(click)="searchAdvanced()">
|
||||
Search{{ advancedSearchForm.invalid && startValidation ? ' ("Modified After" is invalid)' : '' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@ import dayjs from 'dayjs'
|
||||
import { distinctUntilChanged, switchMap, throttleTime } from 'rxjs'
|
||||
import { Difficulty, Instrument } from 'scan-chart'
|
||||
import { SearchService } from 'src-angular/app/core/services/search.service'
|
||||
import { difficulties, difficultyDisplay, instrumentDisplay, instruments } from 'src-shared/UtilFunctions'
|
||||
import { difficulties, difficultyDisplay, drumTypeDisplay, DrumTypeName, drumTypeNames, instrumentDisplay, instruments } from 'src-shared/UtilFunctions'
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-bar',
|
||||
@@ -25,8 +25,10 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
|
||||
public showAdvanced = false
|
||||
public instruments = instruments
|
||||
public difficulties = difficulties
|
||||
public drumTypes = drumTypeNames
|
||||
public instrumentDisplay = instrumentDisplay
|
||||
public difficultyDisplay = difficultyDisplay
|
||||
public drumTypeDisplay = drumTypeDisplay
|
||||
|
||||
public advancedSearchForm: ReturnType<this['getAdvancedSearchForm']>
|
||||
public startValidation = false
|
||||
@@ -90,6 +92,16 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
get drumType() {
|
||||
return this.searchService.drumType.value
|
||||
}
|
||||
setDrumType(drumType: DrumTypeName | null, event: MouseEvent) {
|
||||
this.searchService.drumType.setValue(drumType)
|
||||
if (event.target instanceof HTMLElement) {
|
||||
event.target.parentElement?.parentElement?.blur()
|
||||
}
|
||||
}
|
||||
|
||||
get todayDate() {
|
||||
return dayjs().format('YYYY-MM-DD')
|
||||
}
|
||||
@@ -164,8 +176,11 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
|
||||
maxAverageNPS: null as number | null,
|
||||
minMaxNPS: null as number | null,
|
||||
maxMaxNPS: null as number | null,
|
||||
minYear: null as number | null,
|
||||
maxYear: null as number | null,
|
||||
modifiedAfter: this.fb.nonNullable.control('', { validators: dateVaidator }),
|
||||
hash: this.fb.nonNullable.control(''),
|
||||
trackHash: this.fb.nonNullable.control(''),
|
||||
hasSoloSections: null as boolean | null,
|
||||
hasForcedNotes: null as boolean | null,
|
||||
hasOpenNotes: null as boolean | null,
|
||||
@@ -208,6 +223,7 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
|
||||
this.searchService.advancedSearch({
|
||||
instrument: this.instrument,
|
||||
difficulty: this.difficulty,
|
||||
drumType: this.drumType,
|
||||
source: 'bridge' as const,
|
||||
...this.advancedSearchForm.getRawValue(),
|
||||
}).subscribe()
|
||||
|
||||
Reference in New Issue
Block a user