summaryrefslogtreecommitdiff
path: root/frontend/src/components
diff options
context:
space:
mode:
authorAAGaming <aa@mail.catvibers.me>2022-10-15 23:46:42 -0400
committerGitHub <noreply@github.com>2022-10-15 20:46:42 -0700
commit6e3c05072cb507e2a376b7019836bea7bf663cb0 (patch)
tree6171eb40ba1a76e1e2b24f8cac8545114a5ad4ef /frontend/src/components
parent9b405e4bdc6ead86d69ad8f54af89a8d5b484f08 (diff)
downloaddecky-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.tsx2
-rw-r--r--frontend/src/components/settings/index.tsx50
-rw-r--r--frontend/src/components/settings/pages/developer/index.tsx84
-rw-r--r--frontend/src/components/settings/pages/general/index.tsx24
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' }} />}