mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
can select maps and fix blur issue on translate
This commit is contained in:
+23
-4
@@ -7,6 +7,7 @@ import { Subscription } from "rxjs"
|
||||
import { MapItem, MapItemProps, ParsedMapDiff } from "./map-item.component"
|
||||
import { BsvMapCharacteristic, BsvMapDifficultyType } from "shared/models/maps/beat-saver.model"
|
||||
import { useInView } from "framer-motion"
|
||||
import { MapsToolbar } from "./maps-toolbar.component"
|
||||
|
||||
type Props = {
|
||||
version: BSVersion,
|
||||
@@ -20,6 +21,7 @@ export function LocalMapsListPanel({version, className} : Props) {
|
||||
const ref = useRef()
|
||||
const isVisible = useInView(ref, {once: true});
|
||||
const [maps, setMaps] = useState([] as BsmLocalMap[]);
|
||||
const [selectedMaps, setSelectedMaps] = useState([] as string[]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -59,6 +61,18 @@ export function LocalMapsListPanel({version, className} : Props) {
|
||||
return res;
|
||||
}
|
||||
|
||||
const onMapSelected = (hash: string) => {
|
||||
const hashs = [...selectedMaps];
|
||||
if(hashs.some(selectedHash => selectedHash === hash)){
|
||||
const i = hashs.findIndex(selectedHash => selectedHash === hash);
|
||||
hashs.splice(i, 1);
|
||||
}
|
||||
else{
|
||||
hashs.push(hash);
|
||||
}
|
||||
setSelectedMaps(() => hashs);
|
||||
}
|
||||
|
||||
const renderMapItem = (map: BsmLocalMap) => {
|
||||
|
||||
return <MapItem
|
||||
@@ -70,15 +84,20 @@ export function LocalMapsListPanel({version, className} : Props) {
|
||||
autor={map.rawInfo._levelAuthorName}
|
||||
songAutor={map.rawInfo._songAuthorName}
|
||||
bpm={map.rawInfo._beatsPerMinute}
|
||||
duration={map.bsaverInfo?.metadata?.duration}
|
||||
duration={map.bsaverInfo?.metadata?.duration}
|
||||
selected={selectedMaps.some(hash => hash === map.hash)}
|
||||
diffs={extractMapDiffs(map)} mapId={map.bsaverInfo?.id} qualified={null} ranked={map.bsaverInfo?.ranked} autorId={map.bsaverInfo?.uploader?.id} likes={map.bsaverInfo?.stats?.upvotes} createdAt={map.bsaverInfo?.createdAt}
|
||||
onDelete={() => {}}
|
||||
onSelected={onMapSelected}
|
||||
/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ul ref={ref} className={className}>
|
||||
{maps.map(map => renderMapItem(map))}
|
||||
</ul>
|
||||
<div ref={ref} className={className}>
|
||||
{/* <MapsToolbar className="w-full shrink-0 h-8 border-b-2 border-main-color-1"/> */}
|
||||
<ul className="p-3 w-full grow flex flex-wrap justify-center content-start gap-2 overflow-y-scroll scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900">
|
||||
{maps.map(map => renderMapItem(map))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -32,11 +32,13 @@ export type MapItemProps = {
|
||||
duration: number,
|
||||
likes: number,
|
||||
createdAt: string,
|
||||
selected?: boolean,
|
||||
onDelete?: (hash: string) => void,
|
||||
onDownload?: (id: string) => void,
|
||||
onSelected: (hash: string) => void,
|
||||
}
|
||||
|
||||
export function MapItem({hash, title, autor, songAutor, coverUrl, songUrl, autorId, mapId, diffs, qualified, ranked, bpm, duration, likes, createdAt, onDelete, onDownload}: MapItemProps) {
|
||||
export function MapItem({hash, title, autor, songAutor, coverUrl, songUrl, autorId, mapId, diffs, qualified, ranked, bpm, duration, likes, createdAt, selected, onDelete, onDownload, onSelected}: MapItemProps) {
|
||||
|
||||
const linkOpener = LinkOpenerService.getInstance();
|
||||
const audioPlayer = AudioPlayerService.getInstance();
|
||||
@@ -123,7 +125,8 @@ export function MapItem({hash, title, autor, songAutor, coverUrl, songUrl, autor
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.li className="relative h-[100px] min-w-[400px] shrink grow basis-0 text-white group" onHoverStart={() => setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5}}>
|
||||
<motion.li className="relative h-[100px] min-w-[400px] shrink-0 grow basis-0 text-white group cursor-pointer" onHoverStart={() => setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5, transform: "translateZ(0) scale(1.0, 1.0)", backfaceVisibility: "hidden"}} onClick={e => {e.stopPropagation(); onSelected(hash)}}>
|
||||
{(hovered || selected) && <motion.span className="glow-on-hover" animate={{opacity: 1}} transition={{duration: .1, ease: "easeIn"}}/>}
|
||||
<AnimatePresence>
|
||||
{(diffsPanelHovered || bottomBarHovered) && (
|
||||
<motion.ul key={hash} className="absolute top-[calc(100%-10px)] w-full h-fit max-h-[200%] pt-4 pb-2 px-2 overflow-y-scroll bg-main-color-3 brightness-125 rounded-md flex flex-col gap-3 scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900 shadow-sm shadow-black" initial={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0}} transition={{duration: .15}} onHoverStart={diffsPanelHoverStart} onHoverEnd={diffsPanelHoverEnd}>
|
||||
@@ -194,11 +197,11 @@ export function MapItem({hash, title, autor, songAutor, coverUrl, songUrl, autor
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bg-main-color-3 top-0 right-0 h-full z-[1] w-[30px] translate-x-5 group-hover:translate-x-0 transition-transform">
|
||||
<div className="absolute bg-main-color-3 top-0 h-full z-[1] w-[30px] -right-5 group-hover:right-0 transition-all">
|
||||
<span className="absolute w-[10px] h-[10px] top-0 right-full bg-inherit" style={{clipPath: 'path("M11 -1 L11 10 L10 10 A10 10 0 0 0 0 0 L0 -1 Z")'}}/>
|
||||
<span className="absolute w-[10px] h-[10px] bottom-0 right-full bg-inherit" style={{clipPath: 'path("M11 11 L11 0 L10 0 A10 10 0 0 1 0 10 L 0 11 Z")'}}/>
|
||||
|
||||
<div className="flex flex-col justify-center items-center gap-1 w-full h-full overflow-hidden transition-opacity opacity-0 group-hover:opacity-100">
|
||||
<div className="flex flex-col justify-center items-center gap-1 w-full h-full overflow-hidden opacity-0 group-hover:opacity-100">
|
||||
{onDelete && <BsmButton className="w-6 h-6 p-[2px] rounded-md !bg-inherit hover:!bg-main-color-2" iconClassName="w-full h-full brightness-150 saturate-50" iconColor={color} icon="trash" withBar={false} onClick={e => {e.stopPropagation(); openPreview()}}/>}
|
||||
<BsmButton className="w-6 h-6 p-[2px] rounded-md !bg-inherit hover:!bg-main-color-2" iconClassName="w-full h-full brightness-150 saturate-50" iconColor={color} icon="eye" withBar={false} onClick={e => {e.stopPropagation(); openPreview()}}/>
|
||||
{mapId && <BsmButton className="w-6 h-6 p-1 rounded-md !bg-inherit hover:!bg-main-color-2" iconClassName="w-full h-full brightness-150 saturate-50" iconColor={color} icon="twitch" withBar={false} onClick={e => {e.stopPropagation(); copyBsr()}}/>}
|
||||
|
||||
Reference in New Issue
Block a user