From d4d1c2bbabfcec3c62767e614c9d67f516938af2 Mon Sep 17 00:00:00 2001 From: AAGaming Date: Fri, 26 Aug 2022 01:18:28 -0400 Subject: basic patch notes viewer, lazy-load settings and store, build frontend as esmodule, add lazy-loaded react-markdown, backend changes to accomodate ESModule frontend --- frontend/src/components/Markdown.tsx | 9 ++ .../src/components/patchnotes/InlinePatchNotes.tsx | 21 +++ .../components/settings/pages/general/Updater.tsx | 177 +++++++++++++++------ frontend/src/plugin-loader.tsx | 42 ++++- frontend/src/updater.ts | 25 +-- 5 files changed, 210 insertions(+), 64 deletions(-) create mode 100644 frontend/src/components/Markdown.tsx create mode 100644 frontend/src/components/patchnotes/InlinePatchNotes.tsx (limited to 'frontend/src') diff --git a/frontend/src/components/Markdown.tsx b/frontend/src/components/Markdown.tsx new file mode 100644 index 00000000..7b187f14 --- /dev/null +++ b/frontend/src/components/Markdown.tsx @@ -0,0 +1,9 @@ +import { FunctionComponent } from 'react'; +import ReactMarkdown, { Options as ReactMarkdownOptions } from 'react-markdown'; +import remarkGfm from 'remark-gfm'; + +const Markdown: FunctionComponent = (props) => { + return ; +}; + +export default Markdown; diff --git a/frontend/src/components/patchnotes/InlinePatchNotes.tsx b/frontend/src/components/patchnotes/InlinePatchNotes.tsx new file mode 100644 index 00000000..84861c04 --- /dev/null +++ b/frontend/src/components/patchnotes/InlinePatchNotes.tsx @@ -0,0 +1,21 @@ +import { Focusable, updaterFieldClasses } from 'decky-frontend-lib'; +import { FunctionComponent, ReactNode } from 'react'; + +interface InlinePatchNotesProps { + date: ReactNode; + title: string; + children: ReactNode; + onClick?: () => void; +} + +const InlinePatchNotes: FunctionComponent = ({ date, title, children, onClick }) => { + return ( + +
{date}
+
{title}
+
{children}
+
+ ); +}; + +export default InlinePatchNotes; diff --git a/frontend/src/components/settings/pages/general/Updater.tsx b/frontend/src/components/settings/pages/general/Updater.tsx index f7e4a29d..cb58b24c 100644 --- a/frontend/src/components/settings/pages/general/Updater.tsx +++ b/frontend/src/components/settings/pages/general/Updater.tsx @@ -1,9 +1,66 @@ -import { DialogButton, Field, ProgressBarWithInfo, Spinner } from 'decky-frontend-lib'; +import { Carousel, DialogButton, Field, Focusable, ProgressBarWithInfo, Spinner, showModal } from 'decky-frontend-lib'; +import { useCallback } from 'react'; +import { Suspense, lazy } from 'react'; import { useEffect, useState } from 'react'; import { FaArrowDown } from 'react-icons/fa'; import { VerInfo, callUpdaterMethod, finishUpdate } from '../../../../updater'; import { useDeckyState } from '../../../DeckyState'; +import InlinePatchNotes from '../../../patchnotes/InlinePatchNotes'; + +const MarkdownRenderer = lazy(() => import('../../../Markdown')); + +// import ReactMarkdown from 'react-markdown' +// import remarkGfm from 'remark-gfm' + +function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | null; closeModal?: () => {} }) { + return ( + + { + console.log(args, versionInfo); + return ( + {}} + style={{ + marginTop: '40px', + height: 'calc( 100% - 40px )', + overflowY: 'scroll', + display: 'flex', + justifyContent: 'center', + margin: '40px', + }} + > +
+

{versionInfo?.all?.[id]?.name}

