From 4373af877b6f7797b37190082e3ce175a159948e Mon Sep 17 00:00:00 2001 From: Ariel Juodziukynas Date: Sun, 12 Jan 2025 15:17:37 -0300 Subject: [PATCH] Make install modal global with state moved to zustand --- src/frontend/App.tsx | 2 + src/frontend/screens/Game/GamePage/index.tsx | 13 +----- .../screens/Game/GameSubMenu/index.tsx | 12 +----- .../Library/components/InstallModal/index.tsx | 40 +++++++++++++------ .../screens/Library/components/index.tsx | 1 - src/frontend/screens/Library/index.tsx | 33 +-------------- src/frontend/state/GlobalState.tsx | 14 ------- src/frontend/state/InstallGameModal.ts | 38 ++++++++++++++++++ 8 files changed, 74 insertions(+), 79 deletions(-) delete mode 100644 src/frontend/screens/Library/components/index.tsx create mode 100644 src/frontend/state/InstallGameModal.ts diff --git a/src/frontend/App.tsx b/src/frontend/App.tsx index aec937b571..733284ba02 100644 --- a/src/frontend/App.tsx +++ b/src/frontend/App.tsx @@ -18,6 +18,7 @@ import classNames from 'classnames' import { ThemeProvider, createTheme } from '@mui/material/styles' import LogFileUploadDialog from './components/UI/LogFileUploadDialog' import UploadedLogFilesList from './screens/Settings/sections/LogSettings/components/UploadedLogFilesList' +import { InstallGameWrapper } from './screens/Library/components/InstallModal' function Root() { const { @@ -59,6 +60,7 @@ function Root() { type={isSettingsModalOpen.type} /> )} + diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index 0e0e181491..0e7f4dbf3d 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -39,7 +39,6 @@ import { import GamePicture from '../GamePicture' import TimeContainer from '../TimeContainer' -import { InstallModal } from 'frontend/screens/Library/components' import { install } from 'frontend/helpers/library' import { hasProgress } from 'frontend/hooks/hasProgress' import ErrorComponent from 'frontend/components/UI/ErrorComponent' @@ -71,6 +70,7 @@ import { hasAnticheatInfo } from 'frontend/hooks/hasAnticheatInfo' import { hasHelp } from 'frontend/hooks/hasHelp' import Genres from './components/Genres' import ReleaseDate from './components/ReleaseDate' +import { openInstallGameModal } from 'frontend/state/InstallGameModal' export default React.memo(function GamePage(): JSX.Element | null { const { appName, runner } = useParams() as { appName: string; runner: Runner } @@ -82,7 +82,6 @@ export default React.memo(function GamePage(): JSX.Element | null { const { gameInfo: locationGameInfo } = location.state - const [showModal, setShowModal] = useState({ game: '', show: false }) const [showUninstallModal, setShowUninstallModal] = useState(false) const [wikiInfo, setWikiInfo] = useState(null) @@ -260,7 +259,7 @@ export default React.memo(function GamePage(): JSX.Element | null { } function handleModal() { - setShowModal({ game: appName, show: true }) + openInstallGameModal({ appName, runner, gameInfo }) } let hasUpdate = false @@ -356,14 +355,6 @@ export default React.memo(function GamePage(): JSX.Element | null { className="backgroundImage" /> )} - {gameInfo.runner !== 'sideload' && showModal.show && ( - setShowModal({ game: '', show: false })} - gameInfo={gameInfo} - /> - )} {showUninstallModal && ( (false) const [eosOverlayRefresh, setEosOverlayRefresh] = useState(false) - const [showModal, setShowModal] = useState(false) const eosOverlayAppName = '98bc04bc842e4906993fd6d6644ffb8d' const [showUninstallModal, setShowUninstallModal] = useState(false) const [protonDBurl, setProtonDBurl] = useState( @@ -147,7 +146,7 @@ export default function GamesSubmenu({ } function handleEdit() { - setShowModal(true) + openInstallGameModal({ appName, runner, gameInfo }) } async function handleEosOverlay() { @@ -379,13 +378,6 @@ export default function GamesSubmenu({ )} - {showModal && ( - setShowModal(false)} - /> - )} ) } diff --git a/src/frontend/screens/Library/components/InstallModal/index.tsx b/src/frontend/screens/Library/components/InstallModal/index.tsx index 62ccee3f9e..492d200a9b 100644 --- a/src/frontend/screens/Library/components/InstallModal/index.tsx +++ b/src/frontend/screens/Library/components/InstallModal/index.tsx @@ -20,10 +20,13 @@ import WineSelector from './WineSelector' import { SelectField } from 'frontend/components/UI' import { useTranslation } from 'react-i18next' import ThirdPartyDialog from './ThirdPartyDialog' +import { + closeInstallGameModal, + useInstallGameModal +} from 'frontend/state/InstallGameModal' type Props = { appName: string - backdropClick: () => void runner: Runner gameInfo?: GameInfo | null } @@ -35,12 +38,7 @@ export type AvailablePlatforms = { icon: IconDefinition }[] -export default React.memo(function InstallModal({ - appName, - backdropClick, - runner, - gameInfo = null -}: Props) { +function InstallModal({ appName, runner, gameInfo = null }: Props) { const { platform } = useContext(ContextProvider) const { t } = useTranslation('gamepage') @@ -155,10 +153,12 @@ export default React.memo(function InstallModal({ const showDownloadDialog = !isSideload && gameInfo const isThirdPartyManagedApp = gameInfo && !!gameInfo.thirdPartyManagedApp + const closeModal = () => closeInstallGameModal() + return (
@@ -169,7 +169,7 @@ export default React.memo(function InstallModal({ winePrefix={winePrefix} wineVersion={wineVersion} availablePlatforms={availablePlatforms} - backdropClick={backdropClick} + backdropClick={closeModal} platformToInstall={platformToInstall} gameInfo={gameInfo} crossoverBottle={crossoverBottle} @@ -197,7 +197,7 @@ export default React.memo(function InstallModal({ winePrefix={winePrefix} wineVersion={wineVersion} availablePlatforms={availablePlatforms} - backdropClick={backdropClick} + backdropClick={closeModal} platformToInstall={platformToInstall} gameInfo={gameInfo} crossoverBottle={crossoverBottle} @@ -223,7 +223,7 @@ export default React.memo(function InstallModal({ winePrefix={winePrefix} wineVersion={wineVersion} availablePlatforms={availablePlatforms} - backdropClick={backdropClick} + backdropClick={closeModal} platformToInstall={platformToInstall} appName={appName} crossoverBottle={crossoverBottle} @@ -246,4 +246,20 @@ export default React.memo(function InstallModal({
) -}) +} + +export function InstallGameWrapper() { + const installGameModalState = useInstallGameModal() + + if (!installGameModalState.isOpen) { + return <> + } + + return ( + + ) +} diff --git a/src/frontend/screens/Library/components/index.tsx b/src/frontend/screens/Library/components/index.tsx deleted file mode 100644 index 914f9d9bf4..0000000000 --- a/src/frontend/screens/Library/components/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default as InstallModal } from './InstallModal' diff --git a/src/frontend/screens/Library/index.tsx b/src/frontend/screens/Library/index.tsx index 218441412f..7bc02267b2 100644 --- a/src/frontend/screens/Library/index.tsx +++ b/src/frontend/screens/Library/index.tsx @@ -27,22 +27,15 @@ import { sideloadedCategories } from 'frontend/helpers/library' import RecentlyPlayed from './components/RecentlyPlayed' -import { InstallModal } from './components' import LibraryContext from './LibraryContext' import { Category, PlatformsFilters, StoresFilters } from 'frontend/types' import { hasHelp } from 'frontend/hooks/hasHelp' import EmptyLibraryMessage from './components/EmptyLibrary' import CategoriesManager from './components/CategoriesManager' +import { openInstallGameModal } from 'frontend/state/InstallGameModal' const storage = window.localStorage -type ModalState = { - game: string - show: boolean - runner: Runner - gameInfo: GameInfo | null -} - export default React.memo(function Library(): JSX.Element { const { t } = useTranslation() @@ -180,12 +173,6 @@ export default React.memo(function Library(): JSX.Element { const [showCategories, setShowCategories] = useState(false) - const [showModal, setShowModal] = useState({ - game: '', - show: false, - runner: 'legendary', - gameInfo: null - }) const [sortDescending, setSortDescending] = useState( JSON.parse(storage?.getItem('sortDescending') || 'false') ) @@ -245,7 +232,7 @@ export default React.memo(function Library(): JSX.Element { runner: Runner, gameInfo: GameInfo | null ) { - setShowModal({ game: appName, show: true, runner, gameInfo }) + openInstallGameModal({ appName, runner, gameInfo }) } // cache list of games being installed @@ -662,22 +649,6 @@ export default React.memo(function Library(): JSX.Element { - {showModal.show && ( - - setShowModal({ - game: '', - show: false, - runner: 'legendary', - gameInfo: null - }) - } - /> - )} - {showCategories && } ) diff --git a/src/frontend/state/GlobalState.tsx b/src/frontend/state/GlobalState.tsx index ba91b3aa3c..7430a6164e 100644 --- a/src/frontend/state/GlobalState.tsx +++ b/src/frontend/state/GlobalState.tsx @@ -23,7 +23,6 @@ import { getGameInfo, getLegendaryConfig, notify } from '../helpers' import { i18n, t, TFunction } from 'i18next' import ContextProvider from './ContextProvider' -import { InstallModal } from 'frontend/screens/Library/components' import { configStore, @@ -949,7 +948,6 @@ class GlobalState extends PureComponent { render() { const { - showInstallModal, language, epic, gog, @@ -1045,18 +1043,6 @@ class GlobalState extends PureComponent { }} > {this.props.children} - {showInstallModal.show && ( - - this.setState({ - showInstallModal: { ...showInstallModal, show: false } - }) - } - /> - )} ) } diff --git a/src/frontend/state/InstallGameModal.ts b/src/frontend/state/InstallGameModal.ts new file mode 100644 index 0000000000..dff21758ae --- /dev/null +++ b/src/frontend/state/InstallGameModal.ts @@ -0,0 +1,38 @@ +import { GameInfo, Runner } from 'common/types' +import { create } from 'zustand' + +interface InstallGameModalState { + isOpen: boolean + appName?: string + runner?: Runner + gameInfo: GameInfo | null +} + +export const useInstallGameModal = create()(() => ({ + isOpen: false, + gameInfo: null +})) + +interface OpenInstallGameModalParams { + appName: string + runner: Runner + gameInfo: GameInfo | null +} +export const openInstallGameModal = ({ + appName, + runner, + gameInfo +}: OpenInstallGameModalParams) => { + useInstallGameModal.setState({ + isOpen: true, + appName, + runner, + gameInfo + }) +} + +export const closeInstallGameModal = () => { + useInstallGameModal.setState({ + isOpen: false + }) +}