summaryrefslogtreecommitdiff
path: root/frontend/src/components/settings/pages
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/settings/pages')
-rw-r--r--frontend/src/components/settings/pages/general/Updater.tsx177
1 files changed, 129 insertions, 48 deletions
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 (
+ <Focusable onCancelButton={closeModal}>
+ <Carousel
+ fnItemRenderer={(id: number, ...args: any[]) => {
+ console.log(args, versionInfo);
+ return (
+ <Focusable
+ onActivate={() => {}}
+ style={{
+ marginTop: '40px',
+ height: 'calc( 100% - 40px )',
+ overflowY: 'scroll',
+ display: 'flex',
+ justifyContent: 'center',
+ margin: '40px',
+ }}
+ >
+ <div>
+ <h1>{versionInfo?.all?.[id]?.name}</h1>
+ {versionInfo?.all?.[id]?.body ? (
+ <Suspense fallback={<Spinner style={{ width: '24', height: '24' }} />}>
+ <MarkdownRenderer>{versionInfo.all[id].body}</MarkdownRenderer>
+ </Suspense>
+ ) : (
+ 'no patch notes for this version'
+ )}
+ </div>
+ </Focusable>
+ );
+ }}
+ 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;
+ }}
+ />
+ </Focusable>
+ );
+}
export default function UpdaterSettings() {
const { isLoaderUpdating, setIsLoaderUpdating } = useDeckyState();
@@ -34,56 +91,80 @@ export default function UpdaterSettings() {
};
}, []);
+ const showPatchNotes = useCallback(() => {
+ showModal(<PatchNotesModal versionInfo={versionInfo} />);
+ }, [versionInfo]);
+
return (
- <Field
- label="Updates"
- description={
- versionInfo && (
- <span style={{ whiteSpace: 'pre-line' }}>{`Current version: ${versionInfo.current}\n${
- versionInfo.updatable ? `Latest version: ${versionInfo.remote?.tag_name}` : ''
- }`}</span>
- )
- }
- icon={
- !versionInfo ? (
- <Spinner style={{ width: '1em', height: 20, display: 'block' }} />
+ <>
+ <Field
+ onOptionsActionDescription="Patch Notes"
+ onOptionsButton={showPatchNotes}
+ label="Updates"
+ description={
+ versionInfo && (
+ <span style={{ whiteSpace: 'pre-line' }}>{`Current version: ${versionInfo.current}\n${
+ versionInfo.updatable ? `Latest version: ${versionInfo.remote?.tag_name}` : ''
+ }`}</span>
+ )
+ }
+ icon={
+ !versionInfo ? (
+ <Spinner style={{ width: '1em', height: 20, display: 'block' }} />
+ ) : (
+ <FaArrowDown style={{ display: 'block' }} />
+ )
+ }
+ >
+ {updateProgress == -1 && !isLoaderUpdating ? (
+ <DialogButton
+ disabled={!versionInfo?.updatable || checkingForUpdates}
+ onClick={
+ !versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current
+ ? async () => {
+ 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'}
+ </DialogButton>
) : (
- <FaArrowDown style={{ display: 'block' }} />
- )
- }
- >
- {updateProgress == -1 && !isLoaderUpdating ? (
- <DialogButton
- disabled={!versionInfo?.updatable || checkingForUpdates}
- onClick={
- !versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current
- ? async () => {
- setCheckingForUpdates(true);
- const res = (await callUpdaterMethod('check_for_updates')) as { result: VerInfo };
- setVersionInfo(res.result);
- setCheckingForUpdates(false);
- }
- : async () => {
- setUpdateProgress(0);
- callUpdaterMethod('do_update');
- }
- }
+ <ProgressBarWithInfo
+ layout="inline"
+ bottomSeparator={false}
+ nProgress={updateProgress}
+ indeterminate={reloading}
+ sOperationText={reloading ? 'Reloading' : 'Updating'}
+ />
+ )}
+ </Field>
+ {versionInfo?.remote && (
+ <InlinePatchNotes
+ title={versionInfo?.remote.name}
+ date={new Intl.RelativeTimeFormat('en-US', {
+ numeric: 'auto',
+ }).format(
+ Math.ceil((new Date(versionInfo.remote.published_at).getTime() - new Date().getTime()) / 86400000),
+ 'day',
+ )}
+ onClick={showPatchNotes}
>
- {checkingForUpdates
- ? 'Checking'
- : !versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current
- ? 'Check For Updates'
- : 'Install Update'}
- </DialogButton>
- ) : (
- <ProgressBarWithInfo
- layout="inline"
- bottomSeparator={false}
- nProgress={updateProgress}
- indeterminate={reloading}
- sOperationText={reloading ? 'Reloading' : 'Updating'}
- />
+ <Suspense fallback={<Spinner style={{ width: '24', height: '24' }} />}>
+ <MarkdownRenderer>{versionInfo?.remote.body}</MarkdownRenderer>
+ </Suspense>
+ </InlinePatchNotes>
)}
- </Field>
+ </>
);
}