mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[bugfix] proper filter for leaderboard/ranking
* use leaderboard query param with beatsaver * fixed issue where blRanked is not showing on mapItem components
This commit is contained in:
@@ -832,7 +832,8 @@
|
||||
"tags": "Stichwörter",
|
||||
"specificities": "Allgemein",
|
||||
"requirements": "Anforderungen",
|
||||
"exclude": "Ausschließen"
|
||||
"exclude": "Ausschließen",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "Präzision",
|
||||
@@ -888,6 +889,12 @@
|
||||
"verified": "Verifiziert",
|
||||
"fullSpread": "Full Spread"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "Installiert"
|
||||
},
|
||||
|
||||
@@ -839,7 +839,8 @@
|
||||
"tags": "tags",
|
||||
"specificities": "general",
|
||||
"requirements": "requirements",
|
||||
"exclude": "exclude"
|
||||
"exclude": "exclude",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "accuracy",
|
||||
@@ -895,6 +896,12 @@
|
||||
"verified": "verified",
|
||||
"fullSpread": "full spread"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "installed"
|
||||
},
|
||||
|
||||
@@ -832,7 +832,8 @@
|
||||
"tags": "tags",
|
||||
"specificities": "general",
|
||||
"requirements": "requisitos",
|
||||
"exclude": "excluir"
|
||||
"exclude": "excluir",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "precisión",
|
||||
@@ -888,6 +889,12 @@
|
||||
"verified": "verificado",
|
||||
"fullSpread": "panel completo"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "instalado"
|
||||
},
|
||||
|
||||
@@ -833,7 +833,8 @@
|
||||
"tags": "tags",
|
||||
"specificities": "général",
|
||||
"requirements": "requis",
|
||||
"exclude": "exclure"
|
||||
"exclude": "exclure",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "précision",
|
||||
@@ -889,6 +890,12 @@
|
||||
"verified": "vérifiée",
|
||||
"fullSpread": "panel complet"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "installé"
|
||||
},
|
||||
|
||||
@@ -832,7 +832,8 @@
|
||||
"tags": "タグ",
|
||||
"specificities": "一般",
|
||||
"requirements": "要Mod",
|
||||
"exclude": "除外する"
|
||||
"exclude": "除外する",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "正確",
|
||||
@@ -888,6 +889,12 @@
|
||||
"verified": "認証済み",
|
||||
"fullSpread": "フルスプレッド"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "インストール済み"
|
||||
},
|
||||
|
||||
@@ -831,7 +831,8 @@
|
||||
"tags": "тэги",
|
||||
"specificities": "основное",
|
||||
"requirements": "требуемые моды",
|
||||
"exclude": "исключить"
|
||||
"exclude": "исключить",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "точность",
|
||||
@@ -887,6 +888,12 @@
|
||||
"verified": "проверенные авторы",
|
||||
"fullSpread": "полный набор"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "установленный"
|
||||
},
|
||||
|
||||
@@ -832,7 +832,8 @@
|
||||
"tags": "標籤",
|
||||
"specificities": "general",
|
||||
"requirements": "要求",
|
||||
"exclude": "排除"
|
||||
"exclude": "排除",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "精確度",
|
||||
@@ -888,6 +889,12 @@
|
||||
"verified": "Verified",
|
||||
"fullSpread": "Full spread"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "已安裝"
|
||||
},
|
||||
|
||||
@@ -832,7 +832,8 @@
|
||||
"tags": "标签",
|
||||
"specificities": "general",
|
||||
"requirements": "要求",
|
||||
"exclude": "排除"
|
||||
"exclude": "排除",
|
||||
"leaderboard": "leaderboard"
|
||||
},
|
||||
"map-types": {
|
||||
"accuracy": "精确度",
|
||||
@@ -888,6 +889,12 @@
|
||||
"verified": "verified",
|
||||
"fullSpread": "full spread"
|
||||
},
|
||||
"map-leaderboard": {
|
||||
"All": "All",
|
||||
"Ranked": "Ranked",
|
||||
"BeatLeader": "BeatLeader",
|
||||
"ScoreSaber": "ScoreSaber"
|
||||
},
|
||||
"map-excludes": {
|
||||
"installed": "已安装"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { BsvMapDetail } from "shared/models/maps";
|
||||
import { BsvPlaylistPage, MapFilter, PlaylistSearchParams, PlaylistSearchResponse, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
|
||||
import { BsvPlaylistPage, MapFilter, MapLeaderboard, PlaylistSearchParams, PlaylistSearchResponse, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
|
||||
import { RequestService } from "../../request.service";
|
||||
import { CustomError } from "shared/models/exceptions/custom-error.class";
|
||||
|
||||
@@ -32,6 +32,10 @@ export class BeatSaverApiService {
|
||||
return new URLSearchParams();
|
||||
}
|
||||
|
||||
if (!filter.leaderboard) {
|
||||
filter.leaderboard = MapLeaderboard.All;
|
||||
}
|
||||
|
||||
const enbledTagsString = filter.enabledTags ? Array.from(filter.enabledTags) : null;
|
||||
const excludedTagsString = filter.excludedTags ? Array.from(filter.excludedTags).map(tag => `!${tag}`) : null;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BsvMapDetail, MapFilter, MapRequirement, MapSpecificity, MapStyle, MapTag, MapType } from "shared/models/maps/beat-saver.model";
|
||||
import { BsvMapDetail, MapFilter, MapLeaderboard, MapRequirement, MapSpecificity, MapStyle, MapTag, MapType } from "shared/models/maps/beat-saver.model";
|
||||
import { motion } from "framer-motion";
|
||||
import { MutableRefObject, useEffect, useRef, useState } from "react";
|
||||
import { BsmCheckbox } from "../../shared/bsm-checkbox.component";
|
||||
@@ -14,6 +14,8 @@ import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface";
|
||||
import { SongDetails } from "shared/models/maps";
|
||||
import formatDuration from "format-duration";
|
||||
import { MapInfo } from "shared/models/maps/info/map-info.model";
|
||||
import { BsmSelect, BsmSelectOption } from "renderer/components/shared/bsm-select.component";
|
||||
import { useConstant } from "renderer/hooks/use-constant.hook";
|
||||
|
||||
export type Props = {
|
||||
className?: string;
|
||||
@@ -45,6 +47,13 @@ export function FilterPanel({ className, ref, playlist = false, filter, localDat
|
||||
const isTagActivated = (tag: MapTag): boolean => filter?.enabledTags?.has(tag) || filter?.excludedTags?.has(tag);
|
||||
const isTagExcluded = (tag: MapTag): boolean => filter?.excludedTags?.has(tag);
|
||||
|
||||
const leaderboardOptions: BsmSelectOption<MapLeaderboard>[] = useConstant(
|
||||
() => Object.values(MapLeaderboard).map(key => ({
|
||||
text: `maps.map-leaderboard.${key}`,
|
||||
value: key,
|
||||
}))
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (firstRun.current) {
|
||||
firstRun.current = false;
|
||||
@@ -137,10 +146,6 @@ export function FilterPanel({ className, ref, playlist = false, filter, localDat
|
||||
return t(`maps.map-styles.${style}`);
|
||||
};
|
||||
|
||||
const translateMapSpecificity = (specificity: MapSpecificity): string => {
|
||||
return t(`maps.map-specificities.${specificity}`);
|
||||
};
|
||||
|
||||
type BooleanKeys<T> = { [k in keyof T]: T[k] extends boolean ? k : never }[keyof T];
|
||||
|
||||
const handleCheckbox = (key: BooleanKeys<MapFilter>) => {
|
||||
@@ -153,6 +158,12 @@ export function FilterPanel({ className, ref, playlist = false, filter, localDat
|
||||
onChange(newFilter);
|
||||
};
|
||||
|
||||
const handleLeaderboardChange = (value: MapLeaderboard) => {
|
||||
const newFilter = { ...(filter ?? {}) };
|
||||
newFilter.leaderboard = value;
|
||||
onChange(newFilter);
|
||||
}
|
||||
|
||||
const handleApply = () => {
|
||||
onApply(filter);
|
||||
setHaveChanged(() => false);
|
||||
@@ -173,9 +184,17 @@ export function FilterPanel({ className, ref, playlist = false, filter, localDat
|
||||
{Object.values(MapSpecificity).map(specificity => (
|
||||
<div key={specificity} className="flex justify-start items-center h-[22px] z-20 relative py-0.5 cursor-pointer" onClick={() => handleCheckbox(specificity)}>
|
||||
<BsmCheckbox className="h-full aspect-square relative bg-inherit mr-1" checked={filter?.[specificity]} onChange={() => handleCheckbox(specificity)} />
|
||||
<span className="grow capitalize">{translateMapSpecificity(specificity)}</span>
|
||||
<span className="grow capitalize">{t(`maps.map-specificities.${specificity}`)}</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<h2 className="mb-1 uppercase text-sm">{t("maps.map-filter-panel.leaderboard")}</h2>
|
||||
<BsmSelect
|
||||
options={leaderboardOptions}
|
||||
selected={MapLeaderboard.All}
|
||||
onChange={handleLeaderboardChange}
|
||||
/>
|
||||
|
||||
<h2 className="my-1 uppercase text-sm">{t("maps.map-filter-panel.requirements")}</h2>
|
||||
{Object.values(MapRequirement).map(requirement => (
|
||||
<div key={requirement} className="flex justify-start items-center h-[22px] z-20 relative py-0.5 cursor-pointer" onClick={() => handleCheckbox(requirement)}>
|
||||
|
||||
@@ -209,11 +209,16 @@ export enum MapRequirement {
|
||||
|
||||
export enum MapSpecificity {
|
||||
Automapper = "automapper",
|
||||
Ranked = "ranked",
|
||||
Curated = "curated",
|
||||
Verified = "verified",
|
||||
FullSpread = "fullSpread"
|
||||
}
|
||||
|
||||
export enum MapLeaderboard {
|
||||
All = "All",
|
||||
Ranked = "Ranked",
|
||||
BeatLeader = "BeatLeader",
|
||||
ScoreSaber = "ScoreSaber",
|
||||
}
|
||||
|
||||
// [ Admin, Uploader, SageScore, None ]
|
||||
@@ -235,7 +240,7 @@ export interface MapFilter {
|
||||
from?: number;
|
||||
to?: number;
|
||||
fullSpread?: boolean;
|
||||
ranked?: boolean;
|
||||
leaderboard?: string;
|
||||
installed?: boolean;
|
||||
minDuration?: number;
|
||||
maxDuration?: number;
|
||||
|
||||
Reference in New Issue
Block a user