Skip to content

Commit

Permalink
Migrate the isSettingsModalOpen and setIsSettingsModalOpen proper…
Browse files Browse the repository at this point in the history
…ties
  • Loading branch information
CommandMC committed Jun 17, 2024
1 parent 33bc521 commit 4adc7e6
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 75 deletions.
10 changes: 2 additions & 8 deletions src/frontend/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import { ThemeProvider, createTheme } from '@mui/material/styles'
import { useShallowGlobalState } from './state/GlobalStateV2'

function Root() {
const { isSettingsModalOpen, experimentalFeatures } =
useContext(ContextProvider)
const { experimentalFeatures } = useContext(ContextProvider)
const { isFullscreen, isFrameless, isRTL } = useShallowGlobalState(
'isFullscreen',
'isFrameless',
Expand Down Expand Up @@ -51,12 +50,7 @@ function Root() {
<Sidebar />
<main className="content">
<DialogHandler />
{isSettingsModalOpen.gameInfo && (
<SettingsModal
gameInfo={isSettingsModalOpen.gameInfo}
type={isSettingsModalOpen.type}
/>
)}
<SettingsModal />
<ExternalLinkDialog />
<Outlet />
</main>
Expand Down
12 changes: 8 additions & 4 deletions src/frontend/screens/Game/GamePage/components/ReportIssue.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import React, { useContext } from 'react'
import React from 'react'
import { GameInfo } from 'common/types'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons'
import ContextProvider from 'frontend/state/ContextProvider'
import { useTranslation } from 'react-i18next'
import { useShallowGlobalState } from 'frontend/state/GlobalStateV2'

interface Props {
gameInfo: GameInfo
}

const ReportIssue = ({ gameInfo }: Props) => {
const { t } = useTranslation('gamepage')
const { setIsSettingsModalOpen } = useContext(ContextProvider)
const { setIsSettingsModalOpen } = useShallowGlobalState(
'setIsSettingsModalOpen'
)

const showReportIssue =
gameInfo.is_installed && gameInfo.install.platform !== 'Browser'
Expand All @@ -22,7 +24,9 @@ const ReportIssue = ({ gameInfo }: Props) => {

return (
<span
onClick={() => setIsSettingsModalOpen(true, 'log', gameInfo)}
onClick={() =>
setIsSettingsModalOpen({ value: true, type: 'log', gameInfo })
}
className="clickable reportProblem"
role={'button'}
>
Expand Down
12 changes: 8 additions & 4 deletions src/frontend/screens/Game/GamePage/components/SettingsButton.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import React, { useContext } from 'react'
import React from 'react'
import { GameInfo } from 'common/types'
import ContextProvider from 'frontend/state/ContextProvider'
import { SvgButton } from 'frontend/components/UI'
import SettingsIcoAlt from 'frontend/assets/settings_icon_alt.svg?react'
import { useShallowGlobalState } from 'frontend/state/GlobalStateV2'

interface Props {
gameInfo: GameInfo
}

const SettingsButton = ({ gameInfo }: Props) => {
const { setIsSettingsModalOpen } = useContext(ContextProvider)
const { setIsSettingsModalOpen } = useShallowGlobalState(
'setIsSettingsModalOpen'
)

if (!gameInfo.is_installed) {
return null
}

return (
<SvgButton
onClick={() => setIsSettingsModalOpen(true, 'settings', gameInfo)}
onClick={() =>
setIsSettingsModalOpen({ value: true, type: 'settings', gameInfo })
}
className={`settings-icon`}
>
<SettingsIcoAlt />
Expand Down
16 changes: 7 additions & 9 deletions src/frontend/screens/Game/GamePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ import { hasAnticheatInfo } from 'frontend/hooks/hasAnticheatInfo'
import { hasHelp } from 'frontend/hooks/hasHelp'
import Genres from './components/Genres'
import ReleaseDate from './components/ReleaseDate'
import { useGlobalState } from 'frontend/state/GlobalStateV2'
import {
useGlobalState,
useShallowGlobalState
} from 'frontend/state/GlobalStateV2'
import { useShallow } from 'zustand/react/shallow'

export default React.memo(function GamePage(): JSX.Element | null {
Expand All @@ -88,17 +91,12 @@ export default React.memo(function GamePage(): JSX.Element | null {
const [showUninstallModal, setShowUninstallModal] = useState(false)
const [wikiInfo, setWikiInfo] = useState<WikiInfo | null>(null)

const {
epic,
gog,
showDialogModal,
isSettingsModalOpen,
connectivity,
experimentalFeatures
} = useContext(ContextProvider)
const { epic, gog, showDialogModal, connectivity, experimentalFeatures } =
useContext(ContextProvider)
const gameUpdatesIncludesThis = useGlobalState(
useShallow((state) => state.gameUpdates.includes(appName))
)
const { isSettingsModalOpen } = useShallowGlobalState('isSettingsModalOpen')

hasHelp(
'gamePage',
Expand Down
14 changes: 12 additions & 2 deletions src/frontend/screens/Game/GameSubMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { NavLink } from 'react-router-dom'
import { InstallModal } from 'frontend/screens/Library/components'
import { CircularProgress } from '@mui/material'
import UninstallModal from 'frontend/components/UI/UninstallModal'
import { useShallowGlobalState } from '../../../state/GlobalStateV2'

interface Props {
appName: string
Expand Down Expand Up @@ -44,8 +45,11 @@ export default function GamesSubmenu({
onShowModifyInstall,
gameInfo
}: Props) {
const { refresh, libraryStatus, showDialogModal, setIsSettingsModalOpen } =
const { refresh, libraryStatus, showDialogModal } =
useContext(ContextProvider)
const { setIsSettingsModalOpen } = useShallowGlobalState(
'setIsSettingsModalOpen'
)
const isWin = platform === 'win32'
const isLinux = platform === 'linux'

Expand Down Expand Up @@ -329,7 +333,13 @@ export default function GamesSubmenu({
</>
)}
<button
onClick={() => setIsSettingsModalOpen(true, 'category', gameInfo)}
onClick={() =>
setIsSettingsModalOpen({
value: true,
type: 'category',
gameInfo
})
}
className="link button is-text is-link"
>
{t('submenu.categories', 'Categories')}
Expand Down
32 changes: 20 additions & 12 deletions src/frontend/screens/Library/components/GameCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ import { getCardStatus, getImageFormatting } from './constants'
import { hasStatus } from 'frontend/hooks/hasStatus'
import fallBackImage from 'frontend/assets/heroic_card.jpg'
import LibraryContext from '../../LibraryContext'
import { useGlobalState } from 'frontend/state/GlobalStateV2'
import {
useGlobalState,
useShallowGlobalState
} from 'frontend/state/GlobalStateV2'
import { useShallow } from 'zustand/react/shallow'

interface Card {
Expand Down Expand Up @@ -92,13 +95,11 @@ const GameCard = ({

const navigate = useNavigate()

const {
hiddenGames,
favouriteGames,
showDialogModal,
setIsSettingsModalOpen,
activeController
} = useContext(ContextProvider)
const { hiddenGames, favouriteGames, showDialogModal, activeController } =
useContext(ContextProvider)
const { setIsSettingsModalOpen } = useShallowGlobalState(
'setIsSettingsModalOpen'
)

const { layout } = useContext(LibraryContext)

Expand Down Expand Up @@ -318,12 +319,14 @@ const GameCard = ({
{
// settings
label: t('submenu.settings', 'Settings'),
onclick: () => setIsSettingsModalOpen(true, 'settings', gameInfo),
onclick: () =>
setIsSettingsModalOpen({ value: true, type: 'settings', gameInfo }),
show: isInstalled && !isUninstalling && !isBrowserGame
},
{
label: t('submenu.logs', 'Logs'),
onclick: () => setIsSettingsModalOpen(true, 'log', gameInfo),
onclick: () =>
setIsSettingsModalOpen({ value: true, type: 'log', gameInfo }),
show: isInstalled && !isUninstalling && !isBrowserGame
},
{
Expand All @@ -345,7 +348,8 @@ const GameCard = ({
},
{
label: t('submenu.categories', 'Categories'),
onclick: () => setIsSettingsModalOpen(true, 'category', gameInfo),
onclick: () =>
setIsSettingsModalOpen({ value: true, type: 'category', gameInfo }),
show: true
},
{
Expand Down Expand Up @@ -478,7 +482,11 @@ const GameCard = ({
title={`${t('submenu.settings')} (${title})`}
className="settingsIcon"
onClick={() =>
setIsSettingsModalOpen(true, 'settings', gameInfo)
setIsSettingsModalOpen({
value: true,
type: 'settings',
gameInfo
})
}
>
<SettingsIcon />
Expand Down
22 changes: 18 additions & 4 deletions src/frontend/screens/Settings/components/SettingsModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React, { useContext, useMemo } from 'react'
import React, { useMemo } from 'react'
import { GameInfo } from 'common/types'
import {
Dialog,
DialogContent,
DialogHeader
} from 'frontend/components/UI/Dialog'
import ContextProvider from 'frontend/state/ContextProvider'
import { GamesSettings } from '../../sections'
import SettingsContext from '../../SettingsContext'
import useSettingsContext from 'frontend/hooks/useSettingsContext'
Expand All @@ -14,14 +13,17 @@ import './index.scss'
import { useTranslation } from 'react-i18next'
import { SettingsContextType } from 'frontend/types'
import CategorySettings from '../../sections/CategorySettings'
import { useShallowGlobalState } from 'frontend/state/GlobalStateV2'

type Props = {
gameInfo: GameInfo
type: 'settings' | 'log' | 'category'
}

function SettingsModal({ gameInfo, type }: Props) {
const { setIsSettingsModalOpen } = useContext(ContextProvider)
const { setIsSettingsModalOpen } = useShallowGlobalState(
'setIsSettingsModalOpen'
)
const { t } = useTranslation()

const { app_name: appName, runner, title } = gameInfo
Expand Down Expand Up @@ -67,4 +69,16 @@ function SettingsModal({ gameInfo, type }: Props) {
)
}

export default SettingsModal
// Wraps around SettingsModal to only render it if the modal should be open
// while avoiding re-renders in more complex top-level components
function SettingsModalWrapper() {
const { isSettingsModalOpen } = useShallowGlobalState('isSettingsModalOpen')

if (!isSettingsModalOpen.value) return null

const { gameInfo, type } = isSettingsModalOpen

return <SettingsModal gameInfo={gameInfo} type={type} />
}

export default SettingsModalWrapper
2 changes: 0 additions & 2 deletions src/frontend/state/ContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ const initialContext: ContextType = {
setHideChangelogsOnStartup: () => null,
lastChangelogShown: null,
setLastChangelogShown: () => null,
isSettingsModalOpen: { value: false, type: 'settings' },
setIsSettingsModalOpen: () => null,
experimentalFeatures: {
enableNewDesign: false,
enableHelp: false,
Expand Down
19 changes: 0 additions & 19 deletions src/frontend/state/GlobalState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -527,22 +527,6 @@ class GlobalState extends PureComponent<Props> {

getAmazonLoginData = async () => window.api.getAmazonLoginData()

handleSettingsModalOpen = (
value: boolean,
type?: 'settings' | 'log' | 'category',
gameInfo?: GameInfo
) => {
if (gameInfo) {
this.setState({
settingsModalOpen: { value, type, gameInfo }
})
} else {
this.setState({
settingsModalOpen: { value, gameInfo: null }
})
}
}

refresh = async (
library?: Runner | 'all',
checkUpdates = false
Expand Down Expand Up @@ -890,7 +874,6 @@ class GlobalState extends PureComponent<Props> {
favouriteGames,
customCategories,
hiddenGames,
settingsModalOpen,
hideChangelogsOnStartup,
lastChangelogShown,
libraryStatus
Expand Down Expand Up @@ -963,8 +946,6 @@ class GlobalState extends PureComponent<Props> {
setHideChangelogsOnStartup: this.setHideChangelogsOnStartup,
lastChangelogShown: lastChangelogShown,
setLastChangelogShown: this.setLastChangelogShown,
isSettingsModalOpen: settingsModalOpen,
setIsSettingsModalOpen: this.handleSettingsModalOpen,
setCurrentCustomCategories: this.setCurrentCustomCategories,
setDisableDialogBackdropClose: this.setDisableDialogBackdropClose
}}
Expand Down
17 changes: 16 additions & 1 deletion src/frontend/state/GlobalStateV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { persist } from 'zustand/middleware'
import { useShallow } from 'zustand/react/shallow'

import { configStore } from '../helpers/electronStores'
import type { HelpItem } from '../types'
import type { HelpItem, SettingsModalType } from '../types'
import type { GameInfo } from 'common/types'

const RTL_LANGUAGES = ['fa', 'ar']

Expand All @@ -22,6 +23,13 @@ interface GlobalStateV2 {
helpItems: Record<string, HelpItem>
addHelpItem: (key: string, item: HelpItem) => void
removeHelpItem: (key: string) => void

isSettingsModalOpen:
| { value: false; type?: undefined; gameInfo?: undefined }
| { value: true; type: SettingsModalType; gameInfo: GameInfo }
setIsSettingsModalOpen: (
newState: GlobalStateV2['isSettingsModalOpen'] | false
) => void
}

const useGlobalState = create<GlobalStateV2>()(
Expand Down Expand Up @@ -67,6 +75,13 @@ const useGlobalState = create<GlobalStateV2>()(
const updatedHelpItems = get().helpItems
delete updatedHelpItems[key]
set({ helpItems: updatedHelpItems })
},

isSettingsModalOpen: { value: false },
setIsSettingsModalOpen: (value) => {
if (typeof value === 'boolean')
set({ isSettingsModalOpen: { value: false } })
else set({ isSettingsModalOpen: value })
}
}),
{
Expand Down
12 changes: 2 additions & 10 deletions src/frontend/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,6 @@ export interface ContextType {
setHideChangelogsOnStartup: (value: boolean) => void
lastChangelogShown: string | null
setLastChangelogShown: (value: string) => void
isSettingsModalOpen: {
value: boolean
gameInfo?: GameInfo | null
type: 'settings' | 'log'
}
setIsSettingsModalOpen: (
value: boolean,
type?: 'settings' | 'log' | 'category',
gameInfo?: GameInfo
) => void
experimentalFeatures: ExperimentalFeatures
handleExperimentalFeatures: (newSetting: ExperimentalFeatures) => void
disableDialogBackdropClose: boolean
Expand Down Expand Up @@ -279,3 +269,5 @@ export interface HelpItem {
title: string
content: JSX.Element
}

export type SettingsModalType = 'settings' | 'log' | 'category'

0 comments on commit 4adc7e6

Please sign in to comment.