From b0533406f3f5a3e87cb90d35155a08c675f4a8e7 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sun, 3 Mar 2024 23:17:24 +0100 Subject: [PATCH 01/30] WIP: Better UX for new gamepage Signed-off-by: Kajot-dev --- public/locales/en/gamepage.json | 2 + src/frontend/components/UI/TabPanel/index.tsx | 24 ++++ .../components/HowLongToBeat/index.scss | 3 + src/frontend/components/UI/index.tsx | 1 + .../Game/GamePage/components/HLTBInline.tsx | 48 +++++++ .../Game/GamePage/components/MainButton.tsx | 20 ++- .../Game/GamePage/components/index.tsx | 1 + src/frontend/screens/Game/GamePage/index.scss | 116 ++++++++++------ src/frontend/screens/Game/GamePage/index.tsx | 125 +++++++++++------- .../Game/ModifyInstallModal/GOG/index.tsx | 23 +--- .../Settings/sections/GamesSettings/index.tsx | 22 +-- 11 files changed, 245 insertions(+), 140 deletions(-) create mode 100644 src/frontend/components/UI/TabPanel/index.tsx create mode 100644 src/frontend/screens/Game/GamePage/components/HLTBInline.tsx diff --git a/public/locales/en/gamepage.json b/public/locales/en/gamepage.json index 859cfb6051..a99153970a 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/components/UI/TabPanel/index.tsx b/src/frontend/components/UI/TabPanel/index.tsx new file mode 100644 index 0000000000..6d2f62fe14 --- /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..e842a3c745 100644 --- a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss +++ b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss @@ -38,6 +38,9 @@ } } .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/HLTBInline.tsx b/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx new file mode 100644 index 0000000000..86b564b26b --- /dev/null +++ b/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx @@ -0,0 +1,48 @@ +import React, { useContext, useState } from 'react' +import { useTranslation } from 'react-i18next' +import GameContext from '../../GameContext' +import { Speed, ExpandMore } from '@mui/icons-material' +import { Accordion, AccordionSummary, AccordionDetails } from '@mui/material' +import HowLongToBeat from 'frontend/components/UI/WikiGameInfo/components/HowLongToBeat' + +const HLTBInline = () => { + const { t } = useTranslation('gamepage') + const { wikiInfo } = useContext(GameContext) + + const [isExpanded, setIsExpanded] = useState(false) + + function handleChange() { + setIsExpanded((prevExpanded) => !prevExpanded) + } + + if (!wikiInfo) { + return null + } + + const howlongtobeat = wikiInfo.howlongtobeat + + if (!howlongtobeat) { + return null + } + + return ( +
+ + } + aria-control="hltb-content" + id="hltb-header" + title={t('info.clickToOpen', 'Click to open')} + > + + {t('howLongToBeat', 'How Long To Beat')} + + + + + +
+ ) +} + +export default HLTBInline diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index 0d8788ca06..ace50b61aa 100644 --- a/src/frontend/screens/Game/GamePage/components/MainButton.tsx +++ b/src/frontend/screens/Game/GamePage/components/MainButton.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from 'react' +import React, { useContext, DetailedHTMLProps, ButtonHTMLAttributes } from 'react' import { useTranslation } from 'react-i18next' import GameContext from '../../GameContext' import { @@ -14,7 +14,8 @@ import { import classNames from 'classnames' import { GameInfo } from 'common/types' -interface Props { +// we can't just use HTMLProps because of inconsistency in button's "type" attribute +interface Props extends DetailedHTMLProps, HTMLButtonElement> { gameInfo: GameInfo handlePlay: (gameInfo: GameInfo) => Promise handleInstall: ( @@ -22,7 +23,7 @@ interface Props { ) => Promise } -const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { +const MainButton = ({ gameInfo, handlePlay, handleInstall, ...other }: Props) => { const { t } = useTranslation('gamepage') const { is } = useContext(GameContext) @@ -128,6 +129,13 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { const is_installed = gameInfo.is_installed + const extraClassName = other.className + + if (extraClassName) { + // do not override internal classNames + delete other.className + } + return ( <> {is_installed && !is.queued && ( @@ -154,7 +162,8 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { (!is_installed && is.queued) || (is_installed && is.notAvailable), 'is-disabled': is.updating - })} + }, extraClassName)} + {...other} > {getPlayLabel()} @@ -180,7 +189,8 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { is.queued || is.notInstallable, 'is-secondary': !is_installed && !is.queued - })} + }, extraClassName)} + {...other} > {getButtonLabel()} diff --git a/src/frontend/screens/Game/GamePage/components/index.tsx b/src/frontend/screens/Game/GamePage/components/index.tsx index b7546ddd15..b5ab398d4b 100644 --- a/src/frontend/screens/Game/GamePage/components/index.tsx +++ b/src/frontend/screens/Game/GamePage/components/index.tsx @@ -3,6 +3,7 @@ export { default as DownloadSizeInfo } from './DownloadSizeInfo' export { default as InstalledInfo } from './InstalledInfo' export { default as Scores } from './Scores' export { default as HLTB } from './HLTB' +export { default as HLTBInline } from './HLTBInline' export { default as AppleWikiInfo } from './AppleWikiInfo' export { default as Requirements } from './Requirements' export { default as MainButton } from './MainButton' diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 04c967f328..2028fa5678 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -428,13 +428,29 @@ } .App:not(.oldDesign) .gameConfigContainer { - display: flex; + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr min-content; + row-gap: 20px; + column-gap: min(3vw, 50px); + grid-template-areas: + 'main extra' + 'report report'; + padding: 2vh 2vw; height: 100%; - gap: min(3vw, 50px); align-items: flex-start; max-height: 1100px; + /* + ** 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; + } + .backButton, .showInfo, .showExtra, @@ -463,14 +479,13 @@ .mainInfoWrapper, .extraInfoWrapper { - flex-basis: 50%; display: grid; grid-template-rows: min-content 1fr; row-gap: 20px; } .mainInfo, - .tabContent { + .extraInfo { outline: 3px solid #8a8a8a; outline-offset: -3px; border-radius: 15px; @@ -507,19 +522,9 @@ } .mainInfoWrapper { - grid-template-columns: 1fr min-content min-content; - grid-template-areas: 'back settings menu' 'main main main' 'report report report'; + grid-area: main; column-gap: 15px; min-width: 300px; - width: 50%; - - .backButton { - grid-area: back; - } - - .game-actions { - grid-area: menu; - } .settings-icon { grid-area: settings; @@ -527,7 +532,6 @@ } .mainInfo { - grid-area: main; padding: min(25vh, 300px) min(4vw, 70px) min(5vh, 25px); background-color: var(--body-background); @@ -597,51 +601,55 @@ } .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; + & > button { + align-self: center; + max-height: unset; } - } - } - .reportProblem { - grid-area: report; - svg { - margin-inline-end: 0.5rem; + & .mainBtn { + min-width: 200px; + } + + & .delBtn { + font-size: var(--text-sm); + padding: var(--space-xs); + } } } } .extraInfoWrapper { - .tabs { + grid-area: extra; + + .buttons { display: flex; - gap: 15px; + gap: 5px; justify-content: flex-end; } - .tabContent { + .extraInfo { padding: 4vh 1.5vw; & > div { overflow: auto; - padding: 10px; + padding: 5px 10px; } - &.infoTab, - &.extraTab { - & > div > *, - & > div > .popover-wrapper > * { + & div.infoTab, + & div.extraTab { + & > div > * { display: flex; text-align: end; font-size: 16px; line-height: 24px; - height: 56px; + min-height: 56px; gap: 10px; padding: 10px 0; align-items: center; @@ -673,10 +681,25 @@ 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 { + padding: 0; + min-height: unset; + + & > .MuiAccordionSummary-content { + margin: 0; + display: flex; + gap: 10px; + } + + & .MuiAccordionSummary-expandIconWrapper { + color: inherit; + } } } } @@ -687,13 +710,20 @@ } } + .reportProblem { + grid-area: report; + svg { + margin-inline-end: 0.5rem; + } + } + .mainInfoWrapper, .extraInfoWrapper { max-width: 800px; height: 100%; } .mainInfo, - .tabContent { + .extraInfo { max-height: 900px; } diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index debc536f40..318b855231 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,7 @@ 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 { ExtraInfo, @@ -54,6 +58,7 @@ import { DownloadSizeInfo, GameStatus, HLTB, + HLTBInline, InstalledInfo, LaunchOptions, MainButton, @@ -152,7 +157,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 () => { @@ -425,8 +432,6 @@ export default React.memo(function GamePage(): JSX.Element | null { - - {!isBrowserGame && }
- {gameInfo.is_installed && } + {gameInfo.is_installed && ( + + )}
-
-
- - {hasWikiInfo && ( - - )} - {hasRequirements && ( - - )} +
+ {!isBrowserGame && } +
-
-
- {tab === 'info' && ( - <> - - - - +
+ setCurrentTab(newVal)} + aria-label="gameinfo tabs" + variant="scrollable" + > + } + /> + {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..887513c7d3 100644 --- a/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx +++ b/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx @@ -1,6 +1,6 @@ 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 +20,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 93d8330ffc..9a76f193f5 100644 --- a/src/frontend/screens/Settings/sections/GamesSettings/index.tsx +++ b/src/frontend/screens/Settings/sections/GamesSettings/index.tsx @@ -31,6 +31,7 @@ import { IgnoreGameUpdates, Gamescope } from '../../components' +import { TabPanel } from 'frontend/components/UI' import ContextProvider from 'frontend/state/ContextProvider' import Tools from '../../components/Tools' import SettingsContext from '../../SettingsContext' @@ -43,27 +44,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) { From db59f11f32e9a5d482e8f4581b700fb126814d76 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sun, 3 Mar 2024 23:18:53 +0100 Subject: [PATCH 02/30] WIP: Update formatting Signed-off-by: Kajot-dev --- src/frontend/components/UI/TabPanel/index.tsx | 26 +++---- .../Game/GamePage/components/MainButton.tsx | 70 +++++++++++++------ src/frontend/screens/Game/GamePage/index.tsx | 2 +- .../Game/ModifyInstallModal/GOG/index.tsx | 7 +- 4 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/frontend/components/UI/TabPanel/index.tsx b/src/frontend/components/UI/TabPanel/index.tsx index 6d2f62fe14..b4ba26525a 100644 --- a/src/frontend/components/UI/TabPanel/index.tsx +++ b/src/frontend/components/UI/TabPanel/index.tsx @@ -1,24 +1,24 @@ import React, { HTMLProps } from 'react' type TabPanelProps = HTMLProps & { - children?: React.ReactNode - index: string - value: string - } - + children?: React.ReactNode + index: string + value: string +} + function TabPanel(props: Readonly) { -const { children, value, index, ...other } = props + const { children, value, index, ...other } = props -return ( + return (
- {value === index &&
{children}
} + {value === index &&
{children}
}
-) + ) } export default TabPanel diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index ace50b61aa..15076b83b7 100644 --- a/src/frontend/screens/Game/GamePage/components/MainButton.tsx +++ b/src/frontend/screens/Game/GamePage/components/MainButton.tsx @@ -1,4 +1,8 @@ -import React, { useContext, DetailedHTMLProps, ButtonHTMLAttributes } from 'react' +import React, { + useContext, + DetailedHTMLProps, + ButtonHTMLAttributes +} from 'react' import { useTranslation } from 'react-i18next' import GameContext from '../../GameContext' import { @@ -15,7 +19,11 @@ import classNames from 'classnames' import { GameInfo } from 'common/types' // we can't just use HTMLProps because of inconsistency in button's "type" attribute -interface Props extends DetailedHTMLProps, HTMLButtonElement> { +interface Props + extends DetailedHTMLProps< + ButtonHTMLAttributes, + HTMLButtonElement + > { gameInfo: GameInfo handlePlay: (gameInfo: GameInfo) => Promise handleInstall: ( @@ -23,7 +31,12 @@ interface Props extends DetailedHTMLProps Promise } -const MainButton = ({ gameInfo, handlePlay, handleInstall, ...other }: Props) => { +const MainButton = ({ + gameInfo, + handlePlay, + handleInstall, + ...other +}: Props) => { const { t } = useTranslation('gamepage') const { is } = useContext(GameContext) @@ -152,17 +165,24 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall, ...other }: 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 - }, extraClassName)} + 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 + }, + extraClassName + )} {...other} > {getPlayLabel()} @@ -181,15 +201,19 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall, ...other }: 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 - }, extraClassName)} + className={classNames( + 'button', + { + 'is-primary': is_installed, + 'is-tertiary': + is.notAvailable || + is.installing || + is.queued || + is.notInstallable, + 'is-secondary': !is_installed && !is.queued + }, + extraClassName + )} {...other} > {getButtonLabel()} diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index 318b855231..5568a4ae63 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -533,7 +533,7 @@ export default React.memo(function GamePage(): JSX.Element | null { className="extraTab" > - + diff --git a/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx b/src/frontend/screens/Game/ModifyInstallModal/GOG/index.tsx index 887513c7d3..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, TabPanel } 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' From c1930a8977906640c81ff7347c5fbf2b3545d73a Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 16:28:21 +0100 Subject: [PATCH 03/30] Sticky topbar + UI polish --- src/frontend/screens/Game/GamePage/index.scss | 66 ++++++++++++------- src/frontend/screens/Game/GamePage/index.tsx | 28 ++++---- 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 2028fa5678..670a2b7581 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -429,18 +429,18 @@ .App:not(.oldDesign) .gameConfigContainer { display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr min-content; - row-gap: 20px; - column-gap: min(3vw, 50px); + 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: 2vh 2vw; + padding: var(--space-lg); height: 100%; align-items: flex-start; - max-height: 1100px; /* ** Adding icons to the MUI tabs makes them at least 72px high @@ -477,11 +477,38 @@ } } + .topRowWrapper { + display: flex; + flex-direction: row; + gap: min(var(--space-lg), 50px); + position: sticky; + top: var(--space-lg); + grid-area: top; + justify-content: space-between; + z-index: 30; + + .opts { + display: flex; + gap: var(--space-xs); + > * { + box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.25); + } + } + + .opts-left { + justify-content: flex-start; + } + + .opts-right { + justify-content: flex-end; + } + } + .mainInfoWrapper, .extraInfoWrapper { - display: grid; - grid-template-rows: min-content 1fr; - row-gap: 20px; + display: flex; + flex-direction: column; + gap: var(--space-lg); } .mainInfo, @@ -496,6 +523,7 @@ justify-self: stretch; display: flex; flex-direction: column; + flex-grow: 1; & > * { position: relative; @@ -523,14 +551,8 @@ .mainInfoWrapper { grid-area: main; - column-gap: 15px; min-width: 300px; - .settings-icon { - grid-area: settings; - right: unset; - } - .mainInfo { padding: min(25vh, 300px) min(4vw, 70px) min(5vh, 25px); background-color: var(--body-background); @@ -628,12 +650,6 @@ .extraInfoWrapper { grid-area: extra; - .buttons { - display: flex; - gap: 5px; - justify-content: flex-end; - } - .extraInfo { padding: 4vh 1.5vw; @@ -647,11 +663,10 @@ & > div > * { display: flex; text-align: end; - font-size: 16px; + font-size: var(--space-unit-fixed); line-height: 24px; - min-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); @@ -707,6 +722,7 @@ .anticheatInfo { max-width: none; + margin: 0; } } diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index 5568a4ae63..c34aaa3490 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -423,15 +423,22 @@ export default React.memo(function GamePage(): JSX.Element | null { {/* NEW DESIGN */} {experimentalFeatures.enableNewDesign && ( <> +
+
+ + + +
+
+ {!isBrowserGame && } + +
+
- - - -
-
- {!isBrowserGame && } - -
-
Date: Sat, 16 Mar 2024 16:28:33 +0100 Subject: [PATCH 04/30] HLTB styles improvement --- .../UI/WikiGameInfo/components/HowLongToBeat/index.scss | 7 ++++++- src/frontend/screens/Game/GamePage/index.scss | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss index e842a3c745..c6d60c95e0 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,6 +32,9 @@ .circle__title { font-size: 0.8rem; + white-space: normal; + max-width: 90%; + text-align: center; } .circle__value { diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 670a2b7581..b57b6020cc 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -716,6 +716,10 @@ color: inherit; } } + + .MuiAccordionDetails-root { + padding-bottom: 8px; + } } } } From b7e388b3ded7feea316164e9da9a6fb8013c4516 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 16:30:08 +0100 Subject: [PATCH 05/30] Fix formatting --- src/frontend/screens/Game/GamePage/index.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index b57b6020cc..828e86d7d0 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -429,7 +429,10 @@ .App:not(.oldDesign) .gameConfigContainer { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); /* assure that the columns are always the same width */ + 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); From 9b2547bb2f9db4773257d15ab4ee37660de551bc Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 17:07:26 +0100 Subject: [PATCH 06/30] Implement install button --- src/frontend/screens/Game/GamePage/index.scss | 2 +- src/frontend/screens/Game/GamePage/index.tsx | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 828e86d7d0..e655846755 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -644,7 +644,7 @@ & .delBtn { font-size: var(--text-sm); - padding: var(--space-xs); + padding: var(--space-xs) var(--space-sm); } } } diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index c34aaa3490..ad11d2b746 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -24,6 +24,7 @@ import { NavLink, useLocation, useParams } from 'react-router-dom' import { useTranslation } from 'react-i18next' import ContextProvider from 'frontend/state/ContextProvider' import { CachedImage, UpdateComponent, TabPanel } from 'frontend/components/UI' +import UninstallModal from 'frontend/components/UI/UninstallModal' import { ExtraInfo, @@ -83,6 +84,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 { @@ -353,6 +355,15 @@ export default React.memo(function GamePage(): JSX.Element | null { gameInfo={gameInfo} /> )} + {showUninstallModal && ( + setShowUninstallModal(false)} + isDlc={false} + /> + )} + {title ? ( {/* OLD DESIGN */} @@ -477,10 +488,15 @@ export default React.memo(function GamePage(): JSX.Element | null { className="mainBtn" /> {gameInfo.is_installed && ( - )} From 0557466d2955c4119f57e68711dd7c21dcd963d1 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 20:16:31 +0100 Subject: [PATCH 07/30] Fix aria-control attribute --- src/frontend/screens/Game/GamePage/components/HLTBInline.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx b/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx index 86b564b26b..a3d849f0bf 100644 --- a/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx +++ b/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx @@ -30,7 +30,7 @@ const HLTBInline = () => { } - aria-control="hltb-content" + aria-controls="hltb-content" id="hltb-header" title={t('info.clickToOpen', 'Click to open')} > From 3199362e9351637420935e0b014a4a71516a17d4 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 20:22:09 +0100 Subject: [PATCH 08/30] Remove unnecessary code --- src/frontend/screens/Game/GamePage/index.scss | 10 ---------- src/frontend/screens/Game/GamePage/index.tsx | 4 ++-- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index e655846755..014cd4da18 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -482,8 +482,6 @@ .topRowWrapper { display: flex; - flex-direction: row; - gap: min(var(--space-lg), 50px); position: sticky; top: var(--space-lg); grid-area: top; @@ -497,14 +495,6 @@ box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.25); } } - - .opts-left { - justify-content: flex-start; - } - - .opts-right { - justify-content: flex-end; - } } .mainInfoWrapper, diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index ad11d2b746..43f19559a1 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -435,7 +435,7 @@ export default React.memo(function GamePage(): JSX.Element | null { {experimentalFeatures.enableNewDesign && ( <>
-
+
-
+
{!isBrowserGame && }
From 2144987f153efda7578f7d329faedbcbd8445342 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 20:23:10 +0100 Subject: [PATCH 09/30] Fix HLTB breaking when hours were triple digits --- .../UI/WikiGameInfo/components/HowLongToBeat/index.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss index c6d60c95e0..7fd439331f 100644 --- a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss +++ b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss @@ -32,8 +32,7 @@ .circle__title { font-size: 0.8rem; - white-space: normal; - max-width: 90%; + white-space: nowrap; text-align: center; } From 23e2a4a60dfc3493b56d57210dac58ebe922ff39 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 21:22:06 +0100 Subject: [PATCH 10/30] Fix keyboard focus issues --- .../Game/GamePage/components/CompatibilityInfo.tsx | 2 +- src/frontend/screens/Game/GamePage/index.scss | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) 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/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 014cd4da18..c9131c02e6 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -663,6 +663,10 @@ align-items: center; border-bottom: 1px solid var(--base-06); + &:focus-visible, &:focus-within { + outline: 2px auto -webkit-focus-ring-color; + } + &:last-child { border-bottom: 0px; } @@ -695,6 +699,10 @@ color: var(--text-default); flex-grow: 1; + & > .MuiAccordionSummary-root:focus-visible { + background: unset; /* no more darker background */ + } + & > .MuiAccordionSummary-root { padding: 0; min-height: unset; From 2adb5ad90f249a9eec4bb02e1a54ccdf12b47510 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sat, 16 Mar 2024 21:22:29 +0100 Subject: [PATCH 11/30] Formatting --- src/frontend/screens/Game/GamePage/index.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index c9131c02e6..ffde8efe8f 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -663,7 +663,8 @@ align-items: center; border-bottom: 1px solid var(--base-06); - &:focus-visible, &:focus-within { + &:focus-visible, + &:focus-within { outline: 2px auto -webkit-focus-ring-color; } From 9aec2d8c775d3fe05a98f5e2cb124b135cfeb07f Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sun, 17 Mar 2024 00:54:46 +0100 Subject: [PATCH 12/30] Remove opts wrapper --- src/frontend/screens/Game/GamePage/index.scss | 15 ++++++------- src/frontend/screens/Game/GamePage/index.tsx | 22 ++++++++----------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index ffde8efe8f..198517e02f 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -485,15 +485,15 @@ position: sticky; top: var(--space-lg); grid-area: top; - justify-content: space-between; + gap: var(--space-sm); z-index: 30; - .opts { - display: flex; - gap: var(--space-xs); - > * { - box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.25); - } + & > * { + box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.25); + } + + .backButton { + margin-inline-end: auto; } } @@ -772,7 +772,6 @@ width: 44px; position: relative; padding: 6px; - right: 6px; background: var(--neutral-03); border-radius: 10px; display: grid; diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index 43f19559a1..43227163ea 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -435,19 +435,15 @@ export default React.memo(function GamePage(): JSX.Element | null { {experimentalFeatures.enableNewDesign && ( <>
-
- - - -
-
- {!isBrowserGame && } - -
+ + + + {!isBrowserGame && } +
From ec788fad5a83f056506c64c1756308bafc4acd24 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sun, 17 Mar 2024 01:03:13 +0100 Subject: [PATCH 13/30] Hardcode 'mainBtn' class --- .../Game/GamePage/components/MainButton.tsx | 33 +++---------------- src/frontend/screens/Game/GamePage/index.tsx | 1 - 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index 15076b83b7..bd0e1b911a 100644 --- a/src/frontend/screens/Game/GamePage/components/MainButton.tsx +++ b/src/frontend/screens/Game/GamePage/components/MainButton.tsx @@ -1,8 +1,4 @@ -import React, { - useContext, - DetailedHTMLProps, - ButtonHTMLAttributes -} from 'react' +import React, { useContext } from 'react' import { useTranslation } from 'react-i18next' import GameContext from '../../GameContext' import { @@ -18,12 +14,7 @@ import { import classNames from 'classnames' import { GameInfo } from 'common/types' -// we can't just use HTMLProps because of inconsistency in button's "type" attribute -interface Props - extends DetailedHTMLProps< - ButtonHTMLAttributes, - HTMLButtonElement - > { +interface Props { gameInfo: GameInfo handlePlay: (gameInfo: GameInfo) => Promise handleInstall: ( @@ -31,12 +22,7 @@ interface Props ) => Promise } -const MainButton = ({ - gameInfo, - handlePlay, - handleInstall, - ...other -}: Props) => { +const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { const { t } = useTranslation('gamepage') const { is } = useContext(GameContext) @@ -142,13 +128,6 @@ const MainButton = ({ const is_installed = gameInfo.is_installed - const extraClassName = other.className - - if (extraClassName) { - // do not override internal classNames - delete other.className - } - return ( <> {is_installed && !is.queued && ( @@ -181,9 +160,8 @@ const MainButton = ({ (is_installed && is.notAvailable), 'is-disabled': is.updating }, - extraClassName + 'mainBtn' )} - {...other} > {getPlayLabel()} @@ -212,9 +190,8 @@ const MainButton = ({ is.notInstallable, 'is-secondary': !is_installed && !is.queued }, - extraClassName + 'mainBtn' )} - {...other} > {getButtonLabel()} diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index 43227163ea..efde9b1cd3 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -481,7 +481,6 @@ export default React.memo(function GamePage(): JSX.Element | null { gameInfo={gameInfo} handlePlay={handlePlay} handleInstall={handleInstall} - className="mainBtn" /> {gameInfo.is_installed && (
- } - > -
- + 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/HLTBInline.tsx b/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx deleted file mode 100644 index a3d849f0bf..0000000000 --- a/src/frontend/screens/Game/GamePage/components/HLTBInline.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { useContext, useState } from 'react' -import { useTranslation } from 'react-i18next' -import GameContext from '../../GameContext' -import { Speed, ExpandMore } from '@mui/icons-material' -import { Accordion, AccordionSummary, AccordionDetails } from '@mui/material' -import HowLongToBeat from 'frontend/components/UI/WikiGameInfo/components/HowLongToBeat' - -const HLTBInline = () => { - const { t } = useTranslation('gamepage') - const { wikiInfo } = useContext(GameContext) - - const [isExpanded, setIsExpanded] = useState(false) - - function handleChange() { - setIsExpanded((prevExpanded) => !prevExpanded) - } - - if (!wikiInfo) { - return null - } - - const howlongtobeat = wikiInfo.howlongtobeat - - if (!howlongtobeat) { - return null - } - - return ( -
- - } - aria-controls="hltb-content" - id="hltb-header" - title={t('info.clickToOpen', 'Click to open')} - > - - {t('howLongToBeat', 'How Long To Beat')} - - - - - -
- ) -} - -export default HLTBInline diff --git a/src/frontend/screens/Game/GamePage/components/index.tsx b/src/frontend/screens/Game/GamePage/components/index.tsx index b5ab398d4b..b7546ddd15 100644 --- a/src/frontend/screens/Game/GamePage/components/index.tsx +++ b/src/frontend/screens/Game/GamePage/components/index.tsx @@ -3,7 +3,6 @@ export { default as DownloadSizeInfo } from './DownloadSizeInfo' export { default as InstalledInfo } from './InstalledInfo' export { default as Scores } from './Scores' export { default as HLTB } from './HLTB' -export { default as HLTBInline } from './HLTBInline' export { default as AppleWikiInfo } from './AppleWikiInfo' export { default as Requirements } from './Requirements' export { default as MainButton } from './MainButton' diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index efde9b1cd3..3f8d55b182 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -59,7 +59,6 @@ import { DownloadSizeInfo, GameStatus, HLTB, - HLTBInline, InstalledInfo, LaunchOptions, MainButton, @@ -546,7 +545,7 @@ export default React.memo(function GamePage(): JSX.Element | null { className="extraTab" > - + From 85a70f8df400fabf6eafc86f35bfb33dd3c33a0d Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sun, 17 Mar 2024 13:52:42 +0100 Subject: [PATCH 18/30] Remove unnecessary outline on root element --- src/frontend/App.css | 6 ++++++ 1 file changed, 6 insertions(+) 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) { From 103b26c2d48099b12b2ea5a259b1683ba2c38336 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sun, 17 Mar 2024 16:14:09 +0100 Subject: [PATCH 19/30] Add nowrap to hte HLTB hour count --- .../UI/WikiGameInfo/components/HowLongToBeat/index.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss index 7fd439331f..000d595585 100644 --- a/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss +++ b/src/frontend/components/UI/WikiGameInfo/components/HowLongToBeat/index.scss @@ -38,6 +38,7 @@ .circle__value { font-size: 1.2rem; + white-space: nowrap; font-weight: var(--bold); } } From cdc142d8571df4ab9f544211fe93defccd99f987 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Sun, 17 Mar 2024 20:11:30 +0100 Subject: [PATCH 20/30] Scale bg-image correctly --- src/frontend/screens/Game/GamePage/index.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index e569fee899..d873d8a16a 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -876,8 +876,8 @@ 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%); From 2d0da1543ff241be56589212a05e356a841db53d Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Tue, 26 Mar 2024 01:12:31 +0100 Subject: [PATCH 21/30] Add support for the RTL --- src/frontend/App.tsx | 45 +++++++++++-------- src/frontend/screens/Game/GamePage/index.scss | 5 +++ 2 files changed, 31 insertions(+), 19 deletions(-) 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/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index d873d8a16a..39c4c061c0 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -883,3 +883,8 @@ filter: blur(15px) brightness(30%); } } + +.App:not(.oldDesign).isRTL .gameConfigContainer .game-actions .gameTools { + left: 0; + right: unset; +} From 72858dbc67909d7854689fade8043414c8b0b5d3 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Fri, 29 Mar 2024 10:08:12 +0100 Subject: [PATCH 22/30] Style the progressbar --- src/frontend/screens/Game/GamePage/index.scss | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 39c4c061c0..d6d2fd672c 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -627,6 +627,24 @@ text-align: left; } + .installProgress[value] { + /* display block affects margin-block-end */ + display: block; + appearance: none; + width: 100%; + height: var(--text-xs); + overflow: hidden; + border-radius: 2px; + + &::-webkit-progress-bar { + background-color: var(--neutral-05); + } + + &::-webkit-progress-value { + background-color: var(--success); + } + } + .buttons { display: flex; flex-direction: column; From bf3029c7d07a072fcf7aacb5b9622e71040bbb06 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Mon, 1 Apr 2024 12:49:16 +0200 Subject: [PATCH 23/30] Make nav buttons respect current theme --- src/frontend/screens/Game/GamePage/index.scss | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index d6d2fd672c..010b5acd9d 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -466,28 +466,25 @@ background: none; } - .backButton, - .showInfo, - .showExtra, - .showRequirements { + .backButton { justify-self: flex-start; width: 44px; height: 44px; padding: 6px; - background: var(--neutral-03); + background-color: var(--background-lighter, var(--navbar-background)); border-radius: 10px; display: grid; place-items: center; border: none; svg path { - fill: var(--neutral-06); + fill: var(--text-default); transition: fill 0.2s; } &:hover { svg path { - fill: var(--neutral-05); + fill: var(--accent); } } } @@ -801,20 +798,20 @@ width: 44px; position: relative; padding: 6px; - background: var(--neutral-03); + background-color: var(--background-lighter, var(--navbar-background)); border-radius: 10px; display: grid; place-items: center; height: 44px; svg path { - fill: var(--neutral-06); + fill: var(--text-default); transition: fill 0.2s; } &:hover { svg path { - fill: var(--neutral-05); + fill: var(--accent); } } } @@ -827,7 +824,7 @@ .toggle { align-self: flex-end; border: none; - color: var(--neutral-06); + color: var(--text-default); font-size: var(--text-2xl); padding: var(--space-xs-fixed); cursor: pointer; @@ -837,14 +834,14 @@ justify-content: center; width: 44px; height: 44px; - background: var(--neutral-03); + background-color: var(--background-lighter, var(--navbar-background)); border-radius: 10px; } &:focus-within .toggle, &:hover .toggle, .toggle:hover { - color: var(--neutral-05); + color: var(--accent); } .gameTools { @@ -852,7 +849,7 @@ opacity: 1; pointer-events: all; transition: all 0.2s; - background: var(--navbar-background); + background-color: var(--background-lighter, var(--navbar-background)); border-radius: 5px; z-index: 2; padding: 0; @@ -868,7 +865,7 @@ text-align: start; white-space: nowrap; font-size: 1rem; - background: var(--navbar-background); + background: none; &:hover { color: var(--accent-overlay); From 5cc26723537a28c81639fafaf084c6dd4ec64cfd Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Mon, 1 Apr 2024 23:16:08 +0200 Subject: [PATCH 24/30] use MUI Progress for consistency --- .../Game/GamePage/components/GameStatus.tsx | 5 ++-- src/frontend/screens/Game/GamePage/index.scss | 24 ++++++------------- 2 files changed, 10 insertions(+), 19 deletions(-) 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/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 010b5acd9d..87c0ee55c2 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); } } @@ -624,20 +623,11 @@ text-align: left; } - .installProgress[value] { - /* display block affects margin-block-end */ + .MuiLinearProgress-root { display: block; - appearance: none; - width: 100%; - height: var(--text-xs); - overflow: hidden; - border-radius: 2px; - - &::-webkit-progress-bar { - background-color: var(--neutral-05); - } + background-color: var(--neutral-05); - &::-webkit-progress-value { + .MuiLinearProgress-bar { background-color: var(--success); } } From 62140963d2abfdb4d865855edff8f0b68414f644 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Mon, 1 Apr 2024 23:41:09 +0200 Subject: [PATCH 25/30] Better placed/scaled icons --- .../Game/GamePage/components/MainButton.tsx | 33 +++++-------------- src/frontend/screens/Game/GamePage/index.scss | 25 +++++++++++++- src/frontend/screens/Game/GamePage/index.tsx | 2 +- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index bd0e1b911a..be405c2e07 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')} + {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')} - + ) } diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 87c0ee55c2..85a3325104 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -640,18 +640,41 @@ margin-top: 15px; width: auto; + .buttonWithIcon > svg { + display: flex; + place-items: center; + justify-content: center; + margin-inline-end: var(--space-2xs); + width: auto; + max-height: 1em; + } + & > 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'] { + /* For some reason Play icon is much smaller the rest */ + transform: scale(1.6); + } + } } & .delBtn { font-size: var(--text-sm); - padding: var(--space-xs) var(--space-sm); + padding: var(--space-2xs) var(--space-xs); + & svg { + margin-inline-end: 0; + } } } } diff --git a/src/frontend/screens/Game/GamePage/index.tsx b/src/frontend/screens/Game/GamePage/index.tsx index 3f8d55b182..31b5f1849a 100644 --- a/src/frontend/screens/Game/GamePage/index.tsx +++ b/src/frontend/screens/Game/GamePage/index.tsx @@ -489,8 +489,8 @@ export default React.memo(function GamePage(): JSX.Element | null { }} > - {t('button.uninstall', 'Uninstall')} + {t('button.uninstall', 'Uninstall')} )} From 5fa27e2d13b1003169eadc04c182f321e945156d Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Mon, 1 Apr 2024 23:46:06 +0200 Subject: [PATCH 26/30] Icon scaling --- .../screens/Game/GamePage/components/MainButton.tsx | 2 +- src/frontend/screens/Game/GamePage/index.scss | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index be405c2e07..8531e2f02f 100644 --- a/src/frontend/screens/Game/GamePage/components/MainButton.tsx +++ b/src/frontend/screens/Game/GamePage/components/MainButton.tsx @@ -48,7 +48,7 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.playing) { return ( - + {t('label.playing.stop')} ) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index 85a3325104..a321a6632a 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -416,6 +416,7 @@ & > svg { height: 20px; + margin-inline-end: 5px; /* for compatibility, before was hardcoded in JS*/ } } @@ -662,8 +663,9 @@ & svg { transform: scale(1.2); - &[data-icon='play'] { - /* For some reason Play icon is much smaller the rest */ + &[data-icon='play'], + &[data-icon='stop'] { + /* For some reason Play/Stop icons are much smaller the rest */ transform: scale(1.6); } } From 41b59fdc3c8b9ac96ba12d827875eeaaeef06741 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Mon, 1 Apr 2024 23:46:32 +0200 Subject: [PATCH 27/30] Formatting --- .../screens/Game/GamePage/components/MainButton.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index 8531e2f02f..981d9114b4 100644 --- a/src/frontend/screens/Game/GamePage/components/MainButton.tsx +++ b/src/frontend/screens/Game/GamePage/components/MainButton.tsx @@ -30,7 +30,7 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.syncing) { return ( - + {t('label.saves.syncing')} ) @@ -87,7 +87,7 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.queued) { return ( - + {t('button.queue.remove', 'Remove from Queue')} ) @@ -96,7 +96,7 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { if (is.installing) { return ( - + {t('button.cancel')} ) @@ -104,7 +104,7 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { return ( {t('button.install')} - + ) } From e9b4a8f7421ea21939a4029b03bc2a718d40a8e5 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Tue, 2 Apr 2024 17:36:25 +0200 Subject: [PATCH 28/30] Make new gamepage work on light themes --- src/frontend/screens/Game/GamePage/index.scss | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index a321a6632a..c10c6c0e29 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -471,21 +471,20 @@ width: 44px; height: 44px; padding: 6px; - background-color: var(--background-lighter, var(--navbar-background)); + color: var(--navbar-inactive); + background-color: var(--navbar-background); border-radius: 10px; display: grid; place-items: center; border: none; svg path { - fill: var(--text-default); + fill: currentColor; transition: fill 0.2s; } &:hover { - svg path { - fill: var(--accent); - } + color: var(--navbar-active); } } @@ -813,21 +812,20 @@ width: 44px; position: relative; padding: 6px; - background-color: var(--background-lighter, var(--navbar-background)); + color: var(--navbar-inactive); + background-color: var(--navbar-background); border-radius: 10px; display: grid; place-items: center; height: 44px; svg path { - fill: var(--text-default); + fill: currentColor; transition: fill 0.2s; } &:hover { - svg path { - fill: var(--accent); - } + color: var(--navbar-active); } } @@ -839,7 +837,7 @@ .toggle { align-self: flex-end; border: none; - color: var(--text-default); + color: var(--navbar-inactive); font-size: var(--text-2xl); padding: var(--space-xs-fixed); cursor: pointer; @@ -849,14 +847,14 @@ justify-content: center; width: 44px; height: 44px; - background-color: var(--background-lighter, var(--navbar-background)); + background-color: var(--navbar-background); border-radius: 10px; } &:focus-within .toggle, &:hover .toggle, .toggle:hover { - color: var(--accent); + color: var(--navbar-active); } .gameTools { @@ -864,7 +862,7 @@ opacity: 1; pointer-events: all; transition: all 0.2s; - background-color: var(--background-lighter, var(--navbar-background)); + background-color: var(--navbar-background); border-radius: 5px; z-index: 2; padding: 0; @@ -881,9 +879,10 @@ white-space: nowrap; font-size: 1rem; background: none; + color: var(--navbar-inactive); &:hover { - color: var(--accent-overlay); + color: var(--navbar-active); } &:last-child { @@ -910,7 +909,10 @@ height: 100%; overflow: hidden; object-fit: cover; - filter: blur(15px) brightness(30%); + filter: blur(15px); + opacity: 0.7; + /* scale is so there will be no ugly edges because of the blur */ + transform: scale(1.1); } } From e224bcf3aee720a4ca35ba8330a19d2dae31a313 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Wed, 3 Apr 2024 18:43:25 +0200 Subject: [PATCH 29/30] Bad icon order when game is uninstalled --- src/frontend/screens/Game/GamePage/components/MainButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/screens/Game/GamePage/components/MainButton.tsx b/src/frontend/screens/Game/GamePage/components/MainButton.tsx index 981d9114b4..bdc8fcb992 100644 --- a/src/frontend/screens/Game/GamePage/components/MainButton.tsx +++ b/src/frontend/screens/Game/GamePage/components/MainButton.tsx @@ -103,8 +103,8 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => { } return ( - {t('button.install')} + {t('button.install')} ) } From 7a6ed76eee9e98a7c3d4bc2d5294e930b2ae60e1 Mon Sep 17 00:00:00 2001 From: Kajot-dev Date: Thu, 4 Apr 2024 19:14:41 +0200 Subject: [PATCH 30/30] Reduce background opacity --- src/frontend/screens/Game/GamePage/index.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/screens/Game/GamePage/index.scss b/src/frontend/screens/Game/GamePage/index.scss index c10c6c0e29..87033a21c6 100644 --- a/src/frontend/screens/Game/GamePage/index.scss +++ b/src/frontend/screens/Game/GamePage/index.scss @@ -910,7 +910,7 @@ overflow: hidden; object-fit: cover; filter: blur(15px); - opacity: 0.7; + opacity: 0.3; /* scale is so there will be no ugly edges because of the blur */ transform: scale(1.1); }