add double click to quick launch

This commit is contained in:
MathieuG-P
2022-07-15 20:25:06 +02:00
parent ddc67212d8
commit afdb45a1d2
5 changed files with 125 additions and 112 deletions
@@ -5,6 +5,8 @@ import { SteamIcon } from "../svgs/steam-icon.component";
import { BsDownloaderService } from "renderer/services/bs-downloader.service";
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";
export default function BsVersionItem(props: {version: BSVersion}) {
@@ -14,11 +16,23 @@ export default function BsVersionItem(props: {version: BSVersion}) {
const [downloadPercent, setDownloadPercent] = useState(0);
const downloaderService = BsDownloaderService.getInstance();
const launcherService = BSLauncherService.getInstance();
const configService = ConfigurationService.getInstance();
const isActive = (): boolean => {
return props.version?.BSVersion === state?.BSVersion && props?.version.steam === state?.steam;
}
const handleDoubleClick = () => {
if(state.steam){ return; }
launcherService.launch(
state,
!!configService.get<boolean>(LaunchMods.OCULUS_MOD),
!!configService.get<boolean>(LaunchMods.DESKTOP_MOD),
!!configService.get<boolean>(LaunchMods.DEBUG_MOD)
)
}
useEffect(() => {
combineLatest([downloaderService.currentBsVersionDownload$, downloaderService.downloadProgress$]).subscribe(vals => {
if(vals[0]?.BSVersion === props.version.BSVersion && vals[0]?.steam === props.version.steam){
@@ -36,7 +50,7 @@ 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 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 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"}`}>
<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>
@@ -3,10 +3,8 @@ import { BsDownloaderService } from "../services/bs-downloader.service";
import { Slideshow } from "renderer/components/slideshow/slideshow.component";
import { useEffect, useState } from "react";
import { BSVersion } from "main/services/bs-version-manager.service";
import { ProgressBarService } from "renderer/services/progress-bar.service";
import { BsmButton } from "renderer/components/shared/bsm-button.component";
import { AnimatePresence, motion } from "framer-motion";
import { NotificationService } from "renderer/services/notification.service";
import { useTranslation } from "renderer/hooks/use-translation.hook";
import { BSVersionManagerService } from "renderer/services/bs-version-manager.service";
import { useObservable } from "renderer/hooks/use-observable.hook";
@@ -23,25 +21,15 @@ export function AvailableVersionsList() {
require('../../../assets/images/slideshow-images/image-7-blur.png'),
];
const bsDownloaderService: BsDownloaderService = BsDownloaderService.getInstance();
const progressBarService: ProgressBarService = ProgressBarService.getInstance();
const notificationService: NotificationService = NotificationService.getInstance();
const versionManagerService: BSVersionManagerService = BSVersionManagerService.getInstance();
const [versionSelected, setVersionSelected] = useState(null as BSVersion);
const progressBarVisible = useObservable(progressBarService.visible$);
const currentVersionDownloading = useObservable(bsDownloaderService.currentBsVersionDownload$);
const t = useTranslation();
const startDownload = () => {
if(progressBarService.visible$.value){ return; }
progressBarService.show(bsDownloaderService.downloadProgress$);
bsDownloaderService.download(versionSelected).then(res => {
progressBarService.hide(true);
if(res.success){
notificationService.notifySuccess({title: "notifications.bs-download.success.titles.download-success", duration: 3000});
}
});
}
const startDownload = () => {
bsDownloaderService.download(versionSelected, versionManagerService.isVersionInstalled(versionSelected));
}
useEffect(() => {
const versionSelectedSub = bsDownloaderService.selectedBsVersion$.subscribe(version => {
@@ -61,7 +49,7 @@ export function AvailableVersionsList() {
<AvailableVersionsSlider/>
<AnimatePresence>
{ versionSelected && !progressBarVisible && (
{ versionSelected && !currentVersionDownloading && (
<motion.div initial={{y:"150%"}} animate={{y:"0%"}} exit={{y:"150%"}} className="absolute bottom-5" onClick={startDownload}>
<BsmButton text={versionManagerService.isVersionInstalled(versionSelected) ? "misc.verify" : "misc.download"} className="relative bg-light-main-color-2 text-gray-800 dark:text-gray-100 dark:bg-main-color-2 rounded-md text-3xl font-bold italic tracking-wide px-3 pb-2 pt-1 shadow-md shadow-black"/>
</motion.div>
@@ -14,9 +14,7 @@ import { BSUninstallerService } from '../services/bs-uninstaller.service';
import { BSVersionManagerService } from '../services/bs-version-manager.service';
import { ModalExitCode, ModalService, ModalType } from '../services/modale.service';
import DefautVersionImage from "../../../assets/images/default-version-img.jpg";
import { NotificationService } from 'renderer/services/notification.service';
import { BsDownloaderService } from 'renderer/services/bs-downloader.service';
import { ProgressBarService } from 'renderer/services/progress-bar.service';
import { useTranslation } from 'renderer/hooks/use-translation.hook';
export function VersionViewer() {
@@ -34,9 +32,7 @@ export function VersionViewer() {
const bsUninstallerService = BSUninstallerService.getInstance();
const bsVersionManagerService = BSVersionManagerService.getInstance();
const modalService = ModalService.getInsance();
const notificationService = NotificationService.getInstance();
const bsDownloaderService = BsDownloaderService.getInstance();
const progressService = ProgressBarService.getInstance();
useEffect(() => {
setOculusMode(!!configService.get<boolean>(LaunchMods.OCULUS_MOD));
@@ -81,30 +77,13 @@ export function VersionViewer() {
}
}
const verifyFiles = () => {
progressService.show(bsDownloaderService.downloadProgress$);
bsDownloaderService.download(state).then(res => {
progressService.hide(true);
if(!res.success){ notificationService.notifyError({title: "notifications.bs-download.errors.titles.verification-failed", desc: "notifications.bs-download.errors.msg.verification-failed"}); }
else(notificationService.notifySuccess({title: "notifications.bs-download.success.titles.verification-finished"}));
})
}
const verifyFiles = () => {
bsDownloaderService.download(state, true);
}
const launchBs = () => {
bsLauncherService.launch(state, oculusMode, desktopMode, debugMode).then(res => {
if(!res.success){ notificationService.notifyError({title: "notifications.bs-launch.errors.titles.UNABLE_TO_LAUNCH", desc: res.error.title}); }
else if(res.data === "STEAM_NOT_RUNNING"){ notificationService.notifyError({title: "notifications.bs-launch.errors.titles.STEAM_NOT_RUNNING", desc: "notifications.bs-launch.errors.msg.STEAM_NOT_RUNNING"}); }
else if(res.data === "BS_ALREADY_RUNNING"){ notificationService.notifyError({title: "notifications.bs-launch.errors.titles.UNABLE_TO_LAUNCH", desc: "notifications.bs-launch.errors.msg.UNABLE_TO_LAUNCH"}); }
else if(res.data === "EXE_NOT_FINDED"){
notificationService.notifyError({title: "notifications.bs-launch.errors.titles.EXE_NOT_FINDED", desc: "notifications.bs-launch.errors.msg.EXE_NOT_FINDED", actions: [{id: "0", title:"misc.verify"}]}).then(res => {
if(res !== "0"){ return; }
verifyFiles();
});
}
else if(res.data === "LAUNCHED"){ notificationService.notifySuccess({title: "notifications.bs-launch.success.titles.launching"}) }
else(notificationService.notifyError({title: res.data || res.error.title}));
});
}
const launchBs = () => {
bsLauncherService.launch(state, oculusMode, desktopMode, debugMode);
}
return (
<>
+65 -49
View File
@@ -1,11 +1,13 @@
import { DownloadEvent } from 'main/services/bs-installer.service';
import { BehaviorSubject, distinctUntilChanged } from 'rxjs';
import { BehaviorSubject, distinctUntilChanged, filter, debounceTime } from 'rxjs';
import { IpcResponse } from 'shared/models/ipc-models.model';
import { BSVersion } from '../../main/services/bs-version-manager.service'
import { AuthUserService } from './auth-user.service';
import { BSVersionManagerService } from './bs-version-manager.service';
import { IpcService } from './ipc.service';
import { ModalExitCode, ModalService, ModalType } from './modale.service';
import { NotificationService } from './notification.service';
import { ProgressBarService } from './progress-bar.service';
export class BsDownloaderService{
@@ -15,6 +17,8 @@ export class BsDownloaderService{
private readonly ipcService: IpcService;
private readonly bsVersionManager: BSVersionManagerService;
private readonly authService: AuthUserService;
private readonly progressBarService: ProgressBarService;
private readonly notificationService: NotificationService;
public readonly currentBsVersionDownload$: BehaviorSubject<BSVersion> = new BehaviorSubject(null);
@@ -34,30 +38,35 @@ export class BsDownloaderService{
this.modalService = ModalService.getInsance();
this.bsVersionManager = BSVersionManagerService.getInstance();
this.authService = AuthUserService.getInstance();
this.progressBarService = ProgressBarService.getInstance();
this.notificationService = NotificationService.getInstance();
this.asignListerners();
}
private asignListerners(): void{
this.ipcService.watch<number>("bs-download.[Progress]").pipe(distinctUntilChanged()).subscribe(response => this.downloadProgress$.next(response.data));
private asignListerners(): void{
this.ipcService.watch<number>("bs-download.[Progress]").pipe(distinctUntilChanged()).subscribe(response => this.downloadProgress$.next(response.data));
this.ipcService.watch<string>("bs-download.[SteamID]").subscribe(response => response.success && this.authService.setSteamID(response.data));
this.ipcService.watch<string>("bs-download.[SteamID]").pipe(filter(r => r.success && !!r.data)).subscribe(response => this.authService.setSteamID(response.data));
this.ipcService.watch<string>("bs-download.[Warning]").subscribe(response => this.downloadWarning$.next(response.data));
this.ipcService.watch<string>("bs-download.[Warning]").pipe(filter(v => !!v && !!v.data), distinctUntilChanged(), debounceTime(1000)).subscribe(warning => {
this.notificationService.notifyWarning({title: "notifications.types.warning", desc: `notifications.bs-download.warnings.msg.${warning.data}`});
});
this.ipcService.watch<string>("bs-download.[Error]").subscribe(response => this.downloadError$.next(response.data));
this.ipcService.watch<string>("bs-download.[Error]").pipe(filter(v => !!v && !!v.data), distinctUntilChanged(), debounceTime(1000)).subscribe(err => {
this.notificationService.notifyError({title: "notifications.types.error", desc: `notifications.bs-download.errors.msg.${err.data}`});
});
this.ipcService.watch<void>("bs-download.[2FA]").subscribe(async response => {
if(!response.success){ return; }
const res = await this.modalService.openModal(ModalType.GUARD_CODE);
if(res.exitCode !== ModalExitCode.COMPLETED){ return; }
this.ipcService.sendLazy('bs-download.[2FA]', {args: res.data});
});
this.ipcService.watch<void>("bs-download.[2FA]").subscribe(async response => {
if(!response.success){ return; }
const res = await this.modalService.openModal(ModalType.GUARD_CODE);
if(res.exitCode !== ModalExitCode.COMPLETED){ return; }
this.ipcService.sendLazy('bs-download.[2FA]', {args: res.data});
});
this.currentBsVersionDownload$.subscribe(version => {
if(version){ this.bsVersionManager.setInstalledVersions([...this.bsVersionManager.installedVersions$.value, version]); }
else{ this.bsVersionManager.askInstalledVersions(); }
});
this.currentBsVersionDownload$.subscribe(version => {
if(version){ this.bsVersionManager.setInstalledVersions([...this.bsVersionManager.installedVersions$.value, version]); }
else{ this.bsVersionManager.askInstalledVersions(); }
});
}
private resetDownload(): void{
@@ -66,44 +75,51 @@ export class BsDownloaderService{
this.selectedBsVersion$.next(null);
}
public async download(bsVersion: BSVersion): Promise<IpcResponse<DownloadEvent>>{
let promise;
if(!this.authService.sessionExist()){
const res = await this.modalService.openModal(ModalType.STEAM_LOGIN);
if(res.exitCode !== ModalExitCode.COMPLETED){ return {success: false}; }
this.authService.setSteamSession(res.data.username, res.data.stay);
promise = this.ipcService.send<DownloadEvent>('bs-download.start', {args: {bsVersion: bsVersion, username: res.data.username, password: res.data.password, stay: res.data.stay}});
}
else{
promise = this.ipcService.send<DownloadEvent>('bs-download.start', {args: {bsVersion: bsVersion, username: this.authService.getSteamUsername()}});
}
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};
}
this.currentBsVersionDownload$.next(bsVersion);
this.progressBarService.show(this.downloadProgress$);
let res = await promise;
let promise;
if(!this.authService.sessionExist()){
const res = await this.modalService.openModal(ModalType.STEAM_LOGIN);
if(res.exitCode !== ModalExitCode.COMPLETED){ return {success: false}; }
this.authService.setSteamSession(res.data.username, res.data.stay);
promise = this.ipcService.send<DownloadEvent>('bs-download.start', {args: {bsVersion: bsVersion, username: res.data.username, password: res.data.password, stay: res.data.stay}});
}
else{
promise = this.ipcService.send<DownloadEvent>('bs-download.start', {args: {bsVersion: bsVersion, username: this.authService.getSteamUsername()}});
}
if(!res.success){ return res; }
this.currentBsVersionDownload$.next(bsVersion);
let res = await promise;
if(res.data.type === "[Password]"){
this.authService.deleteSteamSession();
res = await this.download(bsVersion);
}
this.resetDownload();
return res;
}
if(res.data.type === "[Password]"){
this.authService.deleteSteamSession();
res = await this.download(bsVersion);
}
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 async getInstallationFolder(): Promise<string>{
const res = await this.ipcService.send<string>("bs-download.installation-folder");
return res.success ? res.data : "";
}
public async getInstallationFolder(): Promise<string>{
const res = await this.ipcService.send<string>("bs-download.installation-folder");
return res.success ? res.data : "";
}
public setInstallationFolder(path: string): Promise<IpcResponse<string>>{
return this.ipcService.send<string>("bs-download.set-installation-folder", {args: path});
}
public setInstallationFolder(path: string): Promise<IpcResponse<string>>{
return this.ipcService.send<string>("bs-download.set-installation-folder", {args: path});
}
}
+34 -18
View File
@@ -2,32 +2,48 @@ import { LauchOption } from "../../shared/models/launch-models.model";
import { BSVersion } from "../../main/services/bs-version-manager.service";
import { IpcService } from "./ipc.service";
import { BsLaunchResult } from "../../shared/models/launch-models.model";
import { IpcResponse } from "shared/models/ipc-models.model";
import { NotificationResult, NotificationService } from "./notification.service";
import { BsDownloaderService } from "./bs-downloader.service";
export class BSLauncherService{
private static instance: BSLauncherService;
private static instance: BSLauncherService;
private readonly ipcService: IpcService;
private readonly ipcService: IpcService;
private readonly notificationService: NotificationService;
private readonly bsDownloaderService: BsDownloaderService;
public static getInstance(){
if(!BSLauncherService.instance){ BSLauncherService.instance = new BSLauncherService(); }
return BSLauncherService.instance;
}
public static getInstance(){
if(!BSLauncherService.instance){ BSLauncherService.instance = new BSLauncherService(); }
return BSLauncherService.instance;
}
private constructor(){
this.ipcService = IpcService.getInstance();
this.notificationService = NotificationService.getInstance();
this.bsDownloaderService = BsDownloaderService.getInstance();
}
private constructor(){
this.ipcService = IpcService.getInstance();
}
public launch(version: BSVersion, oculus: boolean, desktop: boolean, debug: boolean): Promise<IpcResponse<BsLaunchResult>>{
const lauchOption: LauchOption = {debug, oculus, desktop, version};
return this.ipcService.send<BsLaunchResult>("bs-launch.launch", {args: lauchOption});
}
public launch(version: BSVersion, oculus: boolean, desktop: boolean, debug: boolean): Promise<NotificationResult|string>{
const lauchOption: LauchOption = {debug, oculus, desktop, version};
return this.ipcService.send<BsLaunchResult>("bs-launch.launch", {args: lauchOption}).then(res => {
if(!res.success){ return this.notificationService.notifyError({title: "notifications.bs-launch.errors.titles.UNABLE_TO_LAUNCH", desc: res.error.title}); }
if(res.data === "EXE_NOT_FINDED"){
this.notificationService.notifyError({title: "notifications.bs-launch.errors.titles.EXE_NOT_FINDED", desc: "notifications.bs-launch.errors.msg.EXE_NOT_FINDED", actions: [{id: "0", title:"misc.verify"}]}).then(res => {
if(res === "0"){ this.bsDownloaderService.download(version, true); }
return res;
});
}
if(res.data === "LAUNCHED"){ return this.notificationService.notifySuccess({title: "notifications.bs-launch.success.titles.launching"}); }
if(res.data){ return this.notificationService.notifyError({title: `notifications.bs-launch.errors.titles.${res.data}`}); }
return this.notificationService.notifyError({title: res.data || res.error.title});
});
}
}
export enum LaunchMods{
OCULUS_MOD = "LAUNCH_OCULUS_MOD",
DESKTOP_MOD = "LAUNCH_DESKTOP_MOD",
DEBUG_MOD ="LAUNCH_DEBUG_MOD"
OCULUS_MOD = "LAUNCH_OCULUS_MOD",
DESKTOP_MOD = "LAUNCH_DESKTOP_MOD",
DEBUG_MOD ="LAUNCH_DEBUG_MOD"
}