diff --git a/package-lock.json b/package-lock.json index 5c1ab1ce..4202eb0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1876,7 +1876,7 @@ }, "@types/archiver": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.3.1.tgz", + "resolved": "https://npm.zone51.tf/@types%2farchiver/-/archiver-5.3.1.tgz", "integrity": "sha512-wKYZaSXaDvTZuInAWjCeGG7BEAgTWG2zZW0/f7IYFcoHB2X2d9lkVFnrOlXl3W6NrvO6Ml3FLLu8Uksyymcpnw==", "dev": true, "requires": { @@ -2396,7 +2396,7 @@ }, "@types/yargs": { "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", + "resolved": "https://registry.npmjs.org/@types%2fyargs/-/yargs-17.0.13.tgz", "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", "dev": true, "requires": { @@ -2998,7 +2998,7 @@ }, "archiver": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", + "resolved": "https://npm.zone51.tf/archiver/-/archiver-5.3.1.tgz", "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", "requires": { "archiver-utils": "^2.1.0", @@ -3012,7 +3012,7 @@ }, "archiver-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "resolved": "https://npm.zone51.tf/archiver-utils/-/archiver-utils-2.1.0.tgz", "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", "requires": { "glob": "^7.1.4", @@ -4053,7 +4053,7 @@ }, "compress-commons": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "resolved": "https://npm.zone51.tf/compress-commons/-/compress-commons-4.1.1.tgz", "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "requires": { "buffer-crc32": "^0.2.13", @@ -4281,12 +4281,12 @@ }, "crc-32": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "resolved": "https://npm.zone51.tf/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" }, "crc32-stream": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", + "resolved": "https://npm.zone51.tf/crc32-stream/-/crc32-stream-4.0.2.tgz", "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", "requires": { "crc-32": "^1.2.0", @@ -6895,7 +6895,7 @@ }, "fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "resolved": "https://npm.zone51.tf/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { @@ -9447,7 +9447,7 @@ }, "lazystream": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "resolved": "https://npm.zone51.tf/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "requires": { "readable-stream": "^2.0.5" @@ -11650,6 +11650,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-range": { + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/react-range/-/react-range-1.8.14.tgz", + "integrity": "sha512-v2nyD5106rHf9dwHzq+WRlhCes83h1wJRHIMFjbZsYYsO6LF4mG/mR3cH7Cf+dkeHq65DItuqIbLn/3jjYjsHg==" + }, "react-refresh": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.12.0.tgz", @@ -11758,7 +11763,7 @@ }, "readdir-glob": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.2.tgz", + "resolved": "https://npm.zone51.tf/readdir-glob/-/readdir-glob-1.1.2.tgz", "integrity": "sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==", "requires": { "minimatch": "^5.1.0" @@ -11766,7 +11771,7 @@ "dependencies": { "brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "resolved": "https://npm.zone51.tf/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "requires": { "balanced-match": "^1.0.0" @@ -11774,7 +11779,7 @@ }, "minimatch": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "resolved": "https://npm.zone51.tf/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "requires": { "brace-expansion": "^2.0.1" @@ -12940,7 +12945,7 @@ }, "tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "resolved": "https://npm.zone51.tf/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "requires": { "bl": "^4.0.3", @@ -14130,7 +14135,7 @@ }, "zip-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", + "resolved": "https://npm.zone51.tf/zip-stream/-/zip-stream-4.1.0.tgz", "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", "requires": { "archiver-utils": "^2.1.0", diff --git a/package.json b/package.json index 40e40386..ed308e56 100644 --- a/package.json +++ b/package.json @@ -240,6 +240,7 @@ "react-colorful": "^5.6.1", "react-dom": "^18.2.0", "react-fitty": "^1.0.1", + "react-range": "^1.8.14", "react-router-dom": "^6.3.0", "react-visibility-sensor": "^5.1.1", "regedit": "^5.1.1", diff --git a/src/renderer/components/maps-mangement-components/filter-panel.component.tsx b/src/renderer/components/maps-mangement-components/filter-panel.component.tsx index ac53c47c..e64b4b75 100644 --- a/src/renderer/components/maps-mangement-components/filter-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/filter-panel.component.tsx @@ -1,30 +1,211 @@ import { MapFilter, MapTag } from "shared/models/maps/beat-saver.model" import {motion} from "framer-motion" -import { MutableRefObject, useRef } from "react" +import { MutableRefObject, useRef, useState } from "react" import { MAP_TYPES } from "renderer/partials/map-tags/map-types" import { MAP_STYLES } from "renderer/partials/map-tags/map-styles" +import { BsmCheckbox } from "../shared/bsm-checkbox.component" +import { diffColors } from "./map-item.component" +import { getTrackBackground, Range } from 'react-range'; +import { useThemeColor } from "renderer/hooks/use-theme-color.hook" +import { getCorrectTextColor } from "renderer/helpers/correct-text-color" +import { hour_to_s, min_to_s } from "renderer/helpers/time-utils" +import dateFormat from "dateformat" export type Props = { className?: string, ref?: MutableRefObject playlist?: boolean, filter?: MapFilter - onChange?: () => void + onChange?: (filter: MapFilter) => void } export function FilterPanel({className, ref, playlist = false, filter, onChange}: Props) { - return !playlist ? ( - -
-
- {[...MAP_TYPES, ...MAP_STYLES].map(tag => ( - {tag} - ))} + const MIN_NPS = 0; + const MAX_NPS = 17; + + const MIN_DURATION = 0; + const MAX_DURATION = min_to_s(30); + + const [npss, setNpss] = useState([filter?.minNps || MIN_NPS, filter?.maxNps || MAX_NPS]); + const [durations, setDurations] = useState([filter?.minDuration || MIN_DURATION, filter?.maxDuration || MAX_DURATION]); + const firstColor = useThemeColor("first-color"); + const thumbTextColor = getCorrectTextColor(firstColor); + + const isTagEnabled = (tag: MapTag): boolean => { + return filter?.enabledTags?.some(t => t === tag) || filter?.excludedTags?.some(t => t === tag); + } + + const isTagExcluded = (tag: MapTag): boolean => { + return filter?.excludedTags?.some(t => t === tag); + } + + const secToTimer = (sec: number): string => { + const date = new Date(0); + date.setSeconds(sec); + return sec > 3600 ? dateFormat(date, "h:MM:ss") : dateFormat(date, "MM:ss"); + } + + const handleRangeChange = ([min, max]: number[]) => { + setNpss(() => [min, max]); + onChange?.({...filter, minNps: min, maxNps: max}); + } + + const handleRangeDurationChange = ([min, max]: number[]) => { + setDurations([min, max]); + onChange?.({...filter, minDuration: min, maxDuration: max}); + } + + console.log(hour_to_s(2)); + + return !playlist ? ( + +
+
+ ( +
+ {children} +
+ )} + renderThumb={({ index, props }) => ( +
+ { + npss[index] === MAX_NPS ? "∞" : npss[index] === MIN_NPS ? "NPS" : npss[index].toFixed(1) + } +
+ )} + /> +
+
+ ( +
+ {children} +
+ )} + renderThumb={({ index, props }) => ( +
+ { + durations[index] === MAX_DURATION ? "∞" : durations[index] === MIN_DURATION ? "Durée" : secToTimer(durations[index]) + } +
+ )} + /> +
-
- - ) : ( +
+
+

general

+
+ + AI +
+
+ + Rancked +
+
+ + Curated +
+
+ + Verified Mapper +
+
+ + Full Spread +
+

requirements

+
+ + Chroma +
+
+ + Noodle +
+
+ + Mapping Extensions +
+
+ + Cinema +
+ +
+
+

TAGS

+
+ {MAP_TYPES.map(tag => ( + {tag} + ))} +
+
+ {MAP_STYLES.map(tag => ( + {tag} + ))} +
+ + +
+
+ + ) : ( <> - ) + ) } diff --git a/src/renderer/components/maps-mangement-components/map-item.component.tsx b/src/renderer/components/maps-mangement-components/map-item.component.tsx index 71505564..cfaa1f31 100644 --- a/src/renderer/components/maps-mangement-components/map-item.component.tsx +++ b/src/renderer/components/maps-mangement-components/map-item.component.tsx @@ -214,7 +214,7 @@ export function MapItem({hash, title, autor, songAutor, coverUrl, songUrl, autor ) } -const diffColors: Record = { +export const diffColors: Record = { Easy: "#00FF9E", Normal: "#00FFFF", Hard: "#FFA700", diff --git a/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx b/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx index cee6481a..e8654302 100644 --- a/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx @@ -5,6 +5,7 @@ import { LocalMapsListPanel } from "./local-maps-list-panel.component" import {AnimatePresence, motion} from "framer-motion" import { BsmDropdownButton } from "../shared/bsm-dropdown-button.component" import { FilterPanel } from "./filter-panel.component" +import { MapFilter } from "shared/models/maps/beat-saver.model" type Props = { oneBlock?: boolean, @@ -14,6 +15,20 @@ type Props = { export function MapsPlaylistsPanel({version, oneBlock = false}: Props) { const [tabIndex, setTabIndex] = useState(0); + const [filter, setFilter] = useState({ + automapper: false, + chroma: false, + cinema: false, + curated: false, + enabledTags: [], + excludedTags: [], + fullSpread: false, + me: false, + noodle: false, + ranked: false, + verified: false, + + }) return ( <> @@ -23,10 +38,10 @@ export function MapsPlaylistsPanel({version, oneBlock = false}: Props) {
- - + + - + <> diff --git a/src/renderer/helpers/time-utils.ts b/src/renderer/helpers/time-utils.ts new file mode 100644 index 00000000..6118e6d2 --- /dev/null +++ b/src/renderer/helpers/time-utils.ts @@ -0,0 +1,14 @@ +const SECONDS_IN_MINUTE = 60; +const MINUTES_IN_HOUR = 60; + +export function min_to_s(minutes: number): number{ + return minutes * SECONDS_IN_MINUTE; +} + +export function hour_to_min(hours: number): number{ + return hours * MINUTES_IN_HOUR; +} + +export function hour_to_s(hours: number): number{ + return hours * min_to_s(MINUTES_IN_HOUR); +} \ No newline at end of file diff --git a/src/shared/models/maps/beat-saver.model.ts b/src/shared/models/maps/beat-saver.model.ts index 2c7d4049..16f34ea9 100644 --- a/src/shared/models/maps/beat-saver.model.ts +++ b/src/shared/models/maps/beat-saver.model.ts @@ -152,6 +152,7 @@ export interface MapFilter { chroma?: boolean, cinema?: boolean, noodle?: boolean, + me?: boolean, curated?: boolean, verified?: boolean, from?: number,