diff options
Diffstat (limited to 'frontend/src/toaster.tsx')
| -rw-r--r-- | frontend/src/toaster.tsx | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/frontend/src/toaster.tsx b/frontend/src/toaster.tsx index f42eb3f5..8eea35bc 100644 --- a/frontend/src/toaster.tsx +++ b/frontend/src/toaster.tsx @@ -1,4 +1,5 @@ import { Patch, ToastData, afterPatch, findInReactTree, findModuleChild, sleep } from 'decky-frontend-lib'; +import { ReactNode } from 'react'; import Toast from './components/Toast'; import Logger from './logger'; @@ -14,6 +15,7 @@ class Toaster extends Logger { private instanceRetPatch?: Patch; private node: any; private settingsModule: any; + private ready: boolean = false; constructor() { super('Toaster'); @@ -24,14 +26,8 @@ class Toaster extends Logger { } async init() { - this.settingsModule = findModuleChild((m) => { - if (typeof m !== 'object') return undefined; - for (let prop in m) { - if (typeof m[prop]?.settings?.bDisableToastsInGame !== 'undefined') return m[prop]; - } - }); - let instance: any; + while (true) { instance = findInReactTree( (document.getElementById('root') as any)._reactRootContainer._internalRoot.current, @@ -43,13 +39,26 @@ class Toaster extends Logger { } this.node = instance.return.return; + let toast: any; + let renderedToast: ReactNode = null; this.node.stateNode.render = (...args: any[]) => { const ret = this.node.stateNode.__proto__.render.call(this.node.stateNode, ...args); if (ret) { this.instanceRetPatch = afterPatch(ret, 'type', (_: any, ret: any) => { - if (ret?.props?.children[1]?.children?.props?.notification?.decky) { - const toast = ret.props.children[1].children.props.notification; - ret.props.children[1].children.type = () => <Toast toast={toast} />; + if (ret?.props?.children[1]?.children?.props) { + const currentToast = ret.props.children[1].children.props.notification; + if (currentToast?.decky) { + if (currentToast == toast) { + ret.props.children[1].children = renderedToast; + } else { + toast = currentToast; + renderedToast = <Toast toast={toast} />; + ret.props.children[1].children = renderedToast; + } + } else { + toast = null; + renderedToast = null; + } } return ret; }); @@ -57,11 +66,21 @@ class Toaster extends Logger { return ret; }; this.node.stateNode.forceUpdate(); + this.settingsModule = findModuleChild((m) => { + if (typeof m !== 'object') return undefined; + for (let prop in m) { + if (typeof m[prop]?.settings && m[prop]?.communityPreferences) return m[prop]; + } + }); this.log('Initialized'); + this.ready = true; } - toast(toast: ToastData) { - const settings = this.settingsModule.settings; + async toast(toast: ToastData) { + while (!this.ready) { + await sleep(100); + } + const settings = this.settingsModule?.settings; let toastData = { nNotificationID: window.NotificationStore.m_nNextTestNotificationID++, rtCreated: Date.now(), @@ -73,13 +92,12 @@ class Toaster extends Logger { // @ts-ignore toastData.data.appid = () => 0; if ( - (settings.bDisableAllToasts && !toast.critical) || - (settings.bDisableToastsInGame && !toast.critical && window.NotificationStore.BIsUserInGame()) + (settings?.bDisableAllToasts && !toast.critical) || + (settings?.bDisableToastsInGame && !toast.critical && window.NotificationStore.BIsUserInGame()) ) return; window.NotificationStore.m_rgNotificationToasts.push(toastData); window.NotificationStore.DispatchNextToast(); - window.NotificationStore.m_rgNotificationToasts.pop(); } deinit() { |
