fix updater for new installs, fix file picker patch, fix scrolling on patch notes, fix tasks dir

This commit is contained in:
AAGaming
2022-09-17 23:23:51 -04:00
parent fded2fa8bf
commit c4d6731401
8 changed files with 113 additions and 44 deletions
+1 -1
View File
@@ -107,7 +107,7 @@
"type": "shell", "type": "shell",
"group": "none", "group": "none",
"dependsOn" : ["checkforsettings"], "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": [] "problemMatcher": []
}, },
{ {
+18 -9
View File
@@ -29,18 +29,18 @@ class Updater:
self.remoteVer = None self.remoteVer = None
self.allRemoteVers = None self.allRemoteVers = None
try: try:
self.currentBranch = self.get_branch(self.context.settings) logger.info(getcwd())
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:
with open(path.join(getcwd(), ".loader.version"), 'r') as version_file: with open(path.join(getcwd(), ".loader.version"), 'r') as version_file:
self.localVer = version_file.readline().replace("\n", "") self.localVer = version_file.readline().replace("\n", "")
except: except:
self.localVer = False 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: if context:
context.web_app.add_routes([ context.web_app.add_routes([
web.post("/updater/{method_name}", self._handle_server_method_call) web.post("/updater/{method_name}", self._handle_server_method_call)
@@ -64,8 +64,17 @@ class Updater:
return web.json_response(res) return web.json_response(res)
def get_branch(self, manager: SettingsManager): def get_branch(self, manager: SettingsManager):
logger.debug("current branch: %i" % manager.getSetting("branch", 0)) ver = manager.getSetting("branch", -1)
return manager.getSetting("branch", 0) 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): async def _get_branch(self, manager: SettingsManager):
return self.get_branch(manager) return self.get_branch(manager)
+36 -3
View File
@@ -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 ReactMarkdown, { Options as ReactMarkdownOptions } from 'react-markdown';
import remarkGfm from 'remark-gfm'; import remarkGfm from 'remark-gfm';
const Markdown: FunctionComponent<ReactMarkdownOptions> = (props) => { interface MarkdownProps extends ReactMarkdownOptions {
return <ReactMarkdown remarkPlugins={[remarkGfm]} {...props} />; 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; export default Markdown;
+10 -4
View File
@@ -1,8 +1,9 @@
import { SteamSpinner } from 'decky-frontend-lib'; import { Focusable, SteamSpinner } from 'decky-frontend-lib';
import { FunctionComponent, ReactElement, ReactNode, Suspense } from 'react'; import { FunctionComponent, ReactElement, ReactNode, Suspense } from 'react';
interface WithSuspenseProps { interface WithSuspenseProps {
children: ReactNode; children: ReactNode;
route?: boolean;
} }
// Nice little wrapper around Suspense so we don't have to duplicate the styles and code for the loading spinner // 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 ( return (
<Suspense <Suspense
fallback={ fallback={
<div <Focusable
// needed to enable focus ring so that the focus properly resets on load
onActivate={() => {}}
style={{ style={{
overflowY: 'scroll',
backgroundColor: 'transparent',
...(props.route && {
marginTop: '40px', marginTop: '40px',
height: 'calc( 100% - 40px )', height: 'calc( 100% - 40px )',
overflowY: 'scroll', }),
}} }}
> >
<SteamSpinner /> <SteamSpinner />
</div> </Focusable>
} }
> >
{props.children} {props.children}
@@ -86,7 +86,8 @@ const FilePicker: FunctionComponent<FilePickerProps> = ({
onClick={() => { onClick={() => {
const newPathArr = path.split('/'); const newPathArr = path.split('/');
newPathArr.pop(); newPathArr.pop();
const newPath = newPathArr.join('/'); let newPath = newPathArr.join('/');
if (newPath == '') newPath = '/';
setPath(newPath); setPath(newPath);
}} }}
> >
@@ -113,7 +114,7 @@ const FilePicker: FunctionComponent<FilePickerProps> = ({
<DialogButton <DialogButton
style={{ borderRadius: 'unset', margin: '0', padding: '10px' }} style={{ borderRadius: 'unset', margin: '0', padding: '10px' }}
onClick={() => { onClick={() => {
const fullPath = `${path}/${file.name}`; const fullPath = `${path}${path.endsWith('/') ? '' : '/'}${file.name}`;
if (file.isdir) setPath(fullPath); if (file.isdir) setPath(fullPath);
else { else {
onSubmit({ path: fullPath, realpath: file.realpath }); onSubmit({ path: fullPath, realpath: file.realpath });
@@ -1,4 +1,4 @@
import { Patch, replacePatch, sleep } from 'decky-frontend-lib'; import { Patch, findModuleChild, replacePatch } from 'decky-frontend-lib';
declare global { declare global {
interface Window { interface Window {
@@ -10,8 +10,7 @@ declare global {
let patch: Patch; let patch: Patch;
function rePatch() { 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 // 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?.unpatch();
patch = replacePatch(window.SteamClient.Apps, 'PromptToChangeShortcut', async ([appid]: number[]) => { patch = replacePatch(window.SteamClient.Apps, 'PromptToChangeShortcut', async ([appid]: number[]) => {
try { try {
const details = window.appDetailsStore.GetAppDetails(appid); 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() { export default async function libraryPatch() {
await sleep(10000); try {
rePatch(); rePatch();
await sleep(10000); const unlisten = History.listen(() => {
if (window.SteamClient.Apps.PromptToChangeShortcut !== patch.patchedFunction) {
rePatch(); rePatch();
}
});
return () => { return () => {
patch.unpatch(); patch.unpatch();
unlisten();
}; };
} catch (e) {
console.error('Error patching library file picker', e);
}
return () => {};
} }
@@ -7,19 +7,16 @@ import { FaArrowDown } from 'react-icons/fa';
import { VerInfo, callUpdaterMethod, finishUpdate } from '../../../../updater'; import { VerInfo, callUpdaterMethod, finishUpdate } from '../../../../updater';
import { useDeckyState } from '../../../DeckyState'; import { useDeckyState } from '../../../DeckyState';
import InlinePatchNotes from '../../../patchnotes/InlinePatchNotes'; import InlinePatchNotes from '../../../patchnotes/InlinePatchNotes';
import WithSuspense from '../../../WithSuspense';
const MarkdownRenderer = lazy(() => import('../../../Markdown')); const MarkdownRenderer = lazy(() => import('../../../Markdown'));
// import ReactMarkdown from 'react-markdown'
// import remarkGfm from 'remark-gfm'
function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | null; closeModal?: () => {} }) { function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | null; closeModal?: () => {} }) {
return ( return (
<Focusable onCancelButton={closeModal}> <Focusable onCancelButton={closeModal}>
<Carousel <Carousel
fnItemRenderer={(id: number) => ( fnItemRenderer={(id: number) => (
<Focusable <Focusable
onActivate={() => {}}
style={{ style={{
marginTop: '40px', marginTop: '40px',
height: 'calc( 100% - 40px )', height: 'calc( 100% - 40px )',
@@ -32,9 +29,9 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
<div> <div>
<h1>{versionInfo?.all?.[id]?.name}</h1> <h1>{versionInfo?.all?.[id]?.name}</h1>
{versionInfo?.all?.[id]?.body ? ( {versionInfo?.all?.[id]?.body ? (
<Suspense fallback={<Spinner style={{ width: '24', height: '24' }} />}> <WithSuspense>
<MarkdownRenderer>{versionInfo.all[id].body}</MarkdownRenderer> <MarkdownRenderer onDismiss={closeModal}>{versionInfo.all[id].body}</MarkdownRenderer>
</Suspense> </WithSuspense>
) : ( ) : (
'no patch notes for this version' 'no patch notes for this version'
)} )}
@@ -43,8 +40,8 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
)} )}
fnGetId={(id) => id} fnGetId={(id) => id}
nNumItems={versionInfo?.all?.length} nNumItems={versionInfo?.all?.length}
nHeight={window.innerHeight - 150} nHeight={window.innerHeight - 40}
nItemHeight={window.innerHeight - 200} nItemHeight={window.innerHeight - 40}
nItemMarginX={0} nItemMarginX={0}
initialColumn={0} initialColumn={0}
autoFocus={true} autoFocus={true}
+12 -4
View File
@@ -66,14 +66,14 @@ class PluginLoader extends Logger {
}); });
this.routerHook.addRoute('/decky/store', () => ( this.routerHook.addRoute('/decky/store', () => (
<WithSuspense> <WithSuspense route={true}>
<StorePage /> <StorePage />
</WithSuspense> </WithSuspense>
)); ));
this.routerHook.addRoute('/decky/settings', () => { this.routerHook.addRoute('/decky/settings', () => {
return ( return (
<DeckyStateContextProvider deckyState={this.deckyState}> <DeckyStateContextProvider deckyState={this.deckyState}>
<WithSuspense> <WithSuspense route={true}>
<SettingsPage /> <SettingsPage />
</WithSuspense> </WithSuspense>
</DeckyStateContextProvider> </DeckyStateContextProvider>
@@ -81,11 +81,19 @@ class PluginLoader extends Logger {
}); });
initFilepickerPatches(); initFilepickerPatches();
this.updateVersion();
}
public async updateVersion() {
const versionInfo = (await callUpdaterMethod('get_version')).result as VerInfo;
this.deckyState.setVersionInfo(versionInfo);
return versionInfo;
} }
public async notifyUpdates() { public async notifyUpdates() {
const versionInfo = (await callUpdaterMethod('get_version')).result as VerInfo; const versionInfo = await this.updateVersion();
this.deckyState.setVersionInfo(versionInfo);
if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) { if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) {
this.toaster.toast({ this.toaster.toast({
title: 'Decky', title: 'Decky',