Skip to content

Commit 9a6278b

Browse files
authored
[Refactor] Make InstallModal global with state moved to zustand (#4268)
Make install modal global with state moved to zustand
1 parent 523526e commit 9a6278b

File tree

8 files changed

+74
-79
lines changed

8 files changed

+74
-79
lines changed

src/frontend/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { ThemeProvider, createTheme } from '@mui/material/styles'
1919
import LogFileUploadDialog from './components/UI/LogFileUploadDialog'
2020
import UploadedLogFilesList from './screens/Settings/sections/LogSettings/components/UploadedLogFilesList'
2121
import { TourProvider } from './state/TourContext'
22+
import { InstallGameWrapper } from './screens/Library/components/InstallModal'
2223

2324
function Root() {
2425
const {
@@ -74,6 +75,7 @@ function Root() {
7475
type={isSettingsModalOpen.type}
7576
/>
7677
)}
78+
<InstallGameWrapper />
7779
<ExternalLinkDialog />
7880
<LogFileUploadDialog />
7981
<UploadedLogFilesList />

src/frontend/screens/Game/GamePage/index.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import {
3232
import GamePicture from '../GamePicture'
3333
import TimeContainer from '../TimeContainer'
3434

35-
import { InstallModal } from 'frontend/screens/Library/components'
3635
import { install } from 'frontend/helpers/library'
3736
import { hasProgress } from 'frontend/hooks/hasProgress'
3837
import ErrorComponent from 'frontend/components/UI/ErrorComponent'
@@ -65,6 +64,7 @@ import { hasHelp } from 'frontend/hooks/hasHelp'
6564
import Genres from './components/Genres'
6665
import ReleaseDate from './components/ReleaseDate'
6766
import { hasKnownFixes } from 'frontend/hooks/hasKnownFixes'
67+
import { openInstallGameModal } from 'frontend/state/InstallGameModal'
6868

6969
export default React.memo(function GamePage(): JSX.Element | null {
7070
const { appName, runner } = useParams() as { appName: string; runner: Runner }
@@ -76,7 +76,6 @@ export default React.memo(function GamePage(): JSX.Element | null {
7676

7777
const { gameInfo: locationGameInfo } = location.state
7878

79-
const [showModal, setShowModal] = useState({ game: '', show: false })
8079
const [showUninstallModal, setShowUninstallModal] = useState(false)
8180
const [wikiInfo, setWikiInfo] = useState<WikiInfo | null>(null)
8281

@@ -256,7 +255,7 @@ export default React.memo(function GamePage(): JSX.Element | null {
256255
}
257256

258257
function handleModal() {
259-
setShowModal({ game: appName, show: true })
258+
openInstallGameModal({ appName, runner, gameInfo })
260259
}
261260

262261
let hasUpdate = false
@@ -366,14 +365,6 @@ export default React.memo(function GamePage(): JSX.Element | null {
366365
className="backgroundImage"
367366
/>
368367
)}
369-
{gameInfo.runner !== 'sideload' && showModal.show && (
370-
<InstallModal
371-
appName={showModal.game}
372-
runner={runner}
373-
backdropClick={() => setShowModal({ game: '', show: false })}
374-
gameInfo={gameInfo}
375-
/>
376-
)}
377368
{showUninstallModal && (
378369
<UninstallModal
379370
appName={appName}

src/frontend/screens/Game/GameSubMenu/index.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import { useTranslation } from 'react-i18next'
99
import ContextProvider from 'frontend/state/ContextProvider'
1010
import { NavLink } from 'react-router-dom'
1111

12-
import { InstallModal } from 'frontend/screens/Library/components'
1312
import { CircularProgress } from '@mui/material'
1413
import UninstallModal from 'frontend/components/UI/UninstallModal'
1514
import GameContext from '../GameContext'
15+
import { openInstallGameModal } from 'frontend/state/InstallGameModal'
1616

1717
interface Props {
1818
appName: string
@@ -59,7 +59,6 @@ export default function GamesSubmenu({
5959
const [hasShortcuts, setHasShortcuts] = useState(false)
6060
const [eosOverlayEnabled, setEosOverlayEnabled] = useState<boolean>(false)
6161
const [eosOverlayRefresh, setEosOverlayRefresh] = useState<boolean>(false)
62-
const [showModal, setShowModal] = useState(false)
6362
const eosOverlayAppName = '98bc04bc842e4906993fd6d6644ffb8d'
6463
const [showUninstallModal, setShowUninstallModal] = useState(false)
6564
const [protonDBurl, setProtonDBurl] = useState(
@@ -147,7 +146,7 @@ export default function GamesSubmenu({
147146
}
148147

149148
function handleEdit() {
150-
setShowModal(true)
149+
openInstallGameModal({ appName, runner, gameInfo })
151150
}
152151

153152
async function handleEosOverlay() {
@@ -414,13 +413,6 @@ export default function GamesSubmenu({
414413
)}
415414
</div>
416415
</div>
417-
{showModal && (
418-
<InstallModal
419-
appName={appName}
420-
runner={runner}
421-
backdropClick={() => setShowModal(false)}
422-
/>
423-
)}
424416
</>
425417
)
426418
}

src/frontend/screens/Library/components/InstallModal/index.tsx

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ import { SelectField } from 'frontend/components/UI'
2121
import { useTranslation } from 'react-i18next'
2222
import ThirdPartyDialog from './ThirdPartyDialog'
2323
import { MenuItem } from '@mui/material'
24+
import {
25+
closeInstallGameModal,
26+
useInstallGameModal
27+
} from 'frontend/state/InstallGameModal'
2428

2529
type Props = {
2630
appName: string
27-
backdropClick: () => void
2831
runner: Runner
2932
gameInfo?: GameInfo | null
3033
}
@@ -36,12 +39,7 @@ export type AvailablePlatforms = {
3639
icon: IconDefinition
3740
}[]
3841

39-
export default React.memo(function InstallModal({
40-
appName,
41-
backdropClick,
42-
runner,
43-
gameInfo = null
44-
}: Props) {
42+
function InstallModal({ appName, runner, gameInfo = null }: Props) {
4543
const { platform } = useContext(ContextProvider)
4644
const { t } = useTranslation('gamepage')
4745

@@ -155,10 +153,12 @@ export default React.memo(function InstallModal({
155153
const showDownloadDialog = !isSideload && gameInfo
156154
const isThirdPartyManagedApp = gameInfo && !!gameInfo.thirdPartyManagedApp
157155

156+
const closeModal = () => closeInstallGameModal()
157+
158158
return (
159159
<div className="InstallModal">
160160
<Dialog
161-
onClose={backdropClick}
161+
onClose={closeModal}
162162
showCloseButton
163163
className="InstallModal__dialog"
164164
>
@@ -169,7 +169,7 @@ export default React.memo(function InstallModal({
169169
winePrefix={winePrefix}
170170
wineVersion={wineVersion}
171171
availablePlatforms={availablePlatforms}
172-
backdropClick={backdropClick}
172+
backdropClick={closeModal}
173173
platformToInstall={platformToInstall}
174174
gameInfo={gameInfo}
175175
crossoverBottle={crossoverBottle}
@@ -197,7 +197,7 @@ export default React.memo(function InstallModal({
197197
winePrefix={winePrefix}
198198
wineVersion={wineVersion}
199199
availablePlatforms={availablePlatforms}
200-
backdropClick={backdropClick}
200+
backdropClick={closeModal}
201201
platformToInstall={platformToInstall}
202202
gameInfo={gameInfo}
203203
crossoverBottle={crossoverBottle}
@@ -223,7 +223,7 @@ export default React.memo(function InstallModal({
223223
winePrefix={winePrefix}
224224
wineVersion={wineVersion}
225225
availablePlatforms={availablePlatforms}
226-
backdropClick={backdropClick}
226+
backdropClick={closeModal}
227227
platformToInstall={platformToInstall}
228228
appName={appName}
229229
crossoverBottle={crossoverBottle}
@@ -246,4 +246,20 @@ export default React.memo(function InstallModal({
246246
</Dialog>
247247
</div>
248248
)
249-
})
249+
}
250+
251+
export function InstallGameWrapper() {
252+
const installGameModalState = useInstallGameModal()
253+
254+
if (!installGameModalState.isOpen) {
255+
return <></>
256+
}
257+
258+
return (
259+
<InstallModal
260+
appName={installGameModalState.appName!}
261+
runner={installGameModalState.runner!}
262+
gameInfo={installGameModalState.gameInfo}
263+
/>
264+
)
265+
}

src/frontend/screens/Library/components/index.tsx

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/frontend/screens/Library/index.tsx

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,17 @@ import {
2727
sideloadedCategories
2828
} from 'frontend/helpers/library'
2929
import RecentlyPlayed from './components/RecentlyPlayed'
30-
import { InstallModal } from './components'
3130
import LibraryContext from './LibraryContext'
3231
import { Category, PlatformsFilters, StoresFilters } from 'frontend/types'
3332
import { hasHelp } from 'frontend/hooks/hasHelp'
3433
import EmptyLibraryMessage from './components/EmptyLibrary'
3534
import CategoriesManager from './components/CategoriesManager'
3635
import LibraryTour from './components/LibraryTour'
3736
import AlphabetFilter from './components/AlphabetFilter'
37+
import { openInstallGameModal } from 'frontend/state/InstallGameModal'
3838

3939
const storage = window.localStorage
4040

41-
type ModalState = {
42-
game: string
43-
show: boolean
44-
runner: Runner
45-
gameInfo: GameInfo | null
46-
}
47-
4841
export default React.memo(function Library(): JSX.Element {
4942
const { t } = useTranslation()
5043

@@ -202,12 +195,6 @@ export default React.memo(function Library(): JSX.Element {
202195
string | null
203196
>(null)
204197

205-
const [showModal, setShowModal] = useState<ModalState>({
206-
game: '',
207-
show: false,
208-
runner: 'legendary',
209-
gameInfo: null
210-
})
211198
const [sortDescending, setSortDescending] = useState(
212199
JSON.parse(storage?.getItem('sortDescending') || 'false')
213200
)
@@ -267,7 +254,7 @@ export default React.memo(function Library(): JSX.Element {
267254
runner: Runner,
268255
gameInfo: GameInfo | null
269256
) {
270-
setShowModal({ game: appName, show: true, runner, gameInfo })
257+
openInstallGameModal({ appName, runner, gameInfo })
271258
}
272259

273260
// cache list of games being installed
@@ -735,22 +722,6 @@ export default React.memo(function Library(): JSX.Element {
735722
<ArrowDropUp id="backToTopArrow" className="material-icons" />
736723
</button>
737724

738-
{showModal.show && (
739-
<InstallModal
740-
appName={showModal.game}
741-
runner={showModal.runner}
742-
gameInfo={showModal.gameInfo}
743-
backdropClick={() =>
744-
setShowModal({
745-
game: '',
746-
show: false,
747-
runner: 'legendary',
748-
gameInfo: null
749-
})
750-
}
751-
/>
752-
)}
753-
754725
{showCategories && <CategoriesManager />}
755726
</LibraryContext.Provider>
756727
)

src/frontend/state/GlobalState.tsx

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import { getGameInfo, getLegendaryConfig, notify } from '../helpers'
2323
import { i18n, t, TFunction } from 'i18next'
2424

2525
import ContextProvider from './ContextProvider'
26-
import { InstallModal } from 'frontend/screens/Library/components'
2726

2827
import {
2928
configStore,
@@ -978,7 +977,6 @@ class GlobalState extends PureComponent<Props> {
978977

979978
render() {
980979
const {
981-
showInstallModal,
982980
language,
983981
epic,
984982
gog,
@@ -1074,18 +1072,6 @@ class GlobalState extends PureComponent<Props> {
10741072
}}
10751073
>
10761074
{this.props.children}
1077-
{showInstallModal.show && (
1078-
<InstallModal
1079-
appName={showInstallModal.appName}
1080-
runner={showInstallModal.runner}
1081-
gameInfo={showInstallModal.gameInfo}
1082-
backdropClick={() =>
1083-
this.setState({
1084-
showInstallModal: { ...showInstallModal, show: false }
1085-
})
1086-
}
1087-
/>
1088-
)}
10891075
</ContextProvider.Provider>
10901076
)
10911077
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { GameInfo, Runner } from 'common/types'
2+
import { create } from 'zustand'
3+
4+
interface InstallGameModalState {
5+
isOpen: boolean
6+
appName?: string
7+
runner?: Runner
8+
gameInfo: GameInfo | null
9+
}
10+
11+
export const useInstallGameModal = create<InstallGameModalState>()(() => ({
12+
isOpen: false,
13+
gameInfo: null
14+
}))
15+
16+
interface OpenInstallGameModalParams {
17+
appName: string
18+
runner: Runner
19+
gameInfo: GameInfo | null
20+
}
21+
export const openInstallGameModal = ({
22+
appName,
23+
runner,
24+
gameInfo
25+
}: OpenInstallGameModalParams) => {
26+
useInstallGameModal.setState({
27+
isOpen: true,
28+
appName,
29+
runner,
30+
gameInfo
31+
})
32+
}
33+
34+
export const closeInstallGameModal = () => {
35+
useInstallGameModal.setState({
36+
isOpen: false
37+
})
38+
}

0 commit comments

Comments
 (0)