Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UX] Alt action to launch games with and without logs #4220

Open
wants to merge 1 commit into
base: improve-logs-ux
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/locales/en/gamepage.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
"launching": "Launching",
"playing": {
"start": "Play Now",
"start_with_logs": "Play Now (with logs)",
"stop": "Playing (Stop)"
},
"redist": "Installing Redistributables",
Expand Down
139 changes: 104 additions & 35 deletions src/frontend/screens/Game/GamePage/components/MainButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import GameContext from '../../GameContext'
import {
ArrowBackIosNew,
Cancel,
CloudQueue,
Download,
Expand All @@ -13,6 +14,7 @@ import {
} from '@mui/icons-material'
import classNames from 'classnames'
import { GameInfo } from 'common/types'
import useSetting from 'frontend/hooks/useSetting'

interface Props {
gameInfo: GameInfo
Expand All @@ -25,6 +27,7 @@ interface Props {
const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
const { t } = useTranslation('gamepage')
const { is } = useContext(GameContext)
const [verboseLogs, setVerboseLogs] = useSetting('verboseLogs', false)

function getPlayLabel(): React.ReactNode {
if (is.syncing) {
Expand Down Expand Up @@ -54,6 +57,15 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
)
}

if (verboseLogs) {
return (
<span className="buttonWithIcon">
<PlayArrow data-icon="play" />
{t('label.playing.start_with_logs', 'Play (with logs)')}
</span>
)
}

return (
<span className="buttonWithIcon">
<PlayArrow data-icon="play" />
Expand All @@ -62,6 +74,48 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
)
}

function showAltPlayAction() {
if (
is.syncing ||
is.installingRedist ||
is.installingWinetricksPackages ||
is.launching ||
is.playing
) {
return false
}

return true
}

function getAltPlayLabel() {
if (
is.syncing ||
is.installingRedist ||
is.installingWinetricksPackages ||
is.launching ||
is.playing
) {
return <></>
}

if (verboseLogs) {
return (
<span className="buttonWithIcon">
<PlayArrow data-icon="play" />
{t('label.playing.start')}
</span>
)
}

return (
<span className="buttonWithIcon">
<PlayArrow data-icon="play" />
{t('label.playing.start_with_logs', 'Play Now (with logs)')}
</span>
)
}

function getButtonLabel() {
if (is.notInstallable) {
return (
Expand Down Expand Up @@ -109,45 +163,60 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
)
}

const handleAltLaunch = async () => {
setVerboseLogs(!verboseLogs)
await handlePlay(gameInfo)
}

const is_installed = gameInfo.is_installed

return (
<>
<div className="playButtons">
{is_installed && !is.queued && (
<button
disabled={
is.reparing ||
is.moving ||
is.updating ||
is.uninstalling ||
is.syncing ||
is.launching ||
is.installingWinetricksPackages ||
is.installingRedist
}
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
},
'mainBtn'
<>
<button
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'
)}
disabled={
is.reparing ||
is.moving ||
is.updating ||
is.uninstalling ||
is.syncing ||
is.launching ||
is.installingWinetricksPackages ||
is.installingRedist
}
autoFocus={true}
onClick={async () => handlePlay(gameInfo)}
>
{getPlayLabel()}
</button>
{showAltPlayAction() && (
<button className="button altPlay is-success">
<ArrowBackIosNew />
<a className="button" onClick={handleAltLaunch}>
{getAltPlayLabel()}
</a>
</button>
)}
>
{getPlayLabel()}
</button>
</>
)}
{(!is_installed || is.queued) && (
<button
Expand Down Expand Up @@ -179,7 +248,7 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
{getButtonLabel()}
</button>
)}
</>
</div>
)
}

Expand Down
65 changes: 65 additions & 0 deletions src/frontend/screens/Game/GamePage/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,40 @@
max-width: 560px;
}

& .playButtons {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this CSS is partially duplicated on purpose for both old and new design, eventually we'll remove the old styles and it's easier to do that with duplications

display: flex;

.mainBtn {
flex-grow: 1;
}

.altPlay {
position: relative;
margin-inline-start: 1px;
padding-inline: 8px;

& > svg {
rotate: 270deg;
font-size: 0.7rem;
}

a {
display: none;
position: absolute;
top: 100%;
right: 0px;
white-space: nowrap;
}

&:focus,
&:hover {
a {
display: block;
}
}
}
}

.summary {
font-family: var(--primary-font-family);
font-style: normal;
Expand Down Expand Up @@ -655,6 +689,37 @@
padding: var(--space-sm) var(--space-md);
}

& .playButtons {
display: flex;
justify-content: center;

.altPlay {
position: relative;
margin-inline-start: 1px;
padding-inline: 8px;

& > svg {
rotate: 270deg;
font-size: 0.7rem;
}

a {
display: none;
position: absolute;
top: 100%;
right: 0px;
white-space: nowrap;
}

&:focus,
&:hover {
a {
display: block;
}
}
}
}

& .mainBtn {
min-width: 200px;
font-size: var(--text-md);
Expand Down
Loading
Loading