diff options
| author | AAGaming <aagaming@riseup.net> | 2026-10-26 23:50:59 -0400 |
|---|---|---|
| committer | AAGaming <aagaming@riseup.net> | 2026-10-26 23:50:59 -0400 |
| commit | e82a55e9582fbd6d84f3f4510b04480c35e41fe4 (patch) | |
| tree | 1fe05c2296bbedbf301137a67a28ef542804fd69 /frontend/src/components | |
| parent | 6301508037b30489c42ee9ea8acee97cdea76297 (diff) | |
| download | decky-loader-e82a55e9582fbd6d84f3f4510b04480c35e41fe4.tar.gz decky-loader-e82a55e9582fbd6d84f3f4510b04480c35e41fe4.zip | |
feat: initial VERY VERY incomplete steam frame support
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/NotificationBadge.tsx | 55 | ||||
| -rw-r--r-- | frontend/src/components/PluginView.tsx | 40 | ||||
| -rw-r--r-- | frontend/src/components/QuickAccessVisibleState.tsx | 17 | ||||
| -rw-r--r-- | frontend/src/components/settings/pages/developer/index.tsx | 33 |
4 files changed, 98 insertions, 47 deletions
diff --git a/frontend/src/components/NotificationBadge.tsx b/frontend/src/components/NotificationBadge.tsx index 3c5d8215..1d14d576 100644 --- a/frontend/src/components/NotificationBadge.tsx +++ b/frontend/src/components/NotificationBadge.tsx @@ -2,23 +2,52 @@ import { CSSProperties, FunctionComponent } from 'react'; interface NotificationBadgeProps { show?: boolean; + vr?: boolean; style?: CSSProperties; } -const NotificationBadge: FunctionComponent<NotificationBadgeProps> = ({ show, style }) => { +const NotificationBadge: FunctionComponent<NotificationBadgeProps> = ({ show, style, vr }) => { return show ? ( - <div - style={{ - position: 'absolute', - top: '8px', - right: '8px', - height: '10px', - width: '10px', - background: 'orange', - borderRadius: '50%', - ...style, - }} - /> + vr ? ( + // whoever made transform:scale completely break absolute positioning goes straight to super turbo hell this took me an hour + <div + style={{ + top: 0, + left: 0, + marginLeft: 'auto', + width: 0, + height: 0, + overflow: 'visible', + transform: 'translate(0px, 0px)', + }} + > + <div + style={{ + position: 'fixed', + top: '-18px', + right: '-6px', + width: '10px', + height: '10px', + background: 'orange', + borderRadius: '50%', + ...style, + }} + /> + </div> + ) : ( + <div + style={{ + position: 'absolute', + top: '8px', + right: '8px', + height: '10px', + width: '10px', + background: 'orange', + borderRadius: '50%', + ...style, + }} + /> + ) ) : null; }; diff --git a/frontend/src/components/PluginView.tsx b/frontend/src/components/PluginView.tsx index fbafaf05..27c1f2f1 100644 --- a/frontend/src/components/PluginView.tsx +++ b/frontend/src/components/PluginView.tsx @@ -1,4 +1,12 @@ -import { ButtonItem, ErrorBoundary, Focusable, PanelSection, PanelSectionRow } from '@decky/ui'; +import { + ButtonItem, + ErrorBoundary, + Focusable, + PanelSection, + PanelSectionRow, + joinClassNames, + vrDashboardClasses, +} from '@decky/ui'; import { FC, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { FaBan, FaEyeSlash } from 'react-icons/fa'; @@ -8,7 +16,7 @@ import NotificationBadge from './NotificationBadge'; import { useQuickAccessVisible } from './QuickAccessVisibleState'; import TitleView from './TitleView'; -const PluginView: FC = () => { +const PluginView: FC<{ vr?: boolean }> = ({ vr }) => { const { plugins, disabledPlugins, @@ -40,20 +48,38 @@ const PluginView: FC = () => { if (activePlugin) { return ( - <Focusable onCancelButton={closeActivePlugin}> + <Focusable + onCancelButton={closeActivePlugin} + className={ + (vr && joinClassNames(vrDashboardClasses.QuickAccessPopupPanel, vrDashboardClasses.BottomFade)) || '' + } + style={{ + display: 'flex', + flexDirection: 'column', + paddingBottom: '20px', // override bottomfade, there is prolly a better way + }} + > <TitleView /> - <div style={{ height: '100%', paddingTop: '16px' }}> + <div style={{ paddingTop: '16px', overflowY: vr ? 'auto' : undefined }}> <ErrorBoundary>{(visible || activePlugin.alwaysRender) && activePlugin.content}</ErrorBoundary> </div> </Focusable> ); } return ( - <> + <div + className={(vr && joinClassNames(vrDashboardClasses.QuickAccessPopupPanel, vrDashboardClasses.BottomFade)) || ''} + style={{ + display: 'flex', + flexDirection: 'column', + paddingBottom: '20px', // override bottomfade, there is prolly a better way + }} + > <TitleView /> <div style={{ - paddingTop: '16px', + paddingTop: vr ? '16px' : '16px', + overflowY: vr ? 'auto' : undefined, }} > <PanelSection> @@ -92,7 +118,7 @@ const PluginView: FC = () => { </div> </PanelSection> </div> - </> + </div> ); }; diff --git a/frontend/src/components/QuickAccessVisibleState.tsx b/frontend/src/components/QuickAccessVisibleState.tsx index f90c24b4..83e45177 100644 --- a/frontend/src/components/QuickAccessVisibleState.tsx +++ b/frontend/src/components/QuickAccessVisibleState.tsx @@ -1,16 +1,21 @@ import { FC, PropsWithChildren, createContext, useContext, useState } from 'react'; -const QuickAccessVisibleState = createContext<boolean>(false); +export const QuickAccessVisibleState = createContext<boolean>(false); export const useQuickAccessVisible = () => useContext(QuickAccessVisibleState); -export const QuickAccessVisibleStateProvider: FC<PropsWithChildren<{ tab: any }>> = ({ children, tab }) => { - const initial = tab.initialVisibility; +export const QuickAccessVisibleStateProvider: FC<PropsWithChildren<{ tab?: any; initialVal?: boolean }>> = ({ + children, + tab, + initialVal, +}) => { + const initial = initialVal || tab?.initialVisibility; const [visible, setVisible] = useState<boolean>(initial); // HACK but i can't think of a better way to do this - tab.qAMVisibilitySetter = (val: boolean) => { - if (val != visible) setVisible(val); - }; + if (tab) + tab.qAMVisibilitySetter = (val: boolean) => { + if (val != visible) setVisible(val); + }; return <QuickAccessVisibleState.Provider value={visible}>{children}</QuickAccessVisibleState.Provider>; }; diff --git a/frontend/src/components/settings/pages/developer/index.tsx b/frontend/src/components/settings/pages/developer/index.tsx index 17187675..b6a337f0 100644 --- a/frontend/src/components/settings/pages/developer/index.tsx +++ b/frontend/src/components/settings/pages/developer/index.tsx @@ -9,7 +9,7 @@ import { Toggle, showModal, } from '@decky/ui'; -import { useRef, useState } from 'react'; +import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { FaFileArchive, FaLink, FaReact, FaSteamSymbol, FaTerminal } from 'react-icons/fa'; @@ -49,7 +49,6 @@ export default function DeveloperSettings() { const [acceptedWarning, setAcceptedWarning] = useSetting<boolean>('developer.warn.third_party', false); const waitTime = acceptedWarning ? 0 : 5; const [pluginURL, setPluginURL] = useState(''); - const textRef = useRef<HTMLDivElement>(null); const { t } = useTranslation(); return ( @@ -82,13 +81,6 @@ export default function DeveloperSettings() { </Field> <Field label={t('SettingsDeveloperIndex.third_party_plugins.label_url')} - description={ - <TextField - label={t('SettingsDeveloperIndex.third_party_plugins.label_desc')} - value={pluginURL} - onChange={(e) => setPluginURL(e?.target.value)} - /> - } icon={<FaLink style={{ display: 'block' }} />} > <DialogButton @@ -114,6 +106,11 @@ export default function DeveloperSettings() { {t('SettingsDeveloperIndex.third_party_plugins.button_install')} </DialogButton> </Field> + <TextField + label={t('SettingsDeveloperIndex.third_party_plugins.label_desc')} + value={pluginURL} + onChange={(e) => setPluginURL(e?.target.value)} + /> </DialogControlsSection> <DialogControlsSection> <DialogControlsSectionHeader>{t('SettingsDeveloperIndex.header')}</DialogControlsSectionHeader> @@ -160,18 +157,7 @@ export default function DeveloperSettings() { <Field label={t('SettingsDeveloperIndex.react_devtools.label')} description={ - <> - <span style={{ whiteSpace: 'pre-line' }}>{t('SettingsDeveloperIndex.react_devtools.desc')}</span> - <br /> - <br /> - <div ref={textRef}> - <TextField - label={t('SettingsDeveloperIndex.react_devtools.ip_label')} - value={reactDevtoolsIP} - onChange={(e) => setReactDevtoolsIP(e?.target.value)} - /> - </div> - </> + <span style={{ whiteSpace: 'pre-line' }}>{t('SettingsDeveloperIndex.react_devtools.desc')}</span> } icon={<FaReact style={{ display: 'block' }} />} > @@ -184,6 +170,11 @@ export default function DeveloperSettings() { }} /> </Field> + <TextField + label={t('SettingsDeveloperIndex.react_devtools.ip_label')} + value={reactDevtoolsIP} + onChange={(e) => setReactDevtoolsIP(e?.target.value)} + /> </DialogControlsSection> </DialogBody> ); |
