mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
we can now download maps from bsaver
This commit is contained in:
@@ -45,13 +45,19 @@ export class BeatSaverService {
|
||||
return new Observable(observer => {
|
||||
(async () => {
|
||||
|
||||
if(mapDetails.length > 0){
|
||||
observer.next(mapDetails);
|
||||
}
|
||||
|
||||
for(const hashs of chunkHash){
|
||||
|
||||
const res = await this.bsaverApi.getMapsDetailsByHashs(hashs);
|
||||
|
||||
if(res.status === 200){
|
||||
mapDetails.push(...Object.values<BsvMapDetail>(res.data));
|
||||
mapDetails.forEach(detail => this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail));
|
||||
mapDetails.push(...Object.values<BsvMapDetail>(res.data).filter(detail => !!detail));
|
||||
mapDetails.forEach(detail => {
|
||||
this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail);
|
||||
});
|
||||
}
|
||||
|
||||
if(mapDetails.length > 0){
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import { DownloadMapsModal } from "renderer/components/modal/modal-types/download-maps-modal.component";
|
||||
import { map, filter } from "rxjs/operators";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
import { BSVersion } from "shared/bs-version.interface";
|
||||
import { ModalResponse, ModalService } from "./modale.service";
|
||||
import { Observable } from "rxjs";
|
||||
import { ProgressBarService } from "./progress-bar.service";
|
||||
import { ProgressionInterface } from "shared/models/progress-bar";
|
||||
import { BsvMapDetail } from "shared/models/maps";
|
||||
import { IpcService } from "./ipc.service";
|
||||
import { getMapZipUrlFromMapDetails } from "renderer/helpers/maps-utils";
|
||||
import { OsDiagnosticService } from "./os-diagnostic.service";
|
||||
import { timer } from "rxjs";
|
||||
import equal from "fast-deep-equal/es6";
|
||||
import { CSSProperties } from "react";
|
||||
|
||||
export class MapsDownloaderService {
|
||||
|
||||
@@ -12,15 +24,111 @@ export class MapsDownloaderService {
|
||||
}
|
||||
|
||||
private readonly modals: ModalService;
|
||||
private readonly progressBar: ProgressBarService;
|
||||
private readonly ipc: IpcService;
|
||||
private readonly os: OsDiagnosticService;
|
||||
|
||||
private readonly mapsQueue$: BehaviorSubject<MapDownload[]> = new BehaviorSubject([]);
|
||||
private readonly currentDownload$: BehaviorSubject<MapDownload> = new BehaviorSubject(null);
|
||||
private queueMaxLenght = 0;
|
||||
private downloadedListerners: ((map: BsvMapDetail, version: BSVersion) => void)[] = [];
|
||||
public readonly progressBarStyle: CSSProperties = {zIndex: 100000, position: "fixed", bottom: "10px", right: 0};
|
||||
|
||||
private constructor(){
|
||||
this.modals = ModalService.getInsance();
|
||||
this.progressBar = ProgressBarService.getInstance();
|
||||
this.ipc = IpcService.getInstance();
|
||||
this.os = OsDiagnosticService.getInstance();
|
||||
|
||||
this.mapsQueue$.pipe(filter(queue => queue.length === 1 && !this.isDownloading)).subscribe(() => this.startDownloadMaps());
|
||||
this.mapsQueue$.pipe(filter(queue => queue.length === 0)).subscribe(() => this.queueMaxLenght = 0);
|
||||
}
|
||||
|
||||
public openDownloadMapModal(version?: BSVersion): Promise<ModalResponse<void>>{
|
||||
private async startDownloadMaps(){
|
||||
|
||||
this.progressBar.show(this.downloadProgress$, true, this.progressBarStyle);
|
||||
|
||||
await timer(2000).toPromise();
|
||||
|
||||
while(this.mapsQueue$.value.at(0)){
|
||||
const toDownload = this.mapsQueue$.value.at(0);
|
||||
this.currentDownload$.next(toDownload);
|
||||
const downloaded = await this.downloadMap(toDownload.map, toDownload.version);
|
||||
|
||||
if(downloaded){
|
||||
this.downloadedListerners.forEach(func => func(toDownload.map, toDownload.version));
|
||||
}
|
||||
|
||||
const newArr = [...this.mapsQueue$.value];
|
||||
newArr.shift();
|
||||
this.mapsQueue$.next(newArr);
|
||||
}
|
||||
|
||||
await timer(500).toPromise();
|
||||
|
||||
return this.modals.openModal(DownloadMapsModal, version);
|
||||
|
||||
this.currentDownload$.next(null);
|
||||
this.progressBar.hide(true);
|
||||
}
|
||||
|
||||
private async downloadMap(map: BsvMapDetail, version: BSVersion): Promise<boolean>{
|
||||
if(this.os.isOffline){ return false }
|
||||
const res = await this.ipc.send("download-map", {args: {zipUrl: getMapZipUrlFromMapDetails(map), version}});
|
||||
return res.success;
|
||||
}
|
||||
|
||||
public async openDownloadMapModal(version?: BSVersion): Promise<ModalResponse<void>>{
|
||||
const res = await this.modals.openModal(DownloadMapsModal, version);
|
||||
this.progressBar.setStyle(null);
|
||||
return res;
|
||||
}
|
||||
|
||||
public addMapToDownload(downloadMap: MapDownload){
|
||||
if(this.mapsQueue$.value.length === 0 && !this.progressBar.require()){ return; }
|
||||
this.queueMaxLenght++;
|
||||
this.mapsQueue$.next([...this.mapsQueue$.value, downloadMap]);
|
||||
}
|
||||
|
||||
public removeMapToDownload(downloadMap: MapDownload){
|
||||
const newArr = [...this.mapsQueue$.value];
|
||||
const index = newArr.findIndex(toDownload => toDownload.map.id === downloadMap.map.id && equal(toDownload.version, downloadMap.version));
|
||||
if(index < 0){ return; }
|
||||
newArr.splice(index, 1);
|
||||
this.mapsQueue$.next(newArr);
|
||||
}
|
||||
|
||||
public get downloadProgress$(): Observable<ProgressionInterface> {
|
||||
return this.mapsQueue$.pipe(map<MapDownload[], ProgressionInterface>(download => {
|
||||
let progress = this.queueMaxLenght === 0 ? 100 : ((100 / this.queueMaxLenght) * (this.queueMaxLenght - download.length)) + .1;
|
||||
progress = progress > 100 ? 100 : progress;
|
||||
return {progression: (progress), label: download.at(0)?.map.name || ""};
|
||||
}));
|
||||
}
|
||||
|
||||
public get currentMapDownload$(): Observable<MapDownload> {
|
||||
return this.currentDownload$.asObservable();
|
||||
}
|
||||
|
||||
public get mapsInQueue$(): Observable<MapDownload[]>{
|
||||
return this.mapsQueue$.asObservable();
|
||||
}
|
||||
|
||||
public addOnMapDownloadedListener(func: (map: BsvMapDetail, version: BSVersion) => void){
|
||||
this.downloadedListerners.push(func);
|
||||
}
|
||||
|
||||
public removeOnMapDownloadedListene(func: (map: BsvMapDetail, version: BSVersion) => void){
|
||||
const funcIndex = this.downloadedListerners.indexOf(func);
|
||||
if(funcIndex < 0){ return; }
|
||||
this.downloadedListerners.splice(funcIndex, 1);
|
||||
}
|
||||
|
||||
public get isDownloading(): boolean{
|
||||
return !!this.currentDownload$.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export interface MapDownload {
|
||||
map: BsvMapDetail
|
||||
version: BSVersion
|
||||
}
|
||||
@@ -34,12 +34,16 @@ export class MapsManagerService {
|
||||
this.progressBar = ProgressBarService.getInstance();
|
||||
}
|
||||
|
||||
public getMaps(version?: BSVersion): Observable<BsmLocalMap[]>{
|
||||
public getMaps(version?: BSVersion, withDetails = true): Observable<BsmLocalMap[]>{
|
||||
return new Observable(obs => {
|
||||
this.ipcService.send<BsmLocalMap[], BSVersion>("get-version-maps", {args: version}).then(res => {
|
||||
if(!res.success){ return obs.next(null);}
|
||||
obs.next(res.data);
|
||||
|
||||
if(!withDetails){ return obs.complete(); }
|
||||
|
||||
console.log("GET DETAILS");
|
||||
|
||||
this.bsaver.getMapDetailsFromHashs(res.data.map(localMap => localMap.hash)).pipe(finalize(() => obs.complete())).subscribe(mapsDetails => {
|
||||
mapsDetails.forEach(details => {
|
||||
res.data.find(localMap => localMap.hash === details.versions.find(details => details?.hash === localMap.hash)?.hash).bsaverInfo = details
|
||||
|
||||
@@ -86,6 +86,11 @@ export class ProgressBarService{
|
||||
return true;
|
||||
}
|
||||
|
||||
public setStyle(style: CSSProperties){
|
||||
console.log("SET STYLE", style);
|
||||
this._style$.next(style);
|
||||
}
|
||||
|
||||
public get progressData$(): Observable<ProgressionInterface>{ return this._progression$.asObservable(); }
|
||||
public get progress$(): Observable<number>{ return this._progression$.pipe(map(data => data.progression)); }
|
||||
public get progressLabel(): Observable<string>{ return this._progression$.pipe(map(data => data?.label)); }
|
||||
|
||||
Reference in New Issue
Block a user