From 57e0c73a31e289e615b9d9bf900a4b0c90f80b74 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 7 Dec 2022 01:33:24 +0100 Subject: [PATCH] fix rerendering AND fix downloader map folder name --- package-lock.json | 5 +--- package.json | 1 + src/main/ipcs/bs-maps-ipcs.ts | 5 ++-- .../maps/local-maps-manager.service.ts | 14 ++++++---- .../local-maps-list-panel.component.tsx | 15 ++++++---- .../map-item.component.tsx | 28 +++++++++++-------- .../download-maps-modal.component.tsx | 19 +++++++------ .../services/maps-downloader.service.ts | 2 +- 8 files changed, 50 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ffd2587..f2e1d635 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12111,7 +12111,6 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, "requires": { "truncate-utf8-bytes": "^1.0.0" } @@ -13207,7 +13206,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", - "dev": true, "requires": { "utf8-byte-length": "^1.0.1" } @@ -13567,8 +13565,7 @@ "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", - "dev": true + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==" }, "util-deprecate": { "version": "1.0.2", diff --git a/package.json b/package.json index 8e0a429d..83820427 100644 --- a/package.json +++ b/package.json @@ -248,6 +248,7 @@ "react-visibility-sensor": "^5.1.1", "regedit": "^5.1.1", "rxjs": "^7.5.6", + "sanitize-filename": "^1.6.3", "semver": "^7.3.8", "tailwind-scrollbar-hide": "^1.1.7", "tailwindcss-scoped-groups": "^2.0.0", diff --git a/src/main/ipcs/bs-maps-ipcs.ts b/src/main/ipcs/bs-maps-ipcs.ts index 146f4a1f..ae435007 100644 --- a/src/main/ipcs/bs-maps-ipcs.ts +++ b/src/main/ipcs/bs-maps-ipcs.ts @@ -4,6 +4,7 @@ import { UtilsService } from "../services/utils.service"; import { BSVersion } from "shared/bs-version.interface"; import { IpcRequest } from "shared/models/ipc"; import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface"; +import { BsvMapDetail } from "shared/models/maps"; ipcMain.on('get-version-maps', (event, request: IpcRequest) => { const utilsService = UtilsService.getInstance(); @@ -60,11 +61,11 @@ ipcMain.on("delete-maps", async (event, request: IpcRequest<{version: BSVersion, }); }); -ipcMain.on("download-map", async (event, request: IpcRequest<{zipUrl: string, version: BSVersion}>) => { +ipcMain.on("download-map", async (event, request: IpcRequest<{map: BsvMapDetail, version: BSVersion}>) => { const utils = UtilsService.getInstance(); const maps = LocalMapsManagerService.getInstance(); - maps.downloadMap(request.args.zipUrl, request.args.version).then(() => { + maps.downloadMap(request.args.map, request.args.version).then(() => { utils.ipcSend(request.responceChannel, {success: true}); }).catch(err => { console.log(err); diff --git a/src/main/services/maps/local-maps-manager.service.ts b/src/main/services/maps/local-maps-manager.service.ts index 900be858..e7ea724f 100644 --- a/src/main/services/maps/local-maps-manager.service.ts +++ b/src/main/services/maps/local-maps-manager.service.ts @@ -1,6 +1,6 @@ import path from "path"; import { BSVersion } from "shared/bs-version.interface"; -import { RawMapInfoData } from "shared/models/maps"; +import { BsvMapDetail, RawMapInfoData } from "shared/models/maps"; import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface"; import { BSLocalVersionService } from "../bs-local-version.service"; import { InstallationLocationService } from "../installation-location.service"; @@ -10,6 +10,7 @@ import { lstatSync, symlinkSync, unlinkSync, readdirSync } from "fs"; import { copySync } from "fs-extra"; import StreamZip from "node-stream-zip"; import { RequestService } from "../request.service"; +import sanitize from "sanitize-filename"; export class LocalMapsManagerService { @@ -162,16 +163,19 @@ export class LocalMapsManagerService { } - public async downloadMap(zipUrl: string, version?: BSVersion){ + public async downloadMap(map: BsvMapDetail, version?: BSVersion){ - console.log(zipUrl, version); + if(!map.versions.at(0).hash){ throw "Cannot download map, no hash found"; } + + const zipUrl = `https://r2cdn.beatsaver.com/${map.versions.at(0).hash}.zip` const mapsFolder = await this.getMapsFolderPath(version); const {zip, zipPath} = await this.downloadMapZip(zipUrl); - const zipName = path.parse(zipPath).name; - const mapPath = path.join(mapsFolder, zipName); + const mapFolderName = sanitize(`${map.id}-${map.name}`); + + const mapPath = path.join(mapsFolder, mapFolderName); if(!zip){ throw `Cannot download ${zipUrl}`; } diff --git a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx index 994bfeea..796c0207 100644 --- a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx @@ -1,6 +1,6 @@ import { MapsManagerService } from "renderer/services/maps-manager.service" import { BSVersion } from "shared/bs-version.interface" -import { useEffect, useRef, useState } from "react" +import { useCallback, useEffect, useRef, useState } from "react" import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface" import { Subscription } from "rxjs" import { MapItem, ParsedMapDiff } from "./map-item.component" @@ -46,9 +46,11 @@ export function LocalMapsListPanel({version, className, filter, search} : Props) subs.push(mapsManager.getMaps(version).subscribe(localMaps => setMaps(() => [...localMaps]))); } - const handleDelete = (map: BsmLocalMap) => { + const handleDelete = useCallback((hash: string) => { + const map = maps.find(map => map.hash === hash); + console.log(maps); mapsManager.deleteMaps([map], version).then(res => res && loadMaps()) - } + }, [maps]); const extractMapDiffs = (map: BsmLocalMap): Map => { const res = new Map(); @@ -73,7 +75,7 @@ export function LocalMapsListPanel({version, className, filter, search} : Props) return res; } - const onMapSelected = (hash: string) => { + const onMapSelected = useCallback((hash: string) => { const hashs = [...selectedMaps]; if(hashs.some(selectedHash => selectedHash === hash)){ const i = hashs.findIndex(selectedHash => selectedHash === hash); @@ -83,7 +85,7 @@ export function LocalMapsListPanel({version, className, filter, search} : Props) hashs.push(hash); } setSelectedMaps(() => hashs); - } + }, [selectedMaps]); const isMapFitFilter = (map: BsmLocalMap): boolean => { @@ -199,8 +201,9 @@ export function LocalMapsListPanel({version, className, filter, search} : Props) 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={() => handleDelete(map)} + onDelete={handleDelete} onSelected={onMapSelected} + callBackParam={map.hash} />; } 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 0be1fe39..d0429b27 100644 --- a/src/renderer/components/maps-mangement-components/map-item.component.tsx +++ b/src/renderer/components/maps-mangement-components/map-item.component.tsx @@ -19,7 +19,7 @@ import { BsmBasicSpinner } from "../shared/bsm-basic-spinner/bsm-basic-spinner.c export type ParsedMapDiff = {type: BsvMapDifficultyType, name: string, stars: number} -export type MapItemProps = { +export type MapItemProps = { hash: string, title: string, autor: string, @@ -37,19 +37,18 @@ export type MapItemProps = { createdAt: string, selected?: boolean, downloading?: boolean, - onDelete?: (hash: string) => void, - onDownload?: (zipUrl: string) => void, - onSelected?: (hash: string) => void, - onCancelDownload?: (zipUrl: string) => void + callBackParam: T + onDelete?: (param: T) => void, + onDownload?: (param: T) => void, + onSelected?: (param: T) => void, + onCancelDownload?: (param: T) => void } -export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl, autorId, mapId, diffs, qualified, ranked, bpm, duration, likes, createdAt, selected, downloading, onDelete, onDownload, onSelected, onCancelDownload}: MapItemProps) => { +export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl, autorId, mapId, diffs, qualified, ranked, bpm, duration, likes, createdAt, selected, downloading, callBackParam, onDelete, onDownload, onSelected, onCancelDownload}: MapItemProps) => { const linkOpener = LinkOpenerService.getInstance(); const audioPlayer = AudioPlayerService.getInstance(); - - const color = useThemeColor("first-color"); const [hovered, setHovered] = useState(false); @@ -132,7 +131,7 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl, } return ( - setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5, transform: "translateZ(0) scale(1.0, 1.0)", backfaceVisibility: "hidden"}} onClick={e => {onSelected?.(hash)}}> + setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5, transform: "translateZ(0) scale(1.0, 1.0)", backfaceVisibility: "hidden"}} onClick={e => {onSelected?.(callBackParam)}}> {(hovered || selected) && onSelected && } {(diffsPanelHovered || bottomBarHovered) && ( @@ -209,9 +208,9 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
- {onDelete && !downloading && {e.stopPropagation(); onDelete(hash)}}/>} - {onDownload && !downloading && {e.stopPropagation(); onDownload(zipUrl)}}/>} - {onCancelDownload && !downloading && {e.stopPropagation(); onCancelDownload(zipUrl)}}/>} + {onDelete && !downloading && {e.stopPropagation(); onDelete(callBackParam)}}/>} + {onDownload && !downloading && {e.stopPropagation(); onDownload(callBackParam)}}/>} + {onCancelDownload && !downloading && {e.stopPropagation(); onCancelDownload(callBackParam)}}/>} {downloading && } {previewUrl && {e.stopPropagation(); openPreview()}}/>} {mapId && {e.stopPropagation(); copyBsr()}}/>} @@ -223,6 +222,11 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl, }, areEqual) function areEqual(prevProps: MapItemProps, nextProps: MapItemProps): boolean { + Array.from(Object.entries(prevProps)).forEach(v => { + if(!equal(prevProps[v[0]], nextProps[v[0]])){ + console.log(v[0]); + } + }); return equal(prevProps, nextProps); } diff --git a/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx b/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx index dd77aa5d..2a1573fe 100644 --- a/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx @@ -1,5 +1,5 @@ import { motion } from "framer-motion"; -import { useEffect, useRef, useState } from "react"; +import { Fragment, useCallback, useEffect, useRef, useState } from "react"; import { FilterPanel } from "renderer/components/maps-mangement-components/filter-panel.component"; import { MapItem, ParsedMapDiff } from "renderer/components/maps-mangement-components/map-item.component"; import { BsmButton } from "renderer/components/shared/bsm-button.component"; @@ -92,7 +92,7 @@ export const DownloadMapsModal: ModalComponent = ({data}) => { const inQueue = mapsInQueue.some(toDownload => equal(toDownload.version, data) && toDownload.map.id === map.id); return ( - = ({data}) => { diffs={extractMapDiffs(map)} songUrl={map.versions.at(0).previewURL} key={map.id} - onDownload={(!isMapOwned && !inQueue) && (() => {handleDownloadMap(map)})} - onCancelDownload={(inQueue && !isDownloading) && (() => {handleCancelDownload(map)})} + onDownload={(!isMapOwned && !inQueue) && (handleDownloadMap)} + onCancelDownload={(inQueue && !isDownloading) && (handleCancelDownload)} downloading={isDownloading} + callBackParam={map} /> ) } - const handleDownloadMap = (map: BsvMapDetail) => { - mapsDownloader.addMapToDownload({map, version: data}); - } + const handleDownloadMap = useCallback((map: BsvMapDetail) => { + mapsDownloader.addMapToDownload({map, version: data}) + }, []); - const handleCancelDownload = (map: BsvMapDetail) => { + const handleCancelDownload = useCallback((map: BsvMapDetail) => { mapsDownloader.removeMapToDownload({map, version: data}); - } + }, []); const handleSearch = () => { const searchParams: SearchParams = { diff --git a/src/renderer/services/maps-downloader.service.ts b/src/renderer/services/maps-downloader.service.ts index 7a03fffa..e9c09f35 100644 --- a/src/renderer/services/maps-downloader.service.ts +++ b/src/renderer/services/maps-downloader.service.ts @@ -72,7 +72,7 @@ export class MapsDownloaderService { private async downloadMap(map: BsvMapDetail, version: BSVersion): Promise{ if(this.os.isOffline){ return false } - const res = await this.ipc.send("download-map", {args: {zipUrl: getMapZipUrlFromMapDetails(map), version}}); + const res = await this.ipc.send("download-map", {args: {map, version}}); return res.success; }