From 99b4b939bdd2140aecf19ddb09a59b44e9cd117d Mon Sep 17 00:00:00 2001 From: AAGaming Date: Fri, 17 Jun 2022 18:43:53 -0400 Subject: Implement React-based plugin store (#81) Co-authored-by: TrainDoctor <11465594+TrainDoctor@users.noreply.github.com> Co-authored-by: WerWolv --- frontend/src/components/store/PluginCard.tsx | 172 +++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 frontend/src/components/store/PluginCard.tsx (limited to 'frontend/src/components/store/PluginCard.tsx') diff --git a/frontend/src/components/store/PluginCard.tsx b/frontend/src/components/store/PluginCard.tsx new file mode 100644 index 00000000..7816d1bb --- /dev/null +++ b/frontend/src/components/store/PluginCard.tsx @@ -0,0 +1,172 @@ +import { + DialogButton, + Dropdown, + Focusable, + Router, + SingleDropdownOption, + SuspensefulImage, + staticClasses, +} from 'decky-frontend-lib'; +import { FC, useRef, useState } from 'react'; + +import { StorePlugin } from './Store'; + +interface PluginCardProps { + plugin: StorePlugin; +} + +const classNames = (...classes: string[]) => { + return classes.join(' '); +}; + +async function requestPluginInstall(plugin: StorePlugin, selectedVer: string) { + const formData = new FormData(); + formData.append('artifact', plugin.artifact); + formData.append('version', selectedVer); + formData.append('hash', plugin.versions[selectedVer]); + await fetch('http://localhost:1337/browser/install_plugin', { + method: 'POST', + body: formData, + }); +} + +const PluginCard: FC = ({ plugin }) => { + const [selectedOption, setSelectedOption] = useState(0); + const buttonRef = useRef(null); + const containerRef = useRef(null); + return ( +
+ {/* TODO: abstract this messy focus hackiness into a custom component in lib */} + { + buttonRef.current!.focus(); + }} + onCancel={(e: CustomEvent) => { + containerRef.current!.querySelectorAll('* :focus').length === 0 + ? Router.NavigateBackOrOpenMenu() + : containerRef.current!.focus(); + }} + style={{ + display: 'flex', + flexDirection: 'column', + background: '#ACB2C924', + height: 'unset', + marginBottom: 'unset', + // boxShadow: var(--gpShadow-Medium); + scrollSnapAlign: 'start', + boxSizing: 'border-box', + }} + > + +
+ +
+

+ Author: {plugin.author} +

+

+ Tags: + {plugin.tags.map((tag: string) => ( + + {tag == 'root' ? 'Requires root' : tag} + + ))} +

+
+
+
+ +
+ requestPluginInstall(plugin, Object.keys(plugin.versions)[selectedOption])} + > + Install + +
+
+ ({ + data: k, + label: v, + })) as SingleDropdownOption[] + } + strDefaultLabel={'Select a version'} + selectedOption={selectedOption} + onChange={({ data }) => setSelectedOption(data)} + /> +
+
+
+
+
+ ); +}; + +export default PluginCard; -- cgit v1.2.3