diff --git a/src/main/ipcs/bs-model-ipcs.ts b/src/main/ipcs/bs-model-ipcs.ts index 1e4d3914..b4e2eaaa 100644 --- a/src/main/ipcs/bs-model-ipcs.ts +++ b/src/main/ipcs/bs-model-ipcs.ts @@ -76,4 +76,10 @@ ipc.on<{version: BSVersion, type: MSModelType}>("get-version-models", async (req ipc.on<{version: BSVersion, models: BsmLocalModel[], outPath: string}>("export-models", async (req, reply) => { const models = LocalModelsManagerService.getInstance(); reply(await models.exportModels(req.args.outPath, req.args.version, req.args.models)); +}); + +ipc.on("delete-models", async (req, reply) => { + console.log("LAAAAA"); + const models = LocalModelsManagerService.getInstance(); + reply(models.deleteModels(req.args)); }); \ No newline at end of file diff --git a/src/main/services/additional-content/local-models-manager.service.ts b/src/main/services/additional-content/local-models-manager.service.ts index e41174dd..b9da74db 100644 --- a/src/main/services/additional-content/local-models-manager.service.ts +++ b/src/main/services/additional-content/local-models-manager.service.ts @@ -11,7 +11,7 @@ import path from "path"; import { RequestService } from "../request.service"; import { copyFileSync } from "fs-extra"; import sanitize from "sanitize-filename"; -import { Progression, ensureFolderExist } from "../../helpers/fs.helpers"; +import { Progression, ensureFolderExist, unlinkPath } from "../../helpers/fs.helpers"; import { MODEL_FILE_EXTENSIONS, MODEL_TYPES, MODEL_TYPE_FOLDERS } from "../../../shared/models/models/constants"; import { InstallationLocationService } from "../installation-location.service"; import { Observable, lastValueFrom } from "rxjs"; @@ -168,6 +168,7 @@ export class LocalModelsManagerService { } public async exportModels(output: string, version?: BSVersion, models?: BsmLocalModel[]): Promise>{ + // TOTO NOT ASYNC const archive = new Archive(output); if(models?.length){ models.forEach(model => archive.addFile(model.path)); @@ -181,7 +182,24 @@ export class LocalModelsManagerService { return archive.finalize(); } + public deleteModels(models: BsmLocalModel[]): Observable{ + return new Observable(subscriber => { + (async () => { + const progression: Progression = { + total: models.length, + current: 0, + extra: null + }; + for(const model of models){ + await unlinkPath(model.path); + progression.current += 1; + subscriber.next(progression); + } + + })().catch(e => subscriber.error(e)).finally(() => subscriber.complete()); + }); + } public enableDeepLinks(): boolean{ return Array.from(Object.values(this.DEEP_LINKS)).every(link => this.deepLink.registerDeepLink(link)); diff --git a/src/renderer/components/models-management/models-grid.component.tsx b/src/renderer/components/models-management/models-grid.component.tsx index 3e00d5f6..48166e1d 100644 --- a/src/renderer/components/models-management/models-grid.component.tsx +++ b/src/renderer/components/models-management/models-grid.component.tsx @@ -30,10 +30,17 @@ export const ModelsGrid = forwardRef(({className, version, type}: Props, forward const hasModels = !isLoading && models?.extra.length; useImperativeHandle(forwardRef, () => ({ + getModels: () => { + console.log(type, models?.extra); + return models?.extra ?? []; + }, getSelectedModels: () => { return Array.from(modelsSelected) }, - }), [modelsSelected]); + reloadModels: () => { + setModelsLoadObservable(() => modelsManager.$getModels(type, version)); + } + }), [modelsSelected, models]); useOnUpdate(() => { if(!isVisible){ return; } diff --git a/src/renderer/components/models-management/models-panel.component.tsx b/src/renderer/components/models-management/models-panel.component.tsx index 7a29736f..614304f6 100644 --- a/src/renderer/components/models-management/models-panel.component.tsx +++ b/src/renderer/components/models-management/models-panel.component.tsx @@ -1,5 +1,5 @@ import { BSVersion } from "shared/bs-version.interface"; -import { useRef, useState } from "react"; +import { useRef, useState, MutableRefObject } from "react"; import { ModelsTabsNavbar } from "./models-tabs-navbar.component"; import { ModelsGrid } from "./models-grid.component"; import { MSModelType } from "shared/models/models/model-saber.model"; @@ -14,20 +14,40 @@ export function ModelsPanel({version}: {version?: BSVersion}) { const [avatarsRef, sabersRef, platformsRef, bloqsRef] = [useRef(null), useRef(null), useRef(null), useRef(null)]; const [modelTypeTab, setModelTypeTab] = useState(ModelTabType.Avatars); - const getSelectedModels = () => [avatarsRef, sabersRef, platformsRef, bloqsRef].map(ref =>(ref.current?.getSelectedModels() as BsmLocalModel[])).flat() + console.log(modelTypeTab); + + const getSelectedModels = (ref?: MutableRefObject) => { + if(ref){ return (ref.current?.getSelectedModels() as BsmLocalModel[]); } + return [avatarsRef, sabersRef, platformsRef, bloqsRef].map(ref =>(ref.current?.getSelectedModels() as BsmLocalModel[])).flat() + }; + const getAllModels = (ref?: MutableRefObject) => { + if(ref){ return (ref.current?.getModels() as BsmLocalModel[]); } + return [avatarsRef, sabersRef, platformsRef, bloqsRef].map(ref =>(ref.current?.getModels() as BsmLocalModel[])).flat(); + } + const reloadModels = (ref?: MutableRefObject) => { + if(ref){ return (ref.current?.reloadModels()); } + return [avatarsRef, sabersRef, platformsRef, bloqsRef].forEach(ref => ref.current?.reloadModels()) + }; + + const getActiveTabRef = (activeTab: ModelTabType) => [avatarsRef, sabersRef, platformsRef, bloqsRef][modelTypeTab]; const exportModels = () => { modelsManager.exportModels(getSelectedModels(), version); } const deleteModels = () => { - modelsManager.deleteModels(getSelectedModels(), version); + const activeTab = getActiveTabRef(modelTypeTab); + const models = getSelectedModels(activeTab)?.length ? getSelectedModels(activeTab) : getAllModels(activeTab); + modelsManager.deleteModels(models, version).then(deleted => { + if(!deleted){ return; } + reloadModels(activeTab); + }); } - const threeDotsItems = useConstant(() => [ + const threeDotsItems: DropDownItem[] = [ {text: "TODO TRANSLATE EXPORT", onClick: exportModels, icon: "export"}, {text: "TODO TRANSLATE DELETE", onClick: deleteModels, icon: "trash"}, - ]); + ]; return (
diff --git a/src/renderer/services/models-management/models-manager.service.ts b/src/renderer/services/models-management/models-manager.service.ts index 395ee6e9..9cef601c 100644 --- a/src/renderer/services/models-management/models-manager.service.ts +++ b/src/renderer/services/models-management/models-manager.service.ts @@ -112,11 +112,11 @@ export class ModelsManagerService { } - public async deleteModels(models: BsmLocalModel[], version?: BSVersion){ + public async deleteModels(models: BsmLocalModel[], version?: BSVersion): Promise{ const types = Array.from(new Set(models.map(m => m.type))); - const modelsLinked = await (async () => { + const modelsLinked = await (async () => { // USE AND COMPUTE ONLY IF NEEDED (askModal) for(const type of types){ if(!(await this.isModelsLinked(version, type))){ continue; } return true; @@ -127,7 +127,18 @@ export class ModelsManagerService { const askModal = models.length > 1 || !this.config.get(ModelsManagerService.REMEMBER_CHOICE_DELETE_MODEL_KEY); - console.log(modelsLinked, askModal); + // ADD MODAL HERE + + const showProgressBar = this.progressBar.require(); + + const progress$ = this.ipc.sendV2("delete-models", {args: models}).pipe(map(progress => (progress.current / progress.total) * 100)); + + if(showProgressBar){ this.progressBar.show(progress$); } + + return lastValueFrom(progress$) + .catch(() => false) + .then(() => true) + .finally(() => this.progressBar.hide(true)); }