diff options
| author | AAGaming <aa@mail.catvibers.me> | 2022-10-15 23:46:42 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-15 20:46:42 -0700 |
| commit | 6e3c05072cb507e2a376b7019836bea7bf663cb0 (patch) | |
| tree | 6171eb40ba1a76e1e2b24f8cac8545114a5ad4ef /frontend/src/components | |
| parent | 9b405e4bdc6ead86d69ad8f54af89a8d5b484f08 (diff) | |
| download | decky-loader-6e3c05072cb507e2a376b7019836bea7bf663cb0.tar.gz decky-loader-6e3c05072cb507e2a376b7019836bea7bf663cb0.zip | |
Developer menu (#211)v2.3.0-pre1
* add settings utils to use settings outside of components
* initial implementation of developer menu
* ✨ Add support for addScriptToEvaluateOnNewDocument
* React DevTools support
* increase chance of RDT successfully injecting
* Rewrite toaster hook to not re-create the window
* remove friends focus workaround because it's fixed
* Expose various DFL utilities as DFL in dev mode
* try to fix text field focuss
* move focusable to outside field
* add onTouchEnd and onClick to focusable
* Update pnpm-lock.yaml
Co-authored-by: FinalDoom <7464170-FinalDoom@users.noreply.gitlab.com>
Co-authored-by: TrainDoctor <traindoctor@protonmail.com>
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/Toast.tsx | 2 | ||||
| -rw-r--r-- | frontend/src/components/settings/index.tsx | 50 | ||||
| -rw-r--r-- | frontend/src/components/settings/pages/developer/index.tsx | 84 | ||||
| -rw-r--r-- | frontend/src/components/settings/pages/general/index.tsx | 24 |
4 files changed, 138 insertions, 22 deletions
diff --git a/frontend/src/components/Toast.tsx b/frontend/src/components/Toast.tsx index 559c37c6..01a436d7 100644 --- a/frontend/src/components/Toast.tsx +++ b/frontend/src/components/Toast.tsx @@ -32,7 +32,7 @@ const Toast: FunctionComponent<ToastProps> = ({ toast }) => { return ( <div style={{ '--toast-duration': `${toast.nToastDurationMS}ms` } as React.CSSProperties} - className={joinClassNames(toastClasses.ToastPopup, toastClasses.toastEnter)} + className={toastClasses.toastEnter} > <div onClick={toast.data.onClick} diff --git a/frontend/src/components/settings/index.tsx b/frontend/src/components/settings/index.tsx index eb3a8bbd..01f7d407 100644 --- a/frontend/src/components/settings/index.tsx +++ b/frontend/src/components/settings/index.tsx @@ -1,25 +1,39 @@ import { SidebarNavigation } from 'decky-frontend-lib'; +import { lazy } from 'react'; +import { useSetting } from '../../utils/hooks/useSetting'; +import WithSuspense from '../WithSuspense'; import GeneralSettings from './pages/general'; import PluginList from './pages/plugin_list'; +const DeveloperSettings = lazy(() => import('./pages/developer')); + export default function SettingsPage() { - return ( - <SidebarNavigation - title="Decky Settings" - showTitle - pages={[ - { - title: 'General', - content: <GeneralSettings />, - route: '/decky/settings/general', - }, - { - title: 'Plugins', - content: <PluginList />, - route: '/decky/settings/plugins', - }, - ]} - /> - ); + const [isDeveloper, setIsDeveloper] = useSetting<boolean>('developer.enabled', false); + + const pages = [ + { + title: 'General', + content: <GeneralSettings isDeveloper={isDeveloper} setIsDeveloper={setIsDeveloper} />, + route: '/decky/settings/general', + }, + { + title: 'Plugins', + content: <PluginList />, + route: '/decky/settings/plugins', + }, + ]; + + if (isDeveloper) + pages.push({ + title: 'Developer', + content: ( + <WithSuspense> + <DeveloperSettings /> + </WithSuspense> + ), + route: '/decky/settings/developer', + }); + + return <SidebarNavigation title="Decky Settings" showTitle pages={pages} />; } diff --git a/frontend/src/components/settings/pages/developer/index.tsx b/frontend/src/components/settings/pages/developer/index.tsx new file mode 100644 index 00000000..447c9606 --- /dev/null +++ b/frontend/src/components/settings/pages/developer/index.tsx @@ -0,0 +1,84 @@ +import { Field, Focusable, TextField, Toggle } from 'decky-frontend-lib'; +import { useRef } from 'react'; +import { FaReact, FaSteamSymbol } from 'react-icons/fa'; + +import { setShouldConnectToReactDevTools, setShowValveInternal } from '../../../../developer'; +import { useSetting } from '../../../../utils/hooks/useSetting'; + +export default function DeveloperSettings() { + const [enableValveInternal, setEnableValveInternal] = useSetting<boolean>('developer.valve_internal', false); + const [reactDevtoolsEnabled, setReactDevtoolsEnabled] = useSetting<boolean>('developer.rdt.enabled', false); + const [reactDevtoolsIP, setReactDevtoolsIP] = useSetting<string>('developer.rdt.ip', ''); + const textRef = useRef<HTMLDivElement>(null); + + return ( + <> + <Field + label="Enable Valve Internal" + description={ + <span style={{ whiteSpace: 'pre-line' }}> + Enables the Valve internal developer menu.{' '} + <span style={{ color: 'red' }}>Do not touch anything in this menu unless you know what it does.</span> + </span> + } + icon={<FaSteamSymbol style={{ display: 'block' }} />} + > + <Toggle + value={enableValveInternal} + onChange={(toggleValue) => { + setEnableValveInternal(toggleValue); + setShowValveInternal(toggleValue); + }} + /> + </Field>{' '} + <Focusable + onTouchEnd={ + reactDevtoolsIP == '' + ? () => { + (textRef.current?.childNodes[0] as HTMLInputElement)?.focus(); + } + : undefined + } + onClick={ + reactDevtoolsIP == '' + ? () => { + (textRef.current?.childNodes[0] as HTMLInputElement)?.focus(); + } + : undefined + } + onOKButton={ + reactDevtoolsIP == '' + ? () => { + (textRef.current?.childNodes[0] as HTMLInputElement)?.focus(); + } + : undefined + } + > + <Field + label="Enable React DevTools" + description={ + <> + <span style={{ whiteSpace: 'pre-line' }}> + Enables connection to a computer running React DevTools. Changing this setting will reload Steam. Set + the IP address before enabling. + </span> + <div ref={textRef}> + <TextField label={'IP'} value={reactDevtoolsIP} onChange={(e) => setReactDevtoolsIP(e?.target.value)} /> + </div> + </> + } + icon={<FaReact style={{ display: 'block' }} />} + > + <Toggle + value={reactDevtoolsEnabled} + disabled={reactDevtoolsIP == ''} + onChange={(toggleValue) => { + setReactDevtoolsEnabled(toggleValue); + setShouldConnectToReactDevTools(toggleValue); + }} + /> + </Field> + </Focusable> + </> + ); +} diff --git a/frontend/src/components/settings/pages/general/index.tsx b/frontend/src/components/settings/pages/general/index.tsx index a37d8dab..768cfafb 100644 --- a/frontend/src/components/settings/pages/general/index.tsx +++ b/frontend/src/components/settings/pages/general/index.tsx @@ -1,13 +1,19 @@ -import { DialogButton, Field, TextField } from 'decky-frontend-lib'; +import { DialogButton, Field, TextField, Toggle } from 'decky-frontend-lib'; import { useState } from 'react'; -import { FaShapes } from 'react-icons/fa'; +import { FaShapes, FaTools } from 'react-icons/fa'; import { installFromURL } from '../../../../store'; import BranchSelect from './BranchSelect'; import RemoteDebuggingSettings from './RemoteDebugging'; import UpdaterSettings from './Updater'; -export default function GeneralSettings() { +export default function GeneralSettings({ + isDeveloper, + setIsDeveloper, +}: { + isDeveloper: boolean; + setIsDeveloper: (val: boolean) => void; +}) { const [pluginURL, setPluginURL] = useState(''); // const [checked, setChecked] = useState(false); // store these in some kind of State instead return ( @@ -25,6 +31,18 @@ export default function GeneralSettings() { <BranchSelect /> <RemoteDebuggingSettings /> <Field + label="Developer mode" + description={<span style={{ whiteSpace: 'pre-line' }}>Enables Decky's developer settings.</span>} + icon={<FaTools style={{ display: 'block' }} />} + > + <Toggle + value={isDeveloper} + onChange={(toggleValue) => { + setIsDeveloper(toggleValue); + }} + /> + </Field> + <Field label="Manual plugin install" description={<TextField label={'URL'} value={pluginURL} onChange={(e) => setPluginURL(e?.target.value)} />} icon={<FaShapes style={{ display: 'block' }} />} |
