diff options
| author | Jonas Dellinger <jonas@dellinger.dev> | 2022-05-26 13:30:14 +0200 |
|---|---|---|
| committer | Jonas Dellinger <jonas@dellinger.dev> | 2022-05-26 13:30:14 +0200 |
| commit | 71dd0ea449469ed38e784b9c73b673eece680446 (patch) | |
| tree | 15914a2b7979296b8c04cac0e75191eb9f955919 /frontend/src/components | |
| parent | a06efc08bc01a4a014d916ff1e219a0f17d0c480 (diff) | |
| parent | 4b923c1dc70eaa4a3ca58d9e9f3218785b2fe919 (diff) | |
| download | decky-loader-71dd0ea449469ed38e784b9c73b673eece680446.tar.gz decky-loader-71dd0ea449469ed38e784b9c73b673eece680446.zip | |
Cleanup after merge
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/DeckyState.tsx | 74 | ||||
| -rw-r--r-- | frontend/src/components/LegacyPlugin.tsx | 21 | ||||
| -rw-r--r-- | frontend/src/components/PluginView.tsx | 39 | ||||
| -rw-r--r-- | frontend/src/components/TitleView.tsx | 20 |
4 files changed, 154 insertions, 0 deletions
diff --git a/frontend/src/components/DeckyState.tsx b/frontend/src/components/DeckyState.tsx new file mode 100644 index 00000000..cbeeb5b4 --- /dev/null +++ b/frontend/src/components/DeckyState.tsx @@ -0,0 +1,74 @@ +import { FC, createContext, useContext, useEffect, useState } from 'react'; + +import { Plugin } from '../plugin'; + +interface PublicDeckyState { + plugins: Plugin[]; + activePlugin: Plugin | null; +} + +export class DeckyState { + private _plugins: Plugin[] = []; + private _activePlugin: Plugin | null = null; + + public eventBus = new EventTarget(); + + publicState(): PublicDeckyState { + return { plugins: this._plugins, activePlugin: this._activePlugin }; + } + + setPlugins(plugins: Plugin[]) { + this._plugins = plugins; + this.notifyUpdate(); + } + + setActivePlugin(name: string) { + this._activePlugin = this._plugins.find((plugin) => plugin.name === name) ?? null; + this.notifyUpdate(); + } + + closeActivePlugin() { + this._activePlugin = null; + this.notifyUpdate(); + } + + private notifyUpdate() { + this.eventBus.dispatchEvent(new Event('update')); + } +} + +interface DeckyStateContext extends PublicDeckyState { + setActivePlugin(name: string): void; + closeActivePlugin(): void; +} + +const DeckyStateContext = createContext<DeckyStateContext>(null as any); + +export const useDeckyState = () => useContext(DeckyStateContext); + +interface Props { + deckyState: DeckyState; +} + +export const DeckyStateContextProvider: FC<Props> = ({ children, deckyState }) => { + const [publicDeckyState, setPublicDeckyState] = useState<PublicDeckyState>({ ...deckyState.publicState() }); + + useEffect(() => { + function onUpdate() { + setPublicDeckyState({ ...deckyState.publicState() }); + } + + deckyState.eventBus.addEventListener('update', onUpdate); + + return () => deckyState.eventBus.removeEventListener('update', onUpdate); + }, []); + + const setActivePlugin = (name: string) => deckyState.setActivePlugin(name); + const closeActivePlugin = () => deckyState.closeActivePlugin(); + + return ( + <DeckyStateContext.Provider value={{ ...publicDeckyState, setActivePlugin, closeActivePlugin }}> + {children} + </DeckyStateContext.Provider> + ); +}; diff --git a/frontend/src/components/LegacyPlugin.tsx b/frontend/src/components/LegacyPlugin.tsx new file mode 100644 index 00000000..40f9e85f --- /dev/null +++ b/frontend/src/components/LegacyPlugin.tsx @@ -0,0 +1,21 @@ +import { VFC } from 'react'; + +// class LegacyPlugin extends React.Component { +// constructor(props: object) { +// super(props); +// } + +// render() { +// return <iframe style={{ border: 'none', width: '100%', height: '100%' }} src={this.props.url}></iframe> +// } +// } + +interface Props { + url: string; +} + +const LegacyPlugin: VFC<Props> = () => { + return <div>LegacyPlugin Hello World</div>; +}; + +export default LegacyPlugin; diff --git a/frontend/src/components/PluginView.tsx b/frontend/src/components/PluginView.tsx new file mode 100644 index 00000000..b3640395 --- /dev/null +++ b/frontend/src/components/PluginView.tsx @@ -0,0 +1,39 @@ +import { ButtonItem, DialogButton, PanelSection, PanelSectionRow } from 'decky-frontend-lib'; +import { VFC } from 'react'; +import { FaArrowLeft } from 'react-icons/fa'; + +import { useDeckyState } from './DeckyState'; + +const PluginView: VFC = () => { + const { plugins, activePlugin, setActivePlugin, closeActivePlugin } = useDeckyState(); + + if (activePlugin) { + return ( + <div> + <div style={{ position: 'absolute', top: '3px', left: '16px', zIndex: 20 }}> + <DialogButton style={{ minWidth: 0, padding: '10px 12px' }} onClick={closeActivePlugin}> + <FaArrowLeft style={{ display: 'block' }} /> + </DialogButton> + </div> + {activePlugin.content} + </div> + ); + } + + return ( + <PanelSection> + {plugins.map(({ name, icon }) => ( + <PanelSectionRow key={name}> + <ButtonItem layout="below" onClick={() => setActivePlugin(name)}> + <div style={{ display: 'flex', justifyContent: 'space-between' }}> + <div>{icon}</div> + <div>{name}</div> + </div> + </ButtonItem> + </PanelSectionRow> + ))} + </PanelSection> + ); +}; + +export default PluginView; diff --git a/frontend/src/components/TitleView.tsx b/frontend/src/components/TitleView.tsx new file mode 100644 index 00000000..4b4a6825 --- /dev/null +++ b/frontend/src/components/TitleView.tsx @@ -0,0 +1,20 @@ +import { staticClasses } from 'decky-frontend-lib'; +import { VFC } from 'react'; + +import { useDeckyState } from './DeckyState'; + +const TitleView: VFC = () => { + const { activePlugin } = useDeckyState(); + + if (activePlugin === null) { + return <div className={staticClasses.Title}>Decky</div>; + } + + return ( + <div className={staticClasses.Title} style={{ paddingLeft: '60px' }}> + {activePlugin.name} + </div> + ); +}; + +export default TitleView; |