+ {versionInfo?.all?.[id]?.body ? ( + }> + {versionInfo.all[id].body} + + ) : ( + 'no patch notes for this version' + )} +
+
+ ); + }} + fnGetId={(id) => { + return id; + }} + nNumItems={versionInfo?.all?.length} + nHeight={window.innerHeight - 150} + nItemHeight={window.innerHeight - 200} + nItemMarginX={0} + initialColumn={0} + autoFocus={true} + fnGetColumnWidth={(...args: any[]) => { + console.log('cw', args); + return window.innerWidth; + }} + /> +
+ ); +} export default function UpdaterSettings() { const { isLoaderUpdating, setIsLoaderUpdating } = useDeckyState(); @@ -34,56 +91,80 @@ export default function UpdaterSettings() { }; }, []); + const showPatchNotes = useCallback(() => { + showModal(); + }, [versionInfo]); + return ( - {`Current version: ${versionInfo.current}\n${ - versionInfo.updatable ? `Latest version: ${versionInfo.remote?.tag_name}` : '' - }`} - ) - } - icon={ - !versionInfo ? ( - + <> + {`Current version: ${versionInfo.current}\n${ + versionInfo.updatable ? `Latest version: ${versionInfo.remote?.tag_name}` : '' + }`} + ) + } + icon={ + !versionInfo ? ( + + ) : ( + + ) + } + > + {updateProgress == -1 && !isLoaderUpdating ? ( + { + setCheckingForUpdates(true); + const res = (await callUpdaterMethod('check_for_updates')) as { result: VerInfo }; + setVersionInfo(res.result); + setCheckingForUpdates(false); + } + : async () => { + setUpdateProgress(0); + callUpdaterMethod('do_update'); + } + } + > + {checkingForUpdates + ? 'Checking' + : !versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current + ? 'Check For Updates' + : 'Install Update'} + ) : ( - - ) - } - > - {updateProgress == -1 && !isLoaderUpdating ? ( - { - setCheckingForUpdates(true); - const res = (await callUpdaterMethod('check_for_updates')) as { result: VerInfo }; - setVersionInfo(res.result); - setCheckingForUpdates(false); - } - : async () => { - setUpdateProgress(0); - callUpdaterMethod('do_update'); - } - } + + )} + + {versionInfo?.remote && ( + - {checkingForUpdates - ? 'Checking' - : !versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current - ? 'Check For Updates' - : 'Install Update'} - - ) : ( - + }> + {versionInfo?.remote.body} + + )} - + ); } diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx index c0fc3d00..661a2f67 100644 --- a/frontend/src/plugin-loader.tsx +++ b/frontend/src/plugin-loader.tsx @@ -1,4 +1,5 @@ -import { ModalRoot, QuickAccessTab, Router, showModal, sleep, staticClasses } from 'decky-frontend-lib'; +import { ModalRoot, QuickAccessTab, Router, SteamSpinner, showModal, sleep, staticClasses } from 'decky-frontend-lib'; +import { Suspense, lazy } from 'react'; import { FaPlug } from 'react-icons/fa'; import { DeckyState, DeckyStateContextProvider, useDeckyState } from './components/DeckyState'; @@ -6,8 +7,6 @@ import LegacyPlugin from './components/LegacyPlugin'; import PluginInstallModal from './components/modals/PluginInstallModal'; import NotificationBadge from './components/NotificationBadge'; import PluginView from './components/PluginView'; -import SettingsPage from './components/settings'; -import StorePage from './components/store/Store'; import TitleView from './components/TitleView'; import Logger from './logger'; import { Plugin } from './plugin'; @@ -61,11 +60,44 @@ class PluginLoader extends Logger { ), }); - this.routerHook.addRoute('/decky/store', () => ); + const StorePage = lazy(() => import('./components/store/Store')); + const SettingsPage = lazy(() => import('./components/settings')); + + this.routerHook.addRoute('/decky/store', () => ( + + + + } + > + + + )); this.routerHook.addRoute('/decky/settings', () => { return ( - + + + + } + > + + ); }); diff --git a/frontend/src/updater.ts b/frontend/src/updater.ts index dd37f0b4..ff9cb591 100644 --- a/frontend/src/updater.ts +++ b/frontend/src/updater.ts @@ -11,19 +11,22 @@ export interface DeckyUpdater { finish: () => void; } +export interface RemoteVerInfo { + assets: { + browser_download_url: string; + created_at: string; + }[]; + name: string; + body: string; + prerelease: boolean; + published_at: string; + tag_name: string; +} + export interface VerInfo { current: string; - remote: { - assets: { - browser_download_url: string; - created_at: string; - }[]; - name: string; - body: string; - prerelease: boolean; - published_at: string; - tag_name: string; - } | null; + remote: RemoteVerInfo | null; + all: RemoteVerInfo[] | null; updatable: boolean; } -- cgit v1.2.3