diff --git a/src/renderer/components/modal/modal-types/edit-version-modal.component.tsx b/src/renderer/components/modal/modal-types/edit-version-modal.component.tsx index 2e4de25e..4a44b617 100644 --- a/src/renderer/components/modal/modal-types/edit-version-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/edit-version-modal.component.tsx @@ -5,18 +5,17 @@ import { BsmIcon } from "renderer/components/svgs/bsm-icon.component"; import { DefaultConfigKey } from "renderer/config/default-configuration.config"; import { useTranslation } from "renderer/hooks/use-translation.hook"; import { ConfigurationService } from "renderer/services/configuration.service"; -import { ModalExitCode, ModalResponse, ModalService } from "renderer/services/modale.service"; +import { ModalComponent, ModalExitCode } from "renderer/services/modale.service"; import { BSVersion } from "shared/bs-version.interface"; -export function EditVersionModal({resolver, clone = false}: {resolver: (x: ModalResponse<{name: string, color: string}>) => void, clone?: boolean}) { +export const EditVersionModal: ModalComponent<{name: string, color: string}, {version: BSVersion, clone?: boolean}> = ({resolver, data}) => { + + const {version, clone} = data; const configService = ConfigurationService.getInstance(); - const modalService = ModalService.getInsance(); - const modalData: BSVersion = modalService.getModalData(); - - const [name, setName] = useState(modalData.name || modalData.BSVersion); - const [color, setColor] = useState(modalData.color ?? configService.get("second-color" as DefaultConfigKey)); + const [name, setName] = useState(version.name || version.BSVersion); + const [color, setColor] = useState(version.color ?? configService.get("second-color" as DefaultConfigKey)); const t = useTranslation(); const rename = () => { diff --git a/src/renderer/components/modal/modal-types/guard-modal.component.tsx b/src/renderer/components/modal/modal-types/guard-modal.component.tsx index fcd49bb9..80ace020 100644 --- a/src/renderer/components/modal/modal-types/guard-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/guard-modal.component.tsx @@ -1,11 +1,11 @@ -import { ModalExitCode, ModalResponse } from "../../../services/modale.service"; +import { ModalComponent, ModalExitCode } from "../../../services/modale.service"; import { useState } from "react"; import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png" import { BsmImage } from "renderer/components/shared/bsm-image.component"; import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { useTranslation } from "renderer/hooks/use-translation.hook"; -export function GuardModal({resolver}: {resolver: (x: ModalResponse) => void}) { +export const GuardModal: ModalComponent = ({resolver}) => { const [guardCode, setGuardCode] = useState(''); const t = useTranslation(); diff --git a/src/renderer/components/modal/modal-types/installation-folder-modal.component.tsx b/src/renderer/components/modal/modal-types/installation-folder-modal.component.tsx index d84f3beb..1fd173c6 100644 --- a/src/renderer/components/modal/modal-types/installation-folder-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/installation-folder-modal.component.tsx @@ -1,16 +1,15 @@ import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { BsmImage } from "renderer/components/shared/bsm-image.component"; import { useTranslation } from "renderer/hooks/use-translation.hook"; -import { ModalExitCode, ModalResponse } from "renderer/services/modale.service"; +import { ModalComponent, ModalExitCode } from "renderer/services/modale.service"; import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png" -export function InstallationFolderModal({resolver}: {resolver: (x: ModalResponse) => void}) { +export const InstallationFolderModal: ModalComponent = ({resolver}) => { const t = useTranslation(); return ( - <> - +

{t("modals.install-folder.title")}

{t("modals.install-folder.description")}

@@ -18,6 +17,6 @@ export function InstallationFolderModal({resolver}: {resolver: (x: ModalResponse resolver({exitCode: ModalExitCode.CANCELED})} withBar={false} text="misc.cancel"/> resolver({exitCode: ModalExitCode.COMPLETED})} withBar={false} text="modals.install-folder.buttons.submit"/> - + ) } diff --git a/src/renderer/components/modal/modal-types/login-modal.component.tsx b/src/renderer/components/modal/modal-types/login-modal.component.tsx index 81b58349..87e01e1d 100644 --- a/src/renderer/components/modal/modal-types/login-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/login-modal.component.tsx @@ -2,10 +2,10 @@ import { useState } from "react"; import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { BsmImage } from "renderer/components/shared/bsm-image.component"; import { useTranslation } from "renderer/hooks/use-translation.hook"; -import { ModalExitCode, ModalResponse } from "renderer/services/modale.service"; +import { ModalComponent, ModalExitCode } from "renderer/services/modale.service"; import BeatImpatient from '../../../../../assets/images/apngs/beat-impatient.png' -export function LoginModal({resolver}: {resolver: (x: ModalResponse) => void}) { +export const LoginModal: ModalComponent<{username: string, password: string, stay: boolean}> = ({resolver}) => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); @@ -35,7 +35,7 @@ export function LoginModal({resolver}: {resolver: (x: ModalResponse) => voi
{resolver({exitCode: ModalExitCode.CANCELED})}} withBar={false} text="misc.cancel"/> - +
) diff --git a/src/renderer/components/modal/modal-types/uninstall-all-mods-modal.component.tsx b/src/renderer/components/modal/modal-types/uninstall-all-mods-modal.component.tsx index cede04ca..d95b6978 100644 --- a/src/renderer/components/modal/modal-types/uninstall-all-mods-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/uninstall-all-mods-modal.component.tsx @@ -1,4 +1,4 @@ -import { ModalExitCode, ModalResponse, ModalService } from "../../../services/modale.service"; +import { ModalComponent, ModalExitCode } from "../../../services/modale.service"; import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png" import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { BsmImage } from "renderer/components/shared/bsm-image.component"; @@ -6,9 +6,9 @@ import { useTranslation } from "renderer/hooks/use-translation.hook"; import { BSVersion } from "shared/bs-version.interface"; -export function UninstallAllModsModal({resolver}: {resolver: (x: ModalResponse) => void}) { +export const UninstallAllModsModal: ModalComponent = ({resolver, data}) => { - const version = ModalService.getInsance().getModalData(); + const version = data; const t = useTranslation(); const desc = "modals.uninstall-all-mods.description"; diff --git a/src/renderer/components/modal/modal-types/uninstall-mod-modal.component.tsx b/src/renderer/components/modal/modal-types/uninstall-mod-modal.component.tsx index 4e913e24..7e10e036 100644 --- a/src/renderer/components/modal/modal-types/uninstall-mod-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/uninstall-mod-modal.component.tsx @@ -1,4 +1,4 @@ -import { ModalExitCode, ModalResponse, ModalService } from "../../../services/modale.service"; +import { ModalComponent, ModalExitCode } from "../../../services/modale.service"; import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png" import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { BsmImage } from "renderer/components/shared/bsm-image.component"; @@ -6,9 +6,9 @@ import { useTranslation } from "renderer/hooks/use-translation.hook"; import { Mod } from "shared/models/mods/mod.interface"; -export function UninstallModModal({resolver}: {resolver: (x: ModalResponse) => void}) { +export const UninstallModModal: ModalComponent = ({resolver, data}) => { - const mod = ModalService.getInsance().getModalData(); + const mod = data; const t = useTranslation(); const desc = mod.name.toLowerCase() === "bsipa" ? "modals.uninstall-mod.description-bsipa" : "modals.uninstall-mod.description"; diff --git a/src/renderer/components/modal/modal-types/uninstall-modal.component.tsx b/src/renderer/components/modal/modal-types/uninstall-modal.component.tsx index 812db48c..0f4aa913 100644 --- a/src/renderer/components/modal/modal-types/uninstall-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/uninstall-modal.component.tsx @@ -1,13 +1,13 @@ -import { ModalExitCode, ModalResponse, ModalService } from "../../../services/modale.service"; +import { ModalComponent, ModalExitCode } from "../../../services/modale.service"; import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png" import { BSVersion } from 'shared/bs-version.interface'; import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { BsmImage } from "renderer/components/shared/bsm-image.component"; import { useTranslation } from "renderer/hooks/use-translation.hook"; -export function UninstallModal({resolver}: {resolver: (x: ModalResponse) => void}) { +export const UninstallModal: ModalComponent = ({resolver, data}) => { - const version = ModalService.getInsance().getModalData(); + const version = data; const t = useTranslation(); return ( diff --git a/src/renderer/components/modal/modal.component.tsx b/src/renderer/components/modal/modal.component.tsx index 5a2c402a..1b610182 100644 --- a/src/renderer/components/modal/modal.component.tsx +++ b/src/renderer/components/modal/modal.component.tsx @@ -1,44 +1,28 @@ -import { ModalExitCode, ModalService, ModalType } from "renderer/services/modale.service"; +import { ModalExitCode, ModalService } from "renderer/services/modale.service"; import { AnimatePresence, motion } from "framer-motion"; -import { LoginModal } from "./modal-types/login-modal.component"; -import { GuardModal } from "./modal-types/guard-modal.component"; -import { UninstallModal } from "./modal-types/uninstall-modal.component"; -import { InstallationFolderModal } from "./modal-types/installation-folder-modal.component"; -import { EditVersionModal } from "./modal-types/edit-version-modal.component"; import { useObservable } from "renderer/hooks/use-observable.hook"; import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; -import { UninstallModModal } from "./modal-types/uninstall-mod-modal.component"; -import { UninstallAllModsModal } from "./modal-types/uninstall-all-mods-modal.component"; export function Modal() { const modalSevice = ModalService.getInsance(); - const modalType = useObservable(modalSevice.modalType$); - const {firstColor, secondColor} = useThemeColor(); + const ModalComponent = useObservable(modalSevice.getModalToShow()); - const renderModal = () => { - const resolver = modalSevice.getResolver(); - if(modalType === ModalType.STEAM_LOGIN){ return } - if(modalType === ModalType.GUARD_CODE){ return } - if(modalType === ModalType.UNINSTALL){ return } - if(modalType === ModalType.INSTALLATION_FOLDER){ return } - if(modalType === ModalType.EDIT_VERSION){ return } - if(modalType === ModalType.CLONE_VERSION){ return } - if(modalType === ModalType.UNINSTALL_MOD){ return } - if(modalType === ModalType.UNINSTALL_ALL_MODS){ return } - return null; - } + const modalData = modalSevice.getModalData(); + const resolver = modalSevice.getResolver(); + + const {firstColor, secondColor} = useThemeColor(); return ( - {modalType && ( + {ModalComponent && (
- modalSevice.resolve({exitCode: ModalExitCode.NO_CHOICE})} className="absolute top-0 bottom-0 right-0 left-0 bg-black" initial={{opacity: 0}} animate={{opacity: modalType && .60}} exit={{opacity: 0}} transition={{duration: .2}}/> + modalSevice.resolve({exitCode: ModalExitCode.NO_CHOICE})} className="absolute top-0 bottom-0 right-0 left-0 bg-black" initial={{opacity: 0}} animate={{opacity: ModalComponent && .60}} exit={{opacity: 0}} transition={{duration: .2}}/>
- {renderModal()} +
diff --git a/src/renderer/hooks/use-observable.hook.ts b/src/renderer/hooks/use-observable.hook.ts index 37b5419f..35412fc8 100644 --- a/src/renderer/hooks/use-observable.hook.ts +++ b/src/renderer/hooks/use-observable.hook.ts @@ -2,10 +2,10 @@ import { Observable } from "rxjs"; import { useState, useEffect } from "react"; export function useObservable(observable: Observable): T{ - const [obsValue, setObsValue] = useState(null); + const [obsValue, setObsValue] = useState(null as T); useEffect(() => { - const sub = observable.subscribe(val => setObsValue(val)); + const sub = observable.subscribe(val => setObsValue(() => val)); return () => sub.unsubscribe(); }, []) diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index d7d22494..aaed2f45 100644 --- a/src/renderer/pages/settings-page.component.tsx +++ b/src/renderer/pages/settings-page.component.tsx @@ -12,13 +12,14 @@ import { BsDownloaderService } from "renderer/services/bs-downloader.service"; import { ConfigurationService } from "renderer/services/configuration.service" import { I18nService } from "renderer/services/i18n.service"; import { IpcService } from "renderer/services/ipc.service"; -import { ModalExitCode, ModalService, ModalType } from "renderer/services/modale.service"; +import { ModalExitCode, ModalService } from "renderer/services/modale.service"; import { NotificationService } from "renderer/services/notification.service"; import { ProgressBarService } from "renderer/services/progress-bar.service"; import { ThemeService } from "renderer/services/theme.service"; import { SupportersView } from "renderer/components/settings/supporters-view/supporters-view.component"; import { LinkOpenerService } from "renderer/services/link-opener.service"; import { useNavigate } from "react-router-dom"; +import { InstallationFolderModal } from "renderer/components/modal/modal-types/installation-folder-modal.component"; export function SettingsPage() { @@ -84,7 +85,7 @@ export function SettingsPage() { const setDefaultInstallationFolder = () => { if(!progressBarService.require()){ return; } - modalService.openModal(ModalType.INSTALLATION_FOLDER).then(async res => { + modalService.openModal(InstallationFolderModal).then(async res => { if(res.exitCode !== ModalExitCode.COMPLETED){ return; } const fileChooserRes = await ipcService.send<{canceled: boolean, filePaths: string[]}>("choose-folder"); diff --git a/src/renderer/pages/version-viewer.component.tsx b/src/renderer/pages/version-viewer.component.tsx index 41bba599..619ee9ba 100644 --- a/src/renderer/pages/version-viewer.component.tsx +++ b/src/renderer/pages/version-viewer.component.tsx @@ -8,13 +8,14 @@ import { BsmDropdownButton } from 'renderer/components/shared/bsm-dropdown-butto import { BsmImage } from 'renderer/components/shared/bsm-image.component'; import { BSUninstallerService } from '../services/bs-uninstaller.service'; import { BSVersionManagerService } from '../services/bs-version-manager.service'; -import { ModalExitCode, ModalService, ModalType } from '../services/modale.service'; +import { ModalExitCode, ModalService } from '../services/modale.service'; import DefautVersionImage from "../../../assets/images/default-version-img.jpg"; import { BsDownloaderService } from 'renderer/services/bs-downloader.service'; import { IpcService } from 'renderer/services/ipc.service'; import { MapService } from 'renderer/services/maps.service'; import { LaunchSlide } from 'renderer/components/version-viewer/slides/launch/launch-slide.component'; import { ModsSlide } from 'renderer/components/version-viewer/slides/mods/mods-slide.component'; +import { UninstallModal } from 'renderer/components/modal/modal-types/uninstall-modal.component'; export function VersionViewer() { @@ -35,7 +36,7 @@ export function VersionViewer() { const verifyFiles = () => bsDownloaderService.download(state, true); const uninstall = async () => { - const modalCompleted = await modalService.openModal(ModalType.UNINSTALL, state) + const modalCompleted = await modalService.openModal(UninstallModal, state); if(modalCompleted.exitCode === ModalExitCode.COMPLETED){ bsUninstallerService.uninstall(state).then(() => { bsVersionManagerService.askInstalledVersions(); diff --git a/src/renderer/services/bs-downloader.service.ts b/src/renderer/services/bs-downloader.service.ts index ee21f72f..5cf32032 100644 --- a/src/renderer/services/bs-downloader.service.ts +++ b/src/renderer/services/bs-downloader.service.ts @@ -6,9 +6,11 @@ import { BSVersion } from 'shared/bs-version.interface'; 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 { ModalExitCode, ModalService } from './modale.service'; import { NotificationService } from './notification.service'; import { ProgressBarService } from './progress-bar.service'; +import { LoginModal } from 'renderer/components/modal/modal-types/login-modal.component'; +import { GuardModal } from 'renderer/components/modal/modal-types/guard-modal.component'; export class BsDownloaderService{ @@ -57,7 +59,7 @@ export class BsDownloaderService{ this.ipcService.watch("bs-download.[2FA]").subscribe(async response => { if(!response.success){ this.ipcService.sendLazy("bs-download.kill"); return; } - const res = await this.modalService.openModal(ModalType.GUARD_CODE); + const res = await this.modalService.openModal(GuardModal); if(res.exitCode !== ModalExitCode.COMPLETED){ this.progressBarService.hide(true); this.ipcService.sendLazy("bs-download.kill"); @@ -90,7 +92,7 @@ export class BsDownloaderService{ let promise; if(!this.authService.sessionExist()){ - const res = await this.modalService.openModal<{username: string, stay: boolean, password: string}>(ModalType.STEAM_LOGIN); + const res = await this.modalService.openModal(LoginModal); if(res.exitCode !== ModalExitCode.COMPLETED){ this.progressBarService.hide(true); return {success: false}; diff --git a/src/renderer/services/bs-mods-manager.service.ts b/src/renderer/services/bs-mods-manager.service.ts index e65a330c..0559e5fe 100644 --- a/src/renderer/services/bs-mods-manager.service.ts +++ b/src/renderer/services/bs-mods-manager.service.ts @@ -1,3 +1,5 @@ +import { UninstallAllModsModal } from "renderer/components/modal/modal-types/uninstall-all-mods-modal.component"; +import { UninstallModModal } from "renderer/components/modal/modal-types/uninstall-mod-modal.component"; import { Observable } from "rxjs"; import { BehaviorSubject } from "rxjs"; import { map } from "rxjs/operators"; @@ -6,7 +8,7 @@ import { InstallModsResult, UninstallModsResult } from "shared/models/mods"; import { Mod, ModInstallProgression } from "shared/models/mods"; import { ProgressionInterface } from "shared/models/progress-bar"; import { IpcService } from "./ipc.service"; -import { ModalExitCode, ModalService, ModalType } from "./modale.service"; +import { ModalExitCode, ModalService } from "./modale.service"; import { NotificationService, NotificationType } from "./notification.service"; import { ProgressBarService } from "./progress-bar.service"; @@ -74,7 +76,7 @@ export class BsModsManagerService { if(!this.progressBar.require()){ return; } - const modalRes = await this.modals.openModal(ModalType.UNINSTALL_MOD, mod); + const modalRes = await this.modals.openModal(UninstallModModal, mod); if(modalRes.exitCode !== ModalExitCode.COMPLETED){ return; } @@ -100,7 +102,7 @@ export class BsModsManagerService { if(!this.progressBar.require()){ return; } - const modalRes = await this.modals.openModal(ModalType.UNINSTALL_ALL_MODS, version); + const modalRes = await this.modals.openModal(UninstallAllModsModal, version); if(modalRes.exitCode !== ModalExitCode.COMPLETED){ return; } diff --git a/src/renderer/services/bs-version-manager.service.ts b/src/renderer/services/bs-version-manager.service.ts index f1ee55c5..c5f2249e 100644 --- a/src/renderer/services/bs-version-manager.service.ts +++ b/src/renderer/services/bs-version-manager.service.ts @@ -1,9 +1,10 @@ import { BSVersion } from 'shared/bs-version.interface'; import { BehaviorSubject } from "rxjs"; import { IpcService } from "./ipc.service"; -import { ModalExitCode, ModalService, ModalType } from './modale.service'; +import { ModalExitCode, ModalService } from './modale.service'; import { NotificationService } from './notification.service'; import { ProgressBarService } from './progress-bar.service'; +import { EditVersionModal } from 'renderer/components/modal/modal-types/edit-version-modal.component'; export class BSVersionManagerService { @@ -75,7 +76,7 @@ export class BSVersionManagerService { } public async editVersion(version: BSVersion): Promise{ - const modalRes = await this.modalService.openModal<{name: string, color: string}>(ModalType.EDIT_VERSION, version); + const modalRes = await this.modalService.openModal(EditVersionModal, {version, clone: false}); if(modalRes.exitCode !== ModalExitCode.COMPLETED){ return null; } if(modalRes.data.name?.length < 2){ return null; } return this.ipcService.send("bs-version.edit", {args: {version, name: modalRes.data.name, color: modalRes.data.color}}).then(res => { @@ -93,7 +94,7 @@ export class BSVersionManagerService { public async cloneVersion(version: BSVersion): Promise{ if(!this.progressBarService.require()){ return null; } - const modalRes = await this.modalService.openModal<{name: string, color: string}>(ModalType.CLONE_VERSION, version); + const modalRes = await this.modalService.openModal(EditVersionModal, {version, clone: true}); if(modalRes.exitCode !== ModalExitCode.COMPLETED){ return null; } if(modalRes.data.name?.length < 2){ return null; } this.progressBarService.showFake(0.01); diff --git a/src/renderer/services/modale.service.ts b/src/renderer/services/modale.service.ts index 8e5a3674..82a4ba95 100644 --- a/src/renderer/services/modale.service.ts +++ b/src/renderer/services/modale.service.ts @@ -1,3 +1,4 @@ +import { Observable } from "rxjs"; import { BehaviorSubject } from "rxjs"; import { timeout } from "rxjs/operators"; @@ -5,7 +6,7 @@ export class ModalService{ private static instance: ModalService; - private _modalType$: BehaviorSubject = new BehaviorSubject(null); + private _modalToShow$: BehaviorSubject = new BehaviorSubject(null); private modalData: any = null; private resolver: any; @@ -18,11 +19,7 @@ export class ModalService{ private close(){ if(this.resolver){ this.resolve({exitCode: ModalExitCode.NO_CHOICE}); } - this.modalType$.next(null); - } - - public get modalType$(): BehaviorSubject{ - return this._modalType$; + this._modalToShow$.next(null); } public getModalData(): Type{ @@ -37,29 +34,24 @@ export class ModalService{ this.resolver(data); } - public async openModal(modalType: ModalType, data?: any): Promise>{ + public async openModal(modal: ModalComponent, data?: K): Promise>{ this.close(); await timeout(100); //Must wait resolve const promise = new Promise>((resolve) => { this.resolver = resolve; }); + this._modalToShow$.next(modal); promise.then(() => this.close()); - this.modalType$.next(modalType); if(data){ this.modalData = data; } else{ this.modalData = null; } return promise; } + public getModalToShow(): Observable{ + return this._modalToShow$.asObservable(); + } + } -export const enum ModalType { - STEAM_LOGIN = "STEAM_LOGIN", - GUARD_CODE = "GUARD_CODE", - UNINSTALL = "UNINSTALL", - INSTALLATION_FOLDER = "INSTALLATION_FOLDER", - EDIT_VERSION = "EDIT_VERSION", - CLONE_VERSION = "CLONE_VERSION", - UNINSTALL_MOD = "UNINSTALL_MOD", - UNINSTALL_ALL_MODS = "UNINSTALL_ALL_MODS", -} +export type ModalComponent = ({resolver, data}: {resolver : (x: ModalResponse) => void, data?: K}) => JSX.Element; export const enum ModalExitCode { NO_CHOICE = -1,