mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
add cancel button, and kill on guard cancel
This commit is contained in:
@@ -35,6 +35,11 @@ ipcMain.on(`bs-download.${"[2FA]" as DownloadEventType}`, async (event, args: Ip
|
||||
BSInstallerService.getInstance().sendInputProcess(args.args);
|
||||
});
|
||||
|
||||
ipcMain.on('bs-download.kill', async (event, request: IpcRequest<void>) => {
|
||||
const res = await BSInstallerService.getInstance().killDownloadProcess();
|
||||
if(request.responceChannel){ UtilsService.getInstance().newIpcSenc(request.responceChannel, {success: res}); }
|
||||
});
|
||||
|
||||
ipcMain.on('bs-download.installation-folder', async (event, request: IpcRequest<void>) => {
|
||||
const installationFolder = InstallationLocationService.getInstance().installationDirectory;
|
||||
UtilsService.getInstance().newIpcSenc(request.responceChannel, {success: true, data: installationFolder});
|
||||
|
||||
@@ -2,17 +2,15 @@ import { ipcMain } from "electron";
|
||||
import { BSUninstallerService } from "../services/bs-uninstaller.service";
|
||||
import { BSVersion } from "main/services/bs-version-manager.service";
|
||||
import { UtilsService } from "../services/utils.service";
|
||||
import { IpcRequest } from "shared/models/ipc-models.model";
|
||||
|
||||
ipcMain.on('bs.uninstall', async (event, args: BSVersion) => {
|
||||
ipcMain.on('bs.uninstall', async (event, request: IpcRequest<BSVersion>) => {
|
||||
|
||||
const bsUninstallerService = BSUninstallerService.getInstance();
|
||||
const utilsService = UtilsService.getInstance();
|
||||
|
||||
bsUninstallerService.uninstall(args)
|
||||
.then(() => {
|
||||
utilsService.ipcSend("bs.uninstall.success");
|
||||
})
|
||||
.catch((e) => {
|
||||
utilsService.ipcSend("bs.uninstall.error", e)
|
||||
})
|
||||
if(!request.args){ utilsService.newIpcSenc(request.responceChannel, {success: false}); }
|
||||
|
||||
const res = await bsUninstallerService.uninstall(request.args);
|
||||
utilsService.newIpcSenc(request.responceChannel, {success: res});
|
||||
});
|
||||
@@ -20,12 +20,14 @@ export class BSUninstallerService {
|
||||
this.bsInstallerService = BSInstallerService.getInstance();
|
||||
}
|
||||
|
||||
public async uninstall(version :BSVersion){
|
||||
if(version.steam){ throw "Cannot uninstall steam version"; }
|
||||
const versionFolder = path.join(this.bsInstallerService.installationFolder, version.BSVersion);
|
||||
if(!this.utilsService.folderExist(versionFolder)){ throw "Version folder not exist"; }
|
||||
public async uninstall(version :BSVersion): Promise<boolean>{
|
||||
if(version.steam){ return false; }
|
||||
const versionFolder = path.join(this.bsInstallerService.installationFolder, version.BSVersion);
|
||||
if(!this.utilsService.folderExist(versionFolder)){ return true; }
|
||||
|
||||
return await this.utilsService.deleteFolder(versionFolder);
|
||||
}
|
||||
return this.utilsService.deleteFolder(versionFolder)
|
||||
.then(() => { return true; })
|
||||
.catch(() => { return false; })
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,8 +24,8 @@ export function GuardModal({resolver}: {resolver: (x: ModalResponse) => void}) {
|
||||
<input className="w-full bg-light-main-color-1 dark:bg-main-color-1 px-2 rounded-md py-[2px]" onChange={e => setGuardCode(e.target.value.toUpperCase())} value={guardCode} type="guard" name="guard" id="guard" placeholder={t("modals.guard.inputs.guard-code.placeholder")}/>
|
||||
</div>
|
||||
<div className="grid grid-flow-col grid-cols-2 gap-4">
|
||||
<BsmButton className="rounded-md text-center bg-gray-500 hover:brightness-110 transition-all" onClick={() => {resolver({exitCode: ModalExitCode.CANCELED})}} withBar={false} text={t("misc.cancel")}/>
|
||||
<BsmButton className="rounded-md text-center bg-blue-500 hover:brightness-110 transition-all" type="submit" withBar={false} text={t("modals.guard.buttons.submit")}/>
|
||||
<BsmButton className="rounded-md text-center bg-gray-500 hover:brightness-110 transition-all" onClick={() => {resolver({exitCode: ModalExitCode.CANCELED})}} withBar={false} text="misc.cancel"/>
|
||||
<BsmButton className="rounded-md text-center bg-blue-500 hover:brightness-110 transition-all" type="submit" withBar={false} text="modals.guard.buttons.submit"/>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
|
||||
@@ -7,17 +7,22 @@ import { useEffect, useState } from "react";
|
||||
import { combineLatest } from "rxjs";
|
||||
import { BSLauncherService, LaunchMods } from "renderer/services/bs-launcher.service";
|
||||
import { ConfigurationService } from "renderer/services/configuration.service";
|
||||
import { BsmButton } from "../shared/bsm-button.component";
|
||||
import { BSUninstallerService } from "renderer/services/bs-uninstaller.service";
|
||||
import { BSVersionManagerService } from "renderer/services/bs-version-manager.service";
|
||||
|
||||
export default function BsVersionItem(props: {version: BSVersion}) {
|
||||
export function BsVersionItem(props: {version: BSVersion}) {
|
||||
|
||||
const { state } = useLocation() as { state: BSVersion};
|
||||
|
||||
const [downloading, setDownloading] = useState(false);
|
||||
const [downloading, setDownloading] = useState(true);
|
||||
const [downloadPercent, setDownloadPercent] = useState(0);
|
||||
|
||||
const downloaderService = BsDownloaderService.getInstance();
|
||||
const verionManagerService = BSVersionManagerService.getInstance();
|
||||
const launcherService = BSLauncherService.getInstance();
|
||||
const configService = ConfigurationService.getInstance();
|
||||
const bsUninstallerService = BSUninstallerService.getInstance();
|
||||
|
||||
const isActive = (): boolean => {
|
||||
return props.version?.BSVersion === state?.BSVersion && props?.version.steam === state?.steam;
|
||||
@@ -33,6 +38,16 @@ export default function BsVersionItem(props: {version: BSVersion}) {
|
||||
)
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
const versionDownload = downloaderService.currentBsVersionDownload$.value;
|
||||
downloaderService.cancelDownload().then(async res => {
|
||||
if(!res.success){ return; }
|
||||
if(!downloaderService.isVerification){
|
||||
bsUninstallerService.uninstall(versionDownload).then(res => res && verionManagerService.askInstalledVersions());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
combineLatest([downloaderService.currentBsVersionDownload$, downloaderService.downloadProgress$]).subscribe(vals => {
|
||||
if(vals[0]?.BSVersion === props.version.BSVersion && vals[0]?.steam === props.version.steam){
|
||||
@@ -48,14 +63,19 @@ export default function BsVersionItem(props: {version: BSVersion}) {
|
||||
|
||||
|
||||
return (
|
||||
<div className={`outline-none relative p-[1px] overflow-hidden rounded-full flex justify-center content-center items-center mb-1 ${downloading && "nav-item-download"}`}>
|
||||
<div className="absolute top-0 w-full h-full" style={{transform: `translate(${-(100 - downloadPercent)}%, 0)`}}></div>
|
||||
<Link onDoubleClick={handleDoubleClick} to={`/bs-version/${props.version.BSVersion}`} state={props.version} className={`z-[1] flex cursor-pointer w-full justify-center content-center rounded-full items-center p-[3px] pl-2 pr-2 active:translate-y-[1px] hover:bg-light-main-color-3 dark:hover:bg-main-color-3 ${downloading && 'bg-black'} ${(isActive() && !downloading) && "bg-light-main-color-3 dark:bg-main-color-3"}`}>
|
||||
{props.version.steam && <SteamIcon className="w-[19px] h-[19px] mr-1"/>}
|
||||
{!props.version.steam && <BsNoteFill className="w-[19px] h-[19px] mr-1 text-red-600"/>}
|
||||
<span className="flex items-center justify-center content-center shrink-0 grow text-lg dark:text-gray-200 text-gray-800 font-bold min-w-0 tracking-wide">{props.version.BSVersion}</span>
|
||||
</Link>
|
||||
<div className={`outline-none relative p-[1px] overflow-hidden rounded-xl flex justify-center content-center items-center mb-1 ${downloading && "nav-item-download"}`}>
|
||||
<div className="progress absolute top-0 w-full h-full" style={{transform: `translate(${-(100 - downloadPercent)}%, 0)`}}></div>
|
||||
<div className={`wrapper z-[1] px-2 py-[3px] w-full rounded-xl ${downloading && 'bg-black'} ${!downloading && "hover:bg-light-main-color-3 dark:hover:bg-main-color-3"} ${(isActive() && !downloading) && "bg-light-main-color-3 dark:bg-main-color-3"}`}>
|
||||
<Link onDoubleClick={handleDoubleClick} to={`/bs-version/${props.version.BSVersion}`} state={props.version} className="flex justify-center items-center">
|
||||
{props.version.steam && <SteamIcon className="w-[19px] h-[19px] mr-1"/>}
|
||||
{!props.version.steam && <BsNoteFill className="w-[19px] h-[19px] mr-1 text-red-600"/>}
|
||||
<span className="flex items-center justify-center content-center shrink-0 grow text-lg dark:text-gray-200 text-gray-800 font-bold min-w-0 tracking-wide">{props.version.BSVersion}</span>
|
||||
</Link>
|
||||
{downloading && <BsmButton onClick={cancel} className="my-1 text-xs text-white rounded-md text-center hover:brightness-125" withBar={false} text="misc.cancel" typeColor="error"/>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
// className={`z-[1] flex cursor-pointer w-full justify-center content-center rounded-full items-center p-[3px] pl-2 pr-2 active:translate-y-[1px] hover:bg-light-main-color-3 dark:hover:bg-main-color-3 ${downloading && 'bg-black'} ${(isActive() && !downloading) && "bg-light-main-color-3 dark:bg-main-color-3"}`}
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.nav-item-download > div{
|
||||
.nav-item-download > .progress{
|
||||
background-size: 500% !important;
|
||||
background: linear-gradient(90deg, rgb(62, 51, 255), rgb(255, 0, 0), rgb(62, 51, 255), rgb(255, 0, 0));
|
||||
animation: rainbow 2s linear 0s infinite;
|
||||
}
|
||||
|
||||
.nav-item-download > a > *{
|
||||
.nav-item-download > .wrapper > a > *{
|
||||
animation: opacity 3s ease-in-out 0s infinite;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import './nav-bar.component.css'
|
||||
import BsVersionItem from './bs-version-item.component';
|
||||
import { BsVersionItem } from './bs-version-item.component';
|
||||
import { BSVersionManagerService } from '../../services/bs-version-manager.service';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ConfigurationService } from 'renderer/services/configuration.service';
|
||||
@@ -25,7 +25,7 @@ export function NavBar() {
|
||||
</div>
|
||||
</div>
|
||||
<div id='versions' className='w-fit relative left-[2px] grow overflow-y-hidden scrollbar-track-transparent scrollbar-thin scrollbar-thumb-neutral-900 hover:overflow-y-scroll'>
|
||||
{installedVersions && installedVersions.map((version) => <BsVersionItem key={JSON.stringify(version)} version={version}/>)}
|
||||
{installedVersions && installedVersions.map((version) => <BsVersionItem key={JSON.stringify(version)} version={version}/>)}
|
||||
</div>
|
||||
<div className='w-full p-2 flex flex-col items-center content-center justify-start'>
|
||||
<Link className='mb-2' to={"blah"}>
|
||||
|
||||
@@ -4,13 +4,15 @@ import React from "react";
|
||||
import { BsmImage } from "./bsm-image.component";
|
||||
import { useTranslation } from "renderer/hooks/use-translation.hook";
|
||||
|
||||
export function BsmButton({className, style, imgClassName, icon, image, text, type, active, withBar = true, disabled, onClickOutside, onClick}: {className?: string, style?: React.CSSProperties, imgClassName?: string, icon?: BsmIconType, image?: string, text?: string, type?: string, active?: boolean, withBar?: boolean, disabled?: boolean, onClickOutside?: (e: MouseEvent) => void, onClick?: (e: React.MouseEvent) => void}) {
|
||||
type BsmButtonType = "primary"|"success"|"cancel"|"error";
|
||||
|
||||
export function BsmButton({className, style, imgClassName, icon, image, text, type, active, withBar = true, disabled, onClickOutside, onClick, typeColor}: {className?: string, style?: React.CSSProperties, imgClassName?: string, icon?: BsmIconType, image?: string, text?: string, type?: string, active?: boolean, withBar?: boolean, disabled?: boolean, onClickOutside?: (e: MouseEvent) => void, onClick?: (e: React.MouseEvent) => void, typeColor?:BsmButtonType}) {
|
||||
|
||||
const t = useTranslation();
|
||||
|
||||
return (
|
||||
<OutsideClickHandler onOutsideClick={e => onClickOutside && onClickOutside(e)}>
|
||||
<div onClick={e => onClick && onClick(e)} className={`${className} overflow-hidden cursor-pointer group ${disabled && "brightness-75 cursor-not-allowed"}`} style={style}>
|
||||
<div onClick={e => onClick && onClick(e)} className={`${className} overflow-hidden cursor-pointer group ${disabled && "brightness-75 cursor-not-allowed"} ${typeColor == "error" && 'bg-red-500'}`} style={style}>
|
||||
{ image && <BsmImage image={image} className={imgClassName}/> }
|
||||
{ icon && <BsmIcon icon={icon} className="h-full w-full text-gray-800 dark:text-white"/> }
|
||||
{text && (type === "submit" ? <button className="w-full h-full">{t(text)}</button> : <span>{t(text)}</span>)}
|
||||
|
||||
@@ -20,12 +20,10 @@ export class BsDownloaderService{
|
||||
private readonly progressBarService: ProgressBarService;
|
||||
private readonly notificationService: NotificationService;
|
||||
|
||||
private _isVerification: boolean = false;
|
||||
|
||||
public readonly currentBsVersionDownload$: BehaviorSubject<BSVersion> = new BehaviorSubject(null);
|
||||
|
||||
public readonly downloadProgress$: BehaviorSubject<number> = new BehaviorSubject(0);
|
||||
public readonly downloadWarning$: BehaviorSubject<string> = new BehaviorSubject(null);
|
||||
public readonly downloadError$: BehaviorSubject<string> = new BehaviorSubject(null);
|
||||
|
||||
public readonly selectedBsVersion$: BehaviorSubject<BSVersion> = new BehaviorSubject(null);
|
||||
|
||||
public static getInstance(): BsDownloaderService{
|
||||
@@ -57,9 +55,9 @@ export class BsDownloaderService{
|
||||
});
|
||||
|
||||
this.ipcService.watch<void>("bs-download.[2FA]").subscribe(async response => {
|
||||
if(!response.success){ return; }
|
||||
if(!response.success){ this.ipcService.sendLazy("bs-download.kill"); return; }
|
||||
const res = await this.modalService.openModal(ModalType.GUARD_CODE);
|
||||
if(res.exitCode !== ModalExitCode.COMPLETED){ return; }
|
||||
if(res.exitCode !== ModalExitCode.COMPLETED){ this.ipcService.sendLazy("bs-download.kill"); return; }
|
||||
this.ipcService.sendLazy('bs-download.[2FA]', {args: res.data});
|
||||
});
|
||||
|
||||
@@ -75,13 +73,13 @@ export class BsDownloaderService{
|
||||
this.selectedBsVersion$.next(null);
|
||||
}
|
||||
|
||||
public async download(bsVersion: BSVersion, isVerification?: boolean): Promise<IpcResponse<DownloadEvent>>{
|
||||
if(this.progressBarService.visible$.value){
|
||||
this.notificationService.notifyError({title: "notifications.bs-download.errors.titles.already-downloading"});
|
||||
return {success: false};
|
||||
}
|
||||
public cancelDownload(): Promise<IpcResponse<boolean>>{
|
||||
return this.ipcService.send<boolean>("bs-download.kill");
|
||||
}
|
||||
|
||||
public async download(bsVersion: BSVersion, isVerification?: boolean): Promise<IpcResponse<DownloadEvent>>{
|
||||
this.progressBarService.show(this.downloadProgress$);
|
||||
this._isVerification = !!isVerification;
|
||||
|
||||
let promise;
|
||||
if(!this.authService.sessionExist()){
|
||||
@@ -106,12 +104,12 @@ export class BsDownloaderService{
|
||||
this.progressBarService.hide(true);
|
||||
this.resetDownload();
|
||||
res.success && this.notificationService.notifySuccess({title: `notifications.bs-download.success.titles.${isVerification ? "verification-finished" : "download-success"}`, duration: 3000});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public get isDownloading(): boolean{
|
||||
return !!this.currentBsVersionDownload$.value;
|
||||
}
|
||||
public get isDownloading(): boolean{ return !!this.currentBsVersionDownload$.value; }
|
||||
public get isVerification(): boolean{ return this._isVerification; }
|
||||
|
||||
public async getInstallationFolder(): Promise<string>{
|
||||
const res = await this.ipcService.send<string>("bs-download.installation-folder");
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
import { BSVersion } from "main/services/bs-version-manager.service";
|
||||
import { IpcService } from "./ipc.service";
|
||||
|
||||
export class BSUninstallerService{
|
||||
|
||||
private static instance: BSUninstallerService;
|
||||
|
||||
private readonly ipcService: IpcService;
|
||||
|
||||
public static getInstance(): BSUninstallerService{
|
||||
if(!BSUninstallerService.instance){ BSUninstallerService.instance = new BSUninstallerService(); }
|
||||
return BSUninstallerService.instance;
|
||||
}
|
||||
|
||||
private constructor(){};
|
||||
private constructor(){
|
||||
this.ipcService = IpcService.getInstance();
|
||||
};
|
||||
|
||||
public async uninstall(version: BSVersion){
|
||||
|
||||
const promise = new Promise<void>((reslove, reject) => {
|
||||
window.electron.ipcRenderer.once("bs.uninstall.error", (e) => {
|
||||
reject(e);
|
||||
})
|
||||
|
||||
window.electron.ipcRenderer.once("bs.uninstall.success", () => {
|
||||
reslove();
|
||||
})
|
||||
});
|
||||
|
||||
window.electron.ipcRenderer.sendMessage("bs.uninstall", version);
|
||||
|
||||
return promise;
|
||||
}
|
||||
public async uninstall(version: BSVersion): Promise<boolean>{
|
||||
return (await this.ipcService.send("bs.uninstall", {args: version})).success;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user