mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
move beat-saver service in main
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
export function splitIntoChunk<T = unknown>(arr: T[], chunkSize: number): T[][] {
|
||||
const resArr = [];
|
||||
for(let i = 0; i < arr.length; i += chunkSize){
|
||||
resArr.push(arr.slice(i, i + chunkSize));
|
||||
}
|
||||
return resArr;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ipcMain } from "electron";
|
||||
import { UtilsService } from "../services/utils.service";
|
||||
import { IpcRequest } from "shared/models/ipc";
|
||||
import { SearchParams } from "shared/models/maps/beat-saver.model";
|
||||
import { BeatSaverService } from "../services/thrid-party/beat-saver/beat-saver.service";
|
||||
|
||||
ipcMain.on("bsv-search-map", async (event, request: IpcRequest<SearchParams>) => {
|
||||
const utlis = UtilsService.getInstance();
|
||||
const bsvService = BeatSaverService.getInstance();
|
||||
|
||||
bsvService.searchMaps(request.args).then(maps => {
|
||||
utlis.ipcSend(request.responceChannel, {success: true, data: maps});
|
||||
}).catch(e => {
|
||||
utlis.ipcSend(request.responceChannel, {success: false, error: e});
|
||||
})
|
||||
});
|
||||
|
||||
ipcMain.on("bsv-bet-map-details-from-hashs", async (event, request: IpcRequest<string[]>) => {
|
||||
const utlis = UtilsService.getInstance();
|
||||
const bsvService = BeatSaverService.getInstance();
|
||||
|
||||
bsvService.getMapDetailsFromHashs(request.args).then(maps => {
|
||||
utlis.ipcSend(request.responceChannel, {success: true, data: maps});
|
||||
}).catch(e => {
|
||||
utlis.ipcSend(request.responceChannel, {success: false, error: e});
|
||||
})
|
||||
});
|
||||
@@ -8,3 +8,4 @@ import './launcher-ipcs';
|
||||
import './window-manager-ipcs';
|
||||
import './bs-mods-ipcs';
|
||||
import './bs-maps-ipcs';
|
||||
import './beat-saver-ipcs'
|
||||
+6
-3
@@ -1,6 +1,7 @@
|
||||
import { ApiResult } from "renderer/models/api/api.model";
|
||||
import { BsvMapDetail } from "shared/models/maps";
|
||||
import { MapFilter, SearchOrder, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
|
||||
import { MapFilter, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
|
||||
import fetch from "node-fetch"
|
||||
|
||||
export class BeatSaverApiService {
|
||||
|
||||
@@ -90,11 +91,13 @@ export class BeatSaverApiService {
|
||||
|
||||
public async searchMaps(search: SearchParams): Promise<ApiResult<SearchResponse>>{
|
||||
|
||||
console.log(search);
|
||||
|
||||
const url = new URL(`${this.bsaverApiUrl}/search/text/${search?.page ?? 0}`);
|
||||
|
||||
url.search = this.searchParamsToUrlParams(search).toString();
|
||||
|
||||
const res = await fetch(url);
|
||||
const res = await fetch(url.toString());
|
||||
|
||||
console.log(res);
|
||||
|
||||
@@ -102,7 +105,7 @@ export class BeatSaverApiService {
|
||||
return {status: res.status, data: null};
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
const data: any = await res.json();
|
||||
|
||||
return {status: res.status, data};
|
||||
|
||||
+16
-38
@@ -1,9 +1,6 @@
|
||||
import { splitIntoChunk } from "renderer/helpers/array-tools";
|
||||
import { of } from "rxjs";
|
||||
import { Observable } from "rxjs";
|
||||
import { splitIntoChunk } from "../../../helpers/array-tools";
|
||||
import { BsvMapDetail } from "shared/models/maps";
|
||||
import { SearchParams } from "shared/models/maps/beat-saver.model";
|
||||
import { OsDiagnosticService } from "../os-diagnostic.service";
|
||||
import { BeatSaverApiService } from "./beat-saver-api.service";
|
||||
|
||||
export class BeatSaverService {
|
||||
@@ -16,17 +13,16 @@ export class BeatSaverService {
|
||||
}
|
||||
|
||||
private readonly bsaverApi: BeatSaverApiService;
|
||||
private readonly os: OsDiagnosticService;
|
||||
|
||||
private readonly cachedMapsDetails = new Map<string, BsvMapDetail>()
|
||||
|
||||
private readonly cachedMapsDetails = new Map<string, BsvMapDetail>();
|
||||
|
||||
private constructor(){
|
||||
this.bsaverApi = BeatSaverApiService.getInstance();
|
||||
this.os = OsDiagnosticService.getInstance();
|
||||
}
|
||||
|
||||
public getMapDetailsFromHashs(hashs: string[]): Observable<BsvMapDetail[]>{
|
||||
public async getMapDetailsFromHashs(hashs: string[]): Promise<BsvMapDetail[]>{
|
||||
|
||||
console.log(hashs);
|
||||
|
||||
const filtredHashs = hashs.map(h => h.toLowerCase()).filter(hash => !Array.from(this.cachedMapsDetails.keys()).includes(hash));
|
||||
const chunkHash = splitIntoChunk(filtredHashs, 50);
|
||||
@@ -38,37 +34,19 @@ export class BeatSaverService {
|
||||
return res;
|
||||
}, [] as BsvMapDetail[]);
|
||||
|
||||
if(this.os.isOffline){
|
||||
return of(mapDetails);
|
||||
for(const hashs of chunkHash){
|
||||
|
||||
const res = await this.bsaverApi.getMapsDetailsByHashs(hashs);
|
||||
|
||||
if(res.status === 200){
|
||||
mapDetails.push(...Object.values<BsvMapDetail>(res.data).filter(detail => !!detail));
|
||||
mapDetails.forEach(detail => {
|
||||
this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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).filter(detail => !!detail));
|
||||
mapDetails.forEach(detail => {
|
||||
this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail);
|
||||
});
|
||||
}
|
||||
|
||||
if(mapDetails.length > 0){
|
||||
observer.next(mapDetails);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
observer.complete();
|
||||
})()
|
||||
});
|
||||
return mapDetails;
|
||||
}
|
||||
|
||||
public searchMaps(search: SearchParams): Promise<BsvMapDetail[]>{
|
||||
@@ -13,6 +13,7 @@ import { PageStateService } from "./services/page-state.service";
|
||||
import { MapsPage } from "./pages/maps-page.component";
|
||||
import "tailwindcss/tailwind.css";
|
||||
import { BsmIframeView } from "./components/shared/bsm-map-preview.component";
|
||||
import 'tippy.js/dist/tippy.css';
|
||||
|
||||
export default function App() {
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { BsmDropdownButton } from "renderer/components/shared/bsm-dropdown-butto
|
||||
import { BsmSelect, BsmSelectOption } from "renderer/components/shared/bsm-select.component";
|
||||
import { useObservable } from "renderer/hooks/use-observable.hook";
|
||||
import { BSV_SORT_ORDER } from "renderer/partials/beat-saver/sort-order";
|
||||
import { BeatSaverService } from "renderer/services/beat-saver/beat-saver.service";
|
||||
import { BeatSaverService } from "renderer/services/thrird-partys/beat-saver.service";
|
||||
import { MapsDownloaderService } from "renderer/services/maps-downloader.service";
|
||||
import { MapsManagerService } from "renderer/services/maps-manager.service";
|
||||
import { ModalComponent } from "renderer/services/modale.service";
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
import { CSSProperties, SyntheticEvent, useState } from "react";
|
||||
import { CSSProperties, forwardRef, SyntheticEvent, useState } from "react";
|
||||
|
||||
export function BsmImage({className, image, errorImage, placeholder, loading, style}: {className?: string, image: string, errorImage?: string, placeholder?: string, loading?: "lazy"|"eager", style?: CSSProperties}) {
|
||||
type Props = {
|
||||
className?: string,
|
||||
image: string,
|
||||
errorImage?: string,
|
||||
placeholder?: string,
|
||||
loading?: "lazy"|"eager",
|
||||
style?: CSSProperties
|
||||
title?: string,
|
||||
onClick?: (e: MouseEvent) => void
|
||||
}
|
||||
|
||||
export const BsmImage = forwardRef(({className, image, errorImage, placeholder, loading, style, title, onClick}: Props, ref) => {
|
||||
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
@@ -22,6 +33,7 @@ export function BsmImage({className, image, errorImage, placeholder, loading, st
|
||||
}
|
||||
|
||||
return (
|
||||
<img className={`${className} pointer-events-none`} src={image} loading={loading} onLoad={handleLoaded} onError={handleError} style={styles}/>
|
||||
// @ts-ignore
|
||||
<img ref={ref} title={title} className={className} src={image} loading={loading} onLoad={handleLoaded} onError={handleError} style={styles} onClick={(e) => onClick?.(e)}/>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ import { finalize } from "rxjs/operators";
|
||||
import { Subject, Observable } from "rxjs";
|
||||
import { BSVersion } from "shared/bs-version.interface";
|
||||
import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface";
|
||||
import { BeatSaverService } from "./beat-saver/beat-saver.service";
|
||||
import { BeatSaverService } from "./thrird-partys/beat-saver.service";
|
||||
import { IpcService } from "./ipc.service";
|
||||
import { ModalExitCode, ModalService } from "./modale.service";
|
||||
import { DeleteMapsModal } from "renderer/components/modal/modal-types/delete-maps-modal.component";
|
||||
@@ -47,7 +47,7 @@ export class MapsManagerService {
|
||||
|
||||
if(!withDetails){ return obs.complete(); }
|
||||
|
||||
this.bsaver.getMapDetailsFromHashs(res.data.map(localMap => localMap.hash)).pipe(finalize(() => obs.complete())).subscribe(mapsDetails => {
|
||||
this.bsaver.getMapDetailsFromHashs(res.data.map(localMap => localMap.hash)).then(mapsDetails => {
|
||||
mapsDetails.forEach(details => {
|
||||
const corespondingMap = res.data.find(localMap => localMap.hash === details.versions.find(details => details?.hash === localMap.hash)?.hash);
|
||||
if(!corespondingMap){ return; }
|
||||
@@ -159,6 +159,10 @@ export class MapsManagerService {
|
||||
this.progressBar.hide(true);
|
||||
}
|
||||
|
||||
public async enableDeepLink(): Promise<boolean>{
|
||||
return true;
|
||||
}
|
||||
|
||||
public get versionLinked$(): Observable<BSVersion>{
|
||||
return this.lastLinkedVersion$.asObservable();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { BsvMapDetail } from "shared/models/maps";
|
||||
import { SearchParams } from "shared/models/maps/beat-saver.model";
|
||||
import { IpcService } from "../ipc.service";
|
||||
|
||||
export class BeatSaverService {
|
||||
|
||||
private static instance: BeatSaverService;
|
||||
|
||||
public static getInstance(): BeatSaverService{
|
||||
if(!BeatSaverService.instance){ BeatSaverService.instance = new BeatSaverService(); }
|
||||
return BeatSaverService.instance;
|
||||
}
|
||||
private readonly ipc: IpcService;
|
||||
|
||||
private constructor(){
|
||||
this.ipc = IpcService.getInstance();
|
||||
}
|
||||
|
||||
public async getMapDetailsFromHashs(hashs: string[]): Promise<BsvMapDetail[]>{
|
||||
const res = await this.ipc.send<BsvMapDetail[], string[]>("bsv-bet-map-details-from-hashs", {args: hashs});
|
||||
return res.data ?? [];
|
||||
}
|
||||
|
||||
public async searchMaps(search: SearchParams): Promise<BsvMapDetail[]>{
|
||||
const res = await this.ipc.send<BsvMapDetail[], SearchParams>("bsv-search-map", {args: search});
|
||||
return res.data ?? []
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user