summaryrefslogtreecommitdiff
path: root/frontend/src/components/DeckyToasterState.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/DeckyToasterState.tsx')
-rw-r--r--frontend/src/components/DeckyToasterState.tsx69
1 files changed, 69 insertions, 0 deletions
diff --git a/frontend/src/components/DeckyToasterState.tsx b/frontend/src/components/DeckyToasterState.tsx
new file mode 100644
index 00000000..8732d7f8
--- /dev/null
+++ b/frontend/src/components/DeckyToasterState.tsx
@@ -0,0 +1,69 @@
+import { ToastData } from 'decky-frontend-lib';
+import { FC, createContext, useContext, useEffect, useState } from 'react';
+
+interface PublicDeckyToasterState {
+ toasts: Set<ToastData>;
+}
+
+export class DeckyToasterState {
+ // TODO a set would be better
+ private _toasts: Set<ToastData> = new Set();
+
+ public eventBus = new EventTarget();
+
+ publicState(): PublicDeckyToasterState {
+ return { toasts: this._toasts };
+ }
+
+ addToast(toast: ToastData) {
+ this._toasts.add(toast);
+ this.notifyUpdate();
+ }
+
+ removeToast(toast: ToastData) {
+ this._toasts.delete(toast);
+ this.notifyUpdate();
+ }
+
+ private notifyUpdate() {
+ this.eventBus.dispatchEvent(new Event('update'));
+ }
+}
+
+interface DeckyToasterContext extends PublicDeckyToasterState {
+ addToast(toast: ToastData): void;
+ removeToast(toast: ToastData): void;
+}
+
+const DeckyToasterContext = createContext<DeckyToasterContext>(null as any);
+
+export const useDeckyToasterState = () => useContext(DeckyToasterContext);
+
+interface Props {
+ deckyToasterState: DeckyToasterState;
+}
+
+export const DeckyToasterStateContextProvider: FC<Props> = ({ children, deckyToasterState }) => {
+ const [publicDeckyToasterState, setPublicDeckyToasterState] = useState<PublicDeckyToasterState>({
+ ...deckyToasterState.publicState(),
+ });
+
+ useEffect(() => {
+ function onUpdate() {
+ setPublicDeckyToasterState({ ...deckyToasterState.publicState() });
+ }
+
+ deckyToasterState.eventBus.addEventListener('update', onUpdate);
+
+ return () => deckyToasterState.eventBus.removeEventListener('update', onUpdate);
+ }, []);
+
+ const addToast = deckyToasterState.addToast.bind(deckyToasterState);
+ const removeToast = deckyToasterState.removeToast.bind(deckyToasterState);
+
+ return (
+ <DeckyToasterContext.Provider value={{ ...publicDeckyToasterState, addToast, removeToast }}>
+ {children}
+ </DeckyToasterContext.Provider>
+ );
+};