diff --git a/public/locales/en/gamepage.json b/public/locales/en/gamepage.json index 1433f09e99..3138710b3b 100644 --- a/public/locales/en/gamepage.json +++ b/public/locales/en/gamepage.json @@ -92,9 +92,11 @@ }, "changelogFor": "Changelog for {{gameTitle}}", "downloadSize": "Download Size", + "extra_info": "Extra info", "firstPlayed": "First Played", "getting-download-size": "Getting download size", "getting-install-size": "Getting install size", + "install_info": "Install info", "installSize": "Install Size", "language": "Language", "lastPlayed": "Last Played", diff --git a/src/frontend/App.css b/src/frontend/App.css index 3c8c20652c..29a2cee3f3 100644 --- a/src/frontend/App.css +++ b/src/frontend/App.css @@ -80,6 +80,12 @@ body { } } +/* Remove outline on the root element since it's not clickable anyway and it's partially hidden away by sidebar */ + +#root:focus-visible { + outline: none; +} + /* disable links when the help is open, so users cannot navigate to another page but still use the elements of the current page */ #root:has(.HelpContent.open) { diff --git a/src/frontend/App.tsx b/src/frontend/App.tsx index 96143b9b73..6450e5033b 100644 --- a/src/frontend/App.tsx +++ b/src/frontend/App.tsx @@ -15,6 +15,7 @@ import SettingsModal from './screens/Settings/components/SettingsModal' import ExternalLinkDialog from './components/UI/ExternalLinkDialog' import WindowControls from './components/UI/WindowControls' import classNames from 'classnames' +import { ThemeProvider, createTheme } from '@mui/material/styles' function Root() { const { @@ -29,6 +30,10 @@ function Root() { const hasNativeOverlayControls = navigator['windowControlsOverlay']?.visible const showOverlayControls = isFrameless && !hasNativeOverlayControls + const theme = createTheme({ + direction: isRTL ? 'rtl' : 'ltr' + }) + return (
e.preventDefault()} > - - -
- - {isSettingsModalOpen.gameInfo && ( - - )} - - -
-
- -
-
- {showOverlayControls && } - {experimentalFeatures.enableHelp && } + + + +
+ + {isSettingsModalOpen.gameInfo && ( + + )} + + +
+
+ +
+
+ {showOverlayControls && } + {experimentalFeatures.enableHelp && } +
) } diff --git a/src/frontend/components/UI/TabPanel/index.tsx b/src/frontend/components/UI/TabPanel/index.tsx new file mode 100644 index 0000000000..b4ba26525a --- /dev/null +++ b/src/frontend/components/UI/TabPanel/index.tsx @@ -0,0 +1,24 @@ +import React, { HTMLProps } from 'react' + +type TabPanelProps = HTMLProps & { + children?: React.ReactNode + index: string + value: string +} + +function TabPanel(props: Readonly) { + const { children, value, index, ...other } = props + + return ( +
+ {value === index &&
{children}
} +
+ ) +} + +export default TabPanel diff --git a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss index 71e873e557..000d595585 100644 --- a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss +++ b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss @@ -1,5 +1,7 @@ .howLongToBeat { display: flex; + justify-content: space-around; + gap: var(--space-sm-fixed); .circle { width: 100px; @@ -11,10 +13,10 @@ border-radius: 50%; /* change to a circle */ border: 2px solid; /* add a border */ color: var(--text-secondary); - margin-inline-end: 10px; padding: 0 var(--space-xs); background-color: transparent; cursor: pointer; + position: relative; &.green { border: 3px solid green; @@ -30,14 +32,20 @@ .circle__title { font-size: 0.8rem; + white-space: nowrap; + text-align: center; } .circle__value { font-size: 1.2rem; + white-space: nowrap; font-weight: var(--bold); } } .circle { + flex-basis: 33.3%; + aspect-ratio: 1 / 1; + height: auto; width: fit-content; min-width: 100px; justify-content: center; diff --git a/src/frontend/components/UI/index.tsx b/src/frontend/components/UI/index.tsx index 9b20a52762..d3b5895e55 100644 --- a/src/frontend/components/UI/index.tsx +++ b/src/frontend/components/UI/index.tsx @@ -3,6 +3,7 @@ export { default as InfoBox } from './InfoBox' export { default as LanguageSelector } from './LanguageSelector' export { default as SelectField } from './SelectField' export { default as SmallInfo } from './SmallInfo' +export { default as TabPanel } from './TabPanel' export { default as TextInputField } from './TextInputField' export { default as ToggleSwitch } from './ToggleSwitch' export { default as UpdateComponent } from './UpdateComponent' diff --git a/src/frontend/screens/Game/GamePage/components/CompatibilityInfo.tsx b/src/frontend/screens/Game/GamePage/components/CompatibilityInfo.tsx index 5caec44b3c..d189d2260a 100644 --- a/src/frontend/screens/Game/GamePage/components/CompatibilityInfo.tsx +++ b/src/frontend/screens/Game/GamePage/components/CompatibilityInfo.tsx @@ -81,7 +81,7 @@ const CompatibilityInfo = ({ gameInfo }: Props) => { )} {hasSteamDeckCompat && ( - + {t('info.steamdeck-compatibility-info', 'SteamDeck Compatibility')}: diff --git a/src/frontend/screens/Game/GamePage/components/GameStatus.tsx b/src/frontend/screens/Game/GamePage/components/GameStatus.tsx index be06f1cfd7..da14798dfc 100644 --- a/src/frontend/screens/Game/GamePage/components/GameStatus.tsx +++ b/src/frontend/screens/Game/GamePage/components/GameStatus.tsx @@ -4,6 +4,7 @@ import { GameInfo, InstallProgress } from 'common/types' import { getProgress } from 'frontend/helpers' import { useTranslation } from 'react-i18next' import { Link } from 'react-router-dom' +import { LinearProgress } from '@mui/material' interface Props { gameInfo: GameInfo @@ -118,9 +119,9 @@ const GameStatus = ({ gameInfo, progress, handleUpdate, hasUpdate }: Props) => { return (
{(is.installing || is.updating) && ( - )} diff --git a/src/frontend/screens/Game/GamePage/components/HLTB.tsx b/src/frontend/screens/Game/GamePage/components/HLTB.tsx index e641277c63..5ecad13be1 100644 --- a/src/frontend/screens/Game/GamePage/components/HLTB.tsx +++ b/src/frontend/screens/Game/GamePage/components/HLTB.tsx @@ -1,13 +1,22 @@ -import React, { useContext } from 'react' +import React, { useContext, useState } from 'react' import { useTranslation } from 'react-i18next' import GameContext from '../../GameContext' -import { Speed } from '@mui/icons-material' +import ContextProvider from 'frontend/state/ContextProvider' +import { Speed, ExpandMore } from '@mui/icons-material' +import { Accordion, AccordionSummary, AccordionDetails } from '@mui/material' import PopoverComponent from 'frontend/components/UI/PopoverComponent' import HowLongToBeat from 'frontend/components/UI/WikiGameInfo/components/HowLongToBeat' const HLTB = () => { const { t } = useTranslation('gamepage') const { wikiInfo } = useContext(GameContext) + const { experimentalFeatures } = useContext(ContextProvider) + + const [isExpanded, setIsExpanded] = useState(false) + + function handleExpansionChange() { + setIsExpanded((prevExpanded) => !prevExpanded) + } if (!wikiInfo) { return null @@ -19,23 +28,44 @@ const HLTB = () => { return null } - return ( - - - {t('howLongToBeat', 'How Long To Beat')} -
- } - > -
- + if (experimentalFeatures.enableNewDesign) { + return ( +
+ + } + aria-controls="hltb-content" + id="hltb-header" + title={t('info.clickToOpen', 'Click to open')} + > + + {t('howLongToBeat', 'How Long To Beat')} + + + + +
- - ) + ) + } else { + return ( + + + {t('howLongToBeat', 'How Long To Beat')} +
+ } + > +
+ +
+ + ) + } } export default HLTB diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index 0d8788ca06..bdc8fcb992 100644 --- a/src/frontend/screens/Game/GamePage/components/MainButton.tsx +++ b/src/frontend/screens/Game/GamePage/components/MainButton.tsx @@ -30,12 +30,8 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.syncing) { return ( + {t('label.saves.syncing')} - ) } @@ -52,16 +48,16 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.playing) { return ( + {t('label.playing.stop')} - ) } return ( + {t('label.playing.start')} - ) } @@ -70,21 +66,20 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.notInstallable) { return ( + {t('status.goodie', 'Not installable')} - ) } if (is.notSupportedGame) { return ( - {t('status.notSupported', 'Not supported')} + {t('status.notSupported', 'Not supported')} ) } @@ -92,12 +87,8 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.queued) { return ( + {t('button.queue.remove', 'Remove from Queue')} - ) } @@ -105,23 +96,15 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.installing) { return ( + {t('button.cancel')} - ) } return ( + {t('button.install')} - ) } @@ -144,17 +127,24 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { } autoFocus={true} onClick={async () => handlePlay(gameInfo)} - className={classNames('button', { - 'is-secondary': !is_installed && !is.queued, - 'is-success': - is.syncing || - (!is.updating && !is.playing && is_installed && !is.notAvailable), - 'is-tertiary': - is.playing || - (!is_installed && is.queued) || - (is_installed && is.notAvailable), - 'is-disabled': is.updating - })} + className={classNames( + 'button', + { + 'is-secondary': !is_installed && !is.queued, + 'is-success': + is.syncing || + (!is.updating && + !is.playing && + is_installed && + !is.notAvailable), + 'is-tertiary': + is.playing || + (!is_installed && is.queued) || + (is_installed && is.notAvailable), + 'is-disabled': is.updating + }, + 'mainBtn' + )} > {getPlayLabel()} @@ -172,15 +162,19 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { is.notInstallable } autoFocus={true} - className={classNames('button', { - 'is-primary': is_installed, - 'is-tertiary': - is.notAvailable || - is.installing || - is.queued || - is.notInstallable, - 'is-secondary': !is_installed && !is.queued - })} + className={classNames( + 'button', + { + 'is-primary': is_installed, + 'is-tertiary': + is.notAvailable || + is.installing || + is.queued || + is.notInstallable, + 'is-secondary': !is_installed && !is.queued + }, + 'mainBtn' + )} > {getButtonLabel()} diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 04c967f328..87033a21c6 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -334,14 +334,13 @@ } } - .installProgress[value] { - appearance: none; + .MuiLinearProgress-root { width: 169px; height: 5px; + background-color: var(--neutral-05); - &::-webkit-progress-value { - color: var(--success); - animation: animate-stripes 5s linear infinite; + .MuiLinearProgress-bar { + background-color: var(--success); } } @@ -417,6 +416,7 @@ & > svg { height: 20px; + margin-inline-end: 5px; /* for compatibility, before was hardcoded in JS*/ } } @@ -428,49 +428,91 @@ } .App:not(.oldDesign) .gameConfigContainer { - display: flex; - padding: 2vh 2vw; - height: 100%; - gap: min(3vw, 50px); + display: grid; + position: relative; + grid-template-columns: repeat( + 2, + minmax(0, 1fr) + ); /* assure that the columns are always the same width */ + grid-template-rows: min-content 1fr min-content; + row-gap: var(--space-md); + column-gap: min(var(--space-lg), 50px); + grid-template-areas: + 'top top' + 'main extra' + 'report report'; + + padding: var(--space-lg); + height: 100vh; + min-height: 600px; + overflow: hidden; align-items: flex-start; - max-height: 1100px; - .backButton, - .showInfo, - .showExtra, - .showRequirements { + /* + ** Adding icons to the MUI tabs makes them at least 72px high + ** min-height is guaranteed by the min height of the tab parent element itself + ** which is 44px + */ + .MuiTab-labelIcon { + min-height: unset; + } + + p { + margin-block-start: var(--space-xs); + margin-block-end: var(--space-xs); + } + + ::-webkit-scrollbar { + background: none; + } + + .backButton { justify-self: flex-start; width: 44px; height: 44px; padding: 6px; - background: var(--neutral-03); + color: var(--navbar-inactive); + background-color: var(--navbar-background); border-radius: 10px; display: grid; place-items: center; border: none; svg path { - fill: var(--neutral-06); + fill: currentColor; transition: fill 0.2s; } &:hover { - svg path { - fill: var(--neutral-05); - } + color: var(--navbar-active); + } + } + + .topRowWrapper { + display: flex; + grid-area: top; + gap: var(--space-sm); + z-index: 30; + + & > * { + filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.25)); + } + + .backButton { + margin-inline-end: auto; } } .mainInfoWrapper, .extraInfoWrapper { - flex-basis: 50%; - display: grid; - grid-template-rows: min-content 1fr; - row-gap: 20px; + display: flex; + flex-direction: column; + gap: var(--space-lg); + overflow-y: auto; } .mainInfo, - .tabContent { + .extraInfo { outline: 3px solid #8a8a8a; outline-offset: -3px; border-radius: 15px; @@ -481,6 +523,7 @@ justify-self: stretch; display: flex; flex-direction: column; + flex-grow: 1; & > * { position: relative; @@ -507,28 +550,11 @@ } .mainInfoWrapper { - grid-template-columns: 1fr min-content min-content; - grid-template-areas: 'back settings menu' 'main main main' 'report report report'; - column-gap: 15px; + grid-area: main; min-width: 300px; - width: 50%; - - .backButton { - grid-area: back; - } - - .game-actions { - grid-area: menu; - } - - .settings-icon { - grid-area: settings; - right: unset; - } .mainInfo { - grid-area: main; - padding: min(25vh, 300px) min(4vw, 70px) min(5vh, 25px); + padding: max(20vh, 125px) min(4vw, 70px) min(5vh, 25px); background-color: var(--body-background); .store-icon { @@ -571,10 +597,11 @@ .summary { overflow: auto; - font-size: 18px; - line-height: 34px; + font-size: var(--text-lg); + line-height: 1.5em; text-align: left; flex-grow: 1; + margin-top: var(--space-xs); } .genres { @@ -596,57 +623,94 @@ text-align: left; } + .MuiLinearProgress-root { + display: block; + background-color: var(--neutral-05); + + .MuiLinearProgress-bar { + background-color: var(--success); + } + } + .buttons { - display: grid; - grid-template-columns: 1fr 1fr; - column-gap: 10px; + display: flex; + flex-direction: column; + justify-content: center; + row-gap: 10px; margin-top: 15px; + width: auto; - // hiding the `uninstall` button temporarily until - // properly implemented - button:nth-child(2) { - display: none; + .buttonWithIcon > svg { + display: flex; + place-items: center; + justify-content: center; + margin-inline-end: var(--space-2xs); + width: auto; + max-height: 1em; } - } - } - .reportProblem { - grid-area: report; - svg { - margin-inline-end: 0.5rem; + & > button { + align-self: center; + max-height: unset; + padding: var(--space-sm) var(--space-md); + } + + & .mainBtn { + min-width: 200px; + font-size: var(--text-md); + + & svg { + transform: scale(1.2); + + &[data-icon='play'], + &[data-icon='stop'] { + /* For some reason Play/Stop icons are much smaller the rest */ + transform: scale(1.6); + } + } + } + + & .delBtn { + font-size: var(--text-sm); + padding: var(--space-2xs) var(--space-xs); + & svg { + margin-inline-end: 0; + } + } } } } .extraInfoWrapper { - .tabs { - display: flex; - gap: 15px; - justify-content: flex-end; - } + grid-area: extra; - .tabContent { + .extraInfo { padding: 4vh 1.5vw; & > div { - overflow: auto; - padding: 10px; + overflow-y: auto; + padding: 5px 10px; + max-width: 100%; } - &.infoTab, - &.extraTab { - & > div > *, - & > div > .popover-wrapper > * { + & div.infoTab, + & div.extraTab { + & > div > * { display: flex; text-align: end; - font-size: 16px; + font-size: var(--space-unit-fixed); line-height: 24px; - height: 56px; - gap: 10px; - padding: 10px 0; + gap: var(--space-sm-fixed); + padding: var(--space-unit-fixed) 0; align-items: center; border-bottom: 1px solid var(--base-06); + &:focus-visible, + &:has(:focus-visible) { + /* do not use :focus-within to prevent outline form appearing when using a mouse */ + outline: 2px auto -webkit-focus-ring-color; + } + &:last-child { border-bottom: 0px; } @@ -664,6 +728,7 @@ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + word-break: break-all; } &:hover .truncatedPath, @@ -673,10 +738,33 @@ background: var(--body-background); } } - .popover-wrapper { - overflow: visible; - .popover { - height: auto; + & > div > .hltbWrapper > .MuiAccordion-root { + background-color: unset; + box-shadow: none; + color: var(--text-default); + flex-grow: 1; + + & > .MuiAccordionSummary-root:focus-visible { + background: unset; /* no more darker background */ + } + + & > .MuiAccordionSummary-root { + padding: 0; + min-height: unset; + + & > .MuiAccordionSummary-content { + margin: 0; + display: flex; + gap: 10px; + } + + & .MuiAccordionSummary-expandIconWrapper { + color: inherit; + } + } + + .MuiAccordionDetails-root { + padding-bottom: 8px; } } } @@ -684,6 +772,14 @@ .anticheatInfo { max-width: none; + margin: 0; + } + } + + .reportProblem { + grid-area: report; + svg { + margin-inline-end: 0.5rem; } } @@ -692,10 +788,6 @@ max-width: 800px; height: 100%; } - .mainInfo, - .tabContent { - max-height: 900px; - } .store-icon { border-radius: 10px; @@ -720,22 +812,20 @@ width: 44px; position: relative; padding: 6px; - right: 6px; - background: var(--neutral-03); + color: var(--navbar-inactive); + background-color: var(--navbar-background); border-radius: 10px; display: grid; place-items: center; height: 44px; svg path { - fill: var(--neutral-06); + fill: currentColor; transition: fill 0.2s; } &:hover { - svg path { - fill: var(--neutral-05); - } + color: var(--navbar-active); } } @@ -747,7 +837,7 @@ .toggle { align-self: flex-end; border: none; - color: var(--neutral-06); + color: var(--navbar-inactive); font-size: var(--text-2xl); padding: var(--space-xs-fixed); cursor: pointer; @@ -757,14 +847,14 @@ justify-content: center; width: 44px; height: 44px; - background: var(--neutral-03); + background-color: var(--navbar-background); border-radius: 10px; } &:focus-within .toggle, &:hover .toggle, .toggle:hover { - color: var(--neutral-05); + color: var(--navbar-active); } .gameTools { @@ -772,7 +862,7 @@ opacity: 1; pointer-events: all; transition: all 0.2s; - background: var(--navbar-background); + background-color: var(--navbar-background); border-radius: 5px; z-index: 2; padding: 0; @@ -788,10 +878,11 @@ text-align: start; white-space: nowrap; font-size: 1rem; - background: var(--navbar-background); + background: none; + color: var(--navbar-inactive); &:hover { - color: var(--accent-overlay); + color: var(--navbar-active); } &:last-child { @@ -814,10 +905,18 @@ z-index: -1; top: 0; left: 0; - width: 100vw; - height: 100vh; + width: 100%; + height: 100%; overflow: hidden; object-fit: cover; - filter: blur(15px) brightness(30%); + filter: blur(15px); + opacity: 0.3; + /* scale is so there will be no ugly edges because of the blur */ + transform: scale(1.1); } } + +.App:not(.oldDesign).isRTL .gameConfigContainer .game-actions .gameTools { + left: 0; + right: unset; +} diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index 2baf0df508..f49ca92f92 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -7,8 +7,12 @@ import { ArrowBackIosNew, Info, Star, - Monitor + Monitor, + DeleteOutline } from '@mui/icons-material' + +import { Tab, Tabs } from '@mui/material' + import { getGameInfo, getInstallInfo, @@ -19,7 +23,8 @@ import { import { NavLink, useLocation, useParams } from 'react-router-dom' import { useTranslation } from 'react-i18next' import ContextProvider from 'frontend/state/ContextProvider' -import { CachedImage, UpdateComponent } from 'frontend/components/UI' +import { CachedImage, UpdateComponent, TabPanel } from 'frontend/components/UI' +import UninstallModal from 'frontend/components/UI/UninstallModal' import { ExtraInfo, @@ -78,6 +83,7 @@ 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) const { @@ -153,7 +159,9 @@ export default React.memo(function GamePage(): JSX.Element | null { const storage: Storage = window.localStorage - const [tab, setTab] = useState<'info' | 'extra' | 'requirements'>('info') + const [currentTab, setCurrentTab] = useState< + 'info' | 'extra' | 'requirements' + >('info') useEffect(() => { const updateGameInfo = async () => { @@ -354,6 +362,15 @@ export default React.memo(function GamePage(): JSX.Element | null { gameInfo={gameInfo} /> )} + {showUninstallModal && ( + setShowUninstallModal(false)} + isDlc={false} + /> + )} + {title ? ( {/* OLD DESIGN */} @@ -432,7 +449,7 @@ export default React.memo(function GamePage(): JSX.Element | null { {/* NEW DESIGN */} {experimentalFeatures.enableNewDesign && ( <> -
+
- - {!isBrowserGame && } + +
+
- {gameInfo.is_installed && } + {gameInfo.is_installed && ( + + )}
-
-
- - {hasWikiInfo && ( - - )} - {hasRequirements && ( - - )} -
- -
-
- {tab === 'info' && ( - <> - - - - + } + /> + {hasWikiInfo && ( + } + /> )} - {tab === 'extra' && ( - <> - - - - - + {hasRequirements && ( + } + /> )} - {tab === 'requirements' && } + +
+ + + + + + + + + + + + + + + +
+ )} diff --git a/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx b/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx index e703780828..4758e679fb 100644 --- a/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx +++ b/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx @@ -1,6 +1,11 @@ import { GameInfo } from 'common/types' import { BuildItem, GogInstallInfo } from 'common/types/gog' -import { InfoBox, ToggleSwitch, UpdateComponent } from 'frontend/components/UI' +import { + InfoBox, + ToggleSwitch, + UpdateComponent, + TabPanel +} from 'frontend/components/UI' import { getInstallInfo, getPreferredInstallLanguage } from 'frontend/helpers' import DLCDownloadListing from 'frontend/screens/Library/components/InstallModal/DownloadDialog/DLCDownloadListing' import React, { useEffect, useState } from 'react' @@ -20,27 +25,6 @@ interface GOGModifyInstallModal { onClose: () => void } -type TabPanelProps = { - children?: React.ReactNode - index: string - value: string -} - -function TabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props - - return ( -
- {value === index &&
{children}
} -
- ) -} - export default function GOGModifyInstallModal({ gameInfo, onClose diff --git a/src/frontend/screens/Settings/sections/GamesSettings/index.tsx b/src/frontend/screens/Settings/sections/GamesSettings/index.tsx index 7cda3b180c..f762a04696 100644 --- a/src/frontend/screens/Settings/sections/GamesSettings/index.tsx +++ b/src/frontend/screens/Settings/sections/GamesSettings/index.tsx @@ -34,6 +34,7 @@ import { BeforeLaunchScriptPath, AfterLaunchScriptPath } from '../../components' +import { TabPanel } from 'frontend/components/UI' import ContextProvider from 'frontend/state/ContextProvider' import Tools from '../../components/Tools' import SettingsContext from '../../SettingsContext' @@ -46,27 +47,6 @@ import FooterInfo from '../FooterInfo' import { Tabs, Tab } from '@mui/material' import { GameInfo } from 'common/types' -type TabPanelProps = { - children?: React.ReactNode - index: string - value: string -} - -function TabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props - - return ( -
- {value === index &&
{children}
} -
- ) -} - const windowsPlatforms = ['Win32', 'Windows', 'windows'] function getStartingTab(platform: string, gameInfo?: GameInfo | null): string { if (!gameInfo) {