summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAAGaming <aa@mail.catvibers.me>2022-09-17 23:23:51 -0400
committerAAGaming <aa@mail.catvibers.me>2022-09-17 23:23:51 -0400
commitc4d6731401d3b6dc111a74d086df28704473070d (patch)
treeb8a1cff3ae32eac720300fd03093f9890ddf82cb
parentfded2fa8bfc52ae29848a343483c68f6955feb0c (diff)
downloaddecky-loader-c4d6731401d3b6dc111a74d086df28704473070d.tar.gz
decky-loader-c4d6731401d3b6dc111a74d086df28704473070d.zip
fix updater for new installs, fix file picker patch, fix scrolling on patch notes, fix tasks dir
-rw-r--r--.vscode/tasks.json2
-rw-r--r--backend/updater.py27
-rw-r--r--frontend/src/components/Markdown.tsx39
-rw-r--r--frontend/src/components/WithSuspense.tsx16
-rw-r--r--frontend/src/components/modals/filepicker/index.tsx5
-rw-r--r--frontend/src/components/modals/filepicker/patches/library.ts35
-rw-r--r--frontend/src/components/settings/pages/general/Updater.tsx15
-rw-r--r--frontend/src/plugin-loader.tsx14
8 files changed, 111 insertions, 42 deletions
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 9377a7e8..16c76c91 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -107,7 +107,7 @@
"type": "shell",
"group": "none",
"dependsOn" : ["checkforsettings"],
- "command": "ssh deck@${config:deckip} -p ${config:deckport} ${config:deckkey} 'export PLUGIN_PATH=${config:deckdir}/homebrew/dev/plugins; export CHOWN_PLUGIN_PATH=0; echo '${config:deckpass}' | sudo -SE python3 ${config:deckdir}/homebrew/dev/pluginloader/backend/main.py'",
+ "command": "ssh deck@${config:deckip} -p ${config:deckport} ${config:deckkey} 'export PLUGIN_PATH=${config:deckdir}/homebrew/dev/plugins; export CHOWN_PLUGIN_PATH=0; cd ${config:deckdir}/homebrew/services; echo '${config:deckpass}' | sudo -SE python3 ${config:deckdir}/homebrew/dev/pluginloader/backend/main.py'",
"problemMatcher": []
},
{
diff --git a/backend/updater.py b/backend/updater.py
index 088b3b30..402c152b 100644
--- a/backend/updater.py
+++ b/backend/updater.py
@@ -29,18 +29,18 @@ class Updater:
self.remoteVer = None
self.allRemoteVers = None
try:
- self.currentBranch = self.get_branch(self.context.settings)
- if int(self.currentBranch) == -1:
- raise ValueError("get_branch could not determine branch!")
- except:
- self.currentBranch = 0
- logger.error("Current branch could not be determined, defaulting to \"Stable\"")
- try:
+ logger.info(getcwd())
with open(path.join(getcwd(), ".loader.version"), 'r') as version_file:
self.localVer = version_file.readline().replace("\n", "")
except:
self.localVer = False
+ try:
+ self.currentBranch = self.get_branch(self.context.settings)
+ except:
+ self.currentBranch = 0
+ logger.error("Current branch could not be determined, defaulting to \"Stable\"")
+
if context:
context.web_app.add_routes([
web.post("/updater/{method_name}", self._handle_server_method_call)
@@ -64,8 +64,17 @@ class Updater:
return web.json_response(res)
def get_branch(self, manager: SettingsManager):
- logger.debug("current branch: %i" % manager.getSetting("branch", 0))
- return manager.getSetting("branch", 0)
+ ver = manager.getSetting("branch", -1)
+ logger.debug("current branch: %i" % ver)
+ if ver == -1:
+ logger.info("Current branch is not set, determining branch from version...")
+ if self.localVer.startswith("v") and self.localVer.find("-pre"):
+ logger.info("Current version determined to be pre-release")
+ return 1
+ else:
+ logger.info("Current version determined to be stable")
+ return 0
+ return ver
async def _get_branch(self, manager: SettingsManager):
return self.get_branch(manager)
diff --git a/frontend/src/components/Markdown.tsx b/frontend/src/components/Markdown.tsx
index 7b187f14..cefced91 100644
--- a/frontend/src/components/Markdown.tsx
+++ b/frontend/src/components/Markdown.tsx
@@ -1,9 +1,42 @@
-import { FunctionComponent } from 'react';
+import { Focusable } from 'decky-frontend-lib';
+import { FunctionComponent, useRef } from 'react';
import ReactMarkdown, { Options as ReactMarkdownOptions } from 'react-markdown';
import remarkGfm from 'remark-gfm';
-const Markdown: FunctionComponent<ReactMarkdownOptions> = (props) => {
- return <ReactMarkdown remarkPlugins={[remarkGfm]} {...props} />;
+interface MarkdownProps extends ReactMarkdownOptions {
+ onDismiss?: () => void;
+}
+
+const Markdown: FunctionComponent<MarkdownProps> = (props) => {
+ return (
+ <Focusable>
+ <ReactMarkdown
+ remarkPlugins={[remarkGfm]}
+ components={{
+ div: (nodeProps) => <Focusable {...nodeProps.node.properties}>{nodeProps.children}</Focusable>,
+ a: (nodeProps) => {
+ console.log(nodeProps.node, nodeProps);
+ const aRef = useRef<HTMLAnchorElement>(null);
+ return (
+ // TODO fix focus ring
+ <Focusable
+ onActivate={() => {}}
+ onOKButton={() => {
+ aRef?.current?.click();
+ props.onDismiss?.();
+ }}
+ >
+ <a ref={aRef} {...nodeProps.node.properties}>
+ {nodeProps.children}
+ </a>
+ </Focusable>
+ );
+ },
+ }}
+ {...props}
+ />
+ </Focusable>
+ );
};
export default Markdown;
diff --git a/frontend/src/components/WithSuspense.tsx b/frontend/src/components/WithSuspense.tsx
index 7460aa3d..402f5e5b 100644
--- a/frontend/src/components/WithSuspense.tsx
+++ b/frontend/src/components/WithSuspense.tsx
@@ -1,8 +1,9 @@
-import { SteamSpinner } from 'decky-frontend-lib';
+import { Focusable, SteamSpinner } from 'decky-frontend-lib';
import { FunctionComponent, ReactElement, ReactNode, Suspense } from 'react';
interface WithSuspenseProps {
children: ReactNode;
+ route?: boolean;
}
// Nice little wrapper around Suspense so we don't have to duplicate the styles and code for the loading spinner
@@ -13,15 +14,20 @@ const WithSuspense: FunctionComponent<WithSuspenseProps> = (props) => {
return (
<Suspense
fallback={
- <div
+ <Focusable
+ // needed to enable focus ring so that the focus properly resets on load
+ onActivate={() => {}}
style={{
- marginTop: '40px',
- height: 'calc( 100% - 40px )',
overflowY: 'scroll',
+ backgroundColor: 'transparent',
+ ...(props.route && {
+ marginTop: '40px',
+ height: 'calc( 100% - 40px )',
+ }),
}}
>
<SteamSpinner />
- </div>
+ </Focusable>
}
>
{props.children}
diff --git a/frontend/src/components/modals/filepicker/index.tsx b/frontend/src/components/modals/filepicker/index.tsx
index 0847bd14..dcf179a3 100644
--- a/frontend/src/components/modals/filepicker/index.tsx
+++ b/frontend/src/components/modals/filepicker/index.tsx
@@ -86,7 +86,8 @@ const FilePicker: FunctionComponent<FilePickerProps> = ({
onClick={() => {
const newPathArr = path.split('/');
newPathArr.pop();
- const newPath = newPathArr.join('/');
+ let newPath = newPathArr.join('/');
+ if (newPath == '') newPath = '/';
setPath(newPath);
}}
>
@@ -113,7 +114,7 @@ const FilePicker: FunctionComponent<FilePickerProps> = ({
<DialogButton
style={{ borderRadius: 'unset', margin: '0', padding: '10px' }}
onClick={() => {
- const fullPath = `${path}/${file.name}`;
+ const fullPath = `${path}${path.endsWith('/') ? '' : '/'}${file.name}`;
if (file.isdir) setPath(fullPath);
else {
onSubmit({ path: fullPath, realpath: file.realpath });
diff --git a/frontend/src/components/modals/filepicker/patches/library.ts b/frontend/src/components/modals/filepicker/patches/library.ts
index 7ba977a5..c9c7d53c 100644
--- a/frontend/src/components/modals/filepicker/patches/library.ts
+++ b/frontend/src/components/modals/filepicker/patches/library.ts
@@ -1,4 +1,4 @@
-import { Patch, replacePatch, sleep } from 'decky-frontend-lib';
+import { Patch, findModuleChild, replacePatch } from 'decky-frontend-lib';
declare global {
interface Window {
@@ -10,8 +10,7 @@ declare global {
let patch: Patch;
function rePatch() {
- // If you patch anything on SteamClient within the first few seconds of the client having loaded it will get redefined for some reason, so repatch any of these changes that occur within the first minute of the client loading
- patch?.unpatch();
+ // If you patch anything on SteamClient within the first few seconds of the client having loaded it will get redefined for some reason, so repatch any of these changes that occur within the first 20s of the last patch
patch = replacePatch(window.SteamClient.Apps, 'PromptToChangeShortcut', async ([appid]: number[]) => {
try {
const details = window.appDetailsStore.GetAppDetails(appid);
@@ -30,13 +29,29 @@ function rePatch() {
});
}
+// TODO type and add to frontend-lib
+const History = findModuleChild((m) => {
+ if (typeof m !== 'object') return undefined;
+ for (let prop in m) {
+ if (m[prop]?.m_history) return m[prop].m_history;
+ }
+});
+
export default async function libraryPatch() {
- await sleep(10000);
- rePatch();
- await sleep(10000);
- rePatch();
+ try {
+ rePatch();
+ const unlisten = History.listen(() => {
+ if (window.SteamClient.Apps.PromptToChangeShortcut !== patch.patchedFunction) {
+ rePatch();
+ }
+ });
- return () => {
- patch.unpatch();
- };
+ return () => {
+ patch.unpatch();
+ unlisten();
+ };
+ } catch (e) {
+ console.error('Error patching library file picker', e);
+ }
+ return () => {};
}
diff --git a/frontend/src/components/settings/pages/general/Updater.tsx b/frontend/src/components/settings/pages/general/Updater.tsx
index 7056ed13..ce859de7 100644
--- a/frontend/src/components/settings/pages/general/Updater.tsx
+++ b/frontend/src/components/settings/pages/general/Updater.tsx
@@ -7,19 +7,16 @@ import { FaArrowDown } from 'react-icons/fa';
import { VerInfo, callUpdaterMethod, finishUpdate } from '../../../../updater';
import { useDeckyState } from '../../../DeckyState';
import InlinePatchNotes from '../../../patchnotes/InlinePatchNotes';
+import WithSuspense from '../../../WithSuspense';
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) => (
<Focusable
- onActivate={() => {}}
style={{
marginTop: '40px',
height: 'calc( 100% - 40px )',
@@ -32,9 +29,9 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
<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>
+ <WithSuspense>
+ <MarkdownRenderer onDismiss={closeModal}>{versionInfo.all[id].body}</MarkdownRenderer>
+ </WithSuspense>
) : (
'no patch notes for this version'
)}
@@ -43,8 +40,8 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
)}
fnGetId={(id) => id}
nNumItems={versionInfo?.all?.length}
- nHeight={window.innerHeight - 150}
- nItemHeight={window.innerHeight - 200}
+ nHeight={window.innerHeight - 40}
+ nItemHeight={window.innerHeight - 40}
nItemMarginX={0}
initialColumn={0}
autoFocus={true}
diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx
index 493e5935..a17969a7 100644
--- a/frontend/src/plugin-loader.tsx
+++ b/frontend/src/plugin-loader.tsx
@@ -66,14 +66,14 @@ class PluginLoader extends Logger {
});
this.routerHook.addRoute('/decky/store', () => (
- <WithSuspense>
+ <WithSuspense route={true}>
<StorePage />
</WithSuspense>
));
this.routerHook.addRoute('/decky/settings', () => {
return (
<DeckyStateContextProvider deckyState={this.deckyState}>
- <WithSuspense>
+ <WithSuspense route={true}>
<SettingsPage />
</WithSuspense>
</DeckyStateContextProvider>
@@ -81,11 +81,19 @@ class PluginLoader extends Logger {
});
initFilepickerPatches();
+
+ this.updateVersion();
}
- public async notifyUpdates() {
+ public async updateVersion() {
const versionInfo = (await callUpdaterMethod('get_version')).result as VerInfo;
this.deckyState.setVersionInfo(versionInfo);
+
+ return versionInfo;
+ }
+
+ public async notifyUpdates() {
+ const versionInfo = await this.updateVersion();
if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) {
this.toaster.toast({
title: 'Decky',