Skip to content

Commit ea2e1c5

Browse files
authored
[UX] Alt action to launch games with and without logs (#4220)
* [UX] Alt "Play now" action to disable/enable logs with one click * A bit of refactor of the new code
1 parent d816220 commit ea2e1c5

File tree

6 files changed

+288
-197
lines changed

6 files changed

+288
-197
lines changed

public/locales/en/gamepage.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
"launching": "Launching",
177177
"playing": {
178178
"start": "Play Now",
179+
"start_with_logs": "Play Now (with logs)",
179180
"stop": "Playing (Stop)"
180181
},
181182
"redist": "Installing Redistributables",

src/backend/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ class GlobalConfigV0 extends GlobalConfig {
357357
beforeLaunchScriptPath: '',
358358
afterLaunchScriptPath: '',
359359
disableUMU: false,
360-
verboseLogs: false,
360+
verboseLogs: true,
361361
downloadProtonToSteam: false,
362362
advertiseAvxForRosetta: isMac && defaultWine.type === 'toolkit',
363363
noTrayIcon: false

src/frontend/screens/Game/GamePage/components/MainButton.tsx

Lines changed: 84 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useContext } from 'react'
22
import { useTranslation } from 'react-i18next'
33
import GameContext from '../../GameContext'
44
import {
5+
ArrowBackIosNew,
56
Cancel,
67
CloudQueue,
78
Download,
@@ -13,6 +14,7 @@ import {
1314
} from '@mui/icons-material'
1415
import classNames from 'classnames'
1516
import { GameInfo } from 'common/types'
17+
import useSetting from 'frontend/hooks/useSetting'
1618

1719
interface Props {
1820
gameInfo: GameInfo
@@ -25,6 +27,7 @@ interface Props {
2527
const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
2628
const { t } = useTranslation('gamepage')
2729
const { is } = useContext(GameContext)
30+
const [verboseLogs, setVerboseLogs] = useSetting('verboseLogs', true)
2831

2932
function getPlayLabel(): React.ReactNode {
3033
if (is.syncing) {
@@ -54,6 +57,15 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
5457
)
5558
}
5659

60+
if (verboseLogs) {
61+
return (
62+
<span className="buttonWithIcon">
63+
<PlayArrow data-icon="play" />
64+
{t('label.playing.start_with_logs', 'Play (with logs)')}
65+
</span>
66+
)
67+
}
68+
5769
return (
5870
<span className="buttonWithIcon">
5971
<PlayArrow data-icon="play" />
@@ -62,6 +74,34 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
6274
)
6375
}
6476

77+
function altPlayAction() {
78+
if (
79+
is.syncing ||
80+
is.installingRedist ||
81+
is.installingWinetricksPackages ||
82+
is.launching ||
83+
is.playing
84+
) {
85+
return <></>
86+
}
87+
88+
const label = verboseLogs
89+
? t('label.playing.start')
90+
: t('label.playing.start_with_logs', 'Play Now (with logs)')
91+
92+
return (
93+
<button className="button altPlay is-success">
94+
<ArrowBackIosNew />
95+
<a className="button" onClick={handleAltLaunch}>
96+
<span className="buttonWithIcon">
97+
<PlayArrow data-icon="play" />
98+
{label}
99+
</span>
100+
</a>
101+
</button>
102+
)
103+
}
104+
65105
function getButtonLabel() {
66106
if (is.notInstallable) {
67107
return (
@@ -109,45 +149,53 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
109149
)
110150
}
111151

152+
const handleAltLaunch = async () => {
153+
setVerboseLogs(!verboseLogs)
154+
await handlePlay(gameInfo)
155+
}
156+
112157
const is_installed = gameInfo.is_installed
113158

114159
return (
115-
<>
160+
<div className="playButtons">
116161
{is_installed && !is.queued && (
117-
<button
118-
disabled={
119-
is.reparing ||
120-
is.moving ||
121-
is.updating ||
122-
is.uninstalling ||
123-
is.syncing ||
124-
is.launching ||
125-
is.installingWinetricksPackages ||
126-
is.installingRedist
127-
}
128-
autoFocus={true}
129-
onClick={async () => handlePlay(gameInfo)}
130-
className={classNames(
131-
'button',
132-
{
133-
'is-secondary': !is_installed && !is.queued,
134-
'is-success':
135-
is.syncing ||
136-
(!is.updating &&
137-
!is.playing &&
138-
is_installed &&
139-
!is.notAvailable),
140-
'is-tertiary':
141-
is.playing ||
142-
(!is_installed && is.queued) ||
143-
(is_installed && is.notAvailable),
144-
'is-disabled': is.updating
145-
},
146-
'mainBtn'
147-
)}
148-
>
149-
{getPlayLabel()}
150-
</button>
162+
<>
163+
<button
164+
disabled={
165+
is.reparing ||
166+
is.moving ||
167+
is.updating ||
168+
is.uninstalling ||
169+
is.syncing ||
170+
is.launching ||
171+
is.installingWinetricksPackages ||
172+
is.installingRedist
173+
}
174+
autoFocus={true}
175+
onClick={async () => handlePlay(gameInfo)}
176+
className={classNames(
177+
'button',
178+
{
179+
'is-secondary': !is_installed && !is.queued,
180+
'is-success':
181+
is.syncing ||
182+
(!is.updating &&
183+
!is.playing &&
184+
is_installed &&
185+
!is.notAvailable),
186+
'is-tertiary':
187+
is.playing ||
188+
(!is_installed && is.queued) ||
189+
(is_installed && is.notAvailable),
190+
'is-disabled': is.updating
191+
},
192+
'mainBtn'
193+
)}
194+
>
195+
{getPlayLabel()}
196+
</button>
197+
{altPlayAction()}
198+
</>
151199
)}
152200
{(!is_installed || is.queued) && (
153201
<button
@@ -179,7 +227,7 @@ const MainButton = ({ gameInfo, handlePlay, handleInstall }: Props) => {
179227
{getButtonLabel()}
180228
</button>
181229
)}
182-
</>
230+
</div>
183231
)
184232
}
185233

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,47 @@
272272
align-self: center;
273273
}
274274

275+
& .playButtons {
276+
display: flex;
277+
justify-content: center;
278+
279+
.altPlay {
280+
position: relative;
281+
margin-inline-start: 1px;
282+
padding-inline: 8px;
283+
284+
& > svg {
285+
rotate: 90deg;
286+
font-size: 0.7rem;
287+
}
288+
289+
a {
290+
display: none;
291+
position: absolute;
292+
bottom: 100%;
293+
right: -10px;
294+
white-space: nowrap;
295+
}
296+
297+
&:focus,
298+
&:hover,
299+
&:focus-within {
300+
a {
301+
display: block;
302+
}
303+
}
304+
}
305+
}
306+
275307
& .mainBtn {
276308
min-width: 200px;
277309
font-size: var(--text-md);
278310
white-space: nowrap;
279311

312+
span {
313+
white-space: nowrap;
314+
}
315+
280316
& svg {
281317
transform: scale(1.2);
282318
height: 16px;

0 commit comments

Comments
 (0)