Notifications
{notificationEntries.length > 0 && (
diff --git a/apps/onelauncher/frontend/src/hooks/useNotification.tsx b/apps/onelauncher/frontend/src/hooks/useNotification.tsx
index 02fe79f0..3e7a7de7 100644
--- a/apps/onelauncher/frontend/src/hooks/useNotification.tsx
+++ b/apps/onelauncher/frontend/src/hooks/useNotification.tsx
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react';
import { bindings } from '@/main';
import { randomString } from '@/utils/index';
-import { createContext, useContext, useState } from 'react';
+import { createContext, memo, useContext, useEffect, useMemo, useState } from 'react';
export interface NotificationData {
title: string;
@@ -24,40 +24,72 @@ interface NotificationContextValue {
setNotifications: React.Dispatch
>;
}
-const NotificationContext = createContext(undefined);
+const defaultContextValue: NotificationContextValue = {
+ notifications: {},
+ setNotifications: () => {},
+};
+
+const NotificationContext = createContext(defaultContextValue);
interface NotificationProviderProps {
children: ReactNode;
}
-export function NotificationProvider({ children }: NotificationProviderProps) {
+export const NotificationProvider = memo(({ children }: NotificationProviderProps) => {
const [notifications, setNotifications] = useState({});
- bindings.events.ingress.on((e) => {
- setNotifications(prev => ({
- ...prev,
- [e.id]: {
- title: `${e.ingress_type}`,
- message: e.message,
- },
- }));
- }).then(u => u());
+ useEffect(() => {
+ let cleanup: (() => void) | undefined;
+
+ bindings.events.ingress.on((e) => {
+ setNotifications(prev => ({
+ ...prev,
+ [e.id]: {
+ title: `${e.ingress_type}`,
+ message: e.message,
+ },
+ }));
+ }).then((u) => {
+ cleanup = u;
+ }).catch(console.error);
+
+ return () => {
+ cleanup?.();
+ };
+ }, []);
+
+ const contextValue = useMemo(() => ({
+ notifications,
+ setNotifications,
+ }), [notifications, setNotifications]);
return (
-
+
{children}
);
-}
+});
function useNotifications(): HookReturn {
const context = useContext(NotificationContext);
-
- if (!context)
- throw new Error('useNotifications must be used within a NotificationProvider');
-
const { notifications, setNotifications } = context;
+ const isDefaultContext = setNotifications === defaultContextValue.setNotifications;
+
+ if (isDefaultContext) {
+ if (import.meta.env.DEV) {
+ console.warn('useNotifications: Using default context (likely due to HMR or missing provider)');
+ return {
+ list: {},
+ set: () => {},
+ create: () => {},
+ remove: () => {},
+ clear: () => {},
+ };
+ }
+ throw new Error('useNotifications must be used within a NotificationProvider');
+ }
+
const ctx: HookReturn = {
list: notifications,
set: (id, data) => setNotifications(prev => ({ ...prev, [id]: data })),
diff --git a/apps/onelauncher/frontend/src/routes/app/cluster/settings.tsx b/apps/onelauncher/frontend/src/routes/app/cluster/settings.tsx
index 93f94dda..c3277183 100644
--- a/apps/onelauncher/frontend/src/routes/app/cluster/settings.tsx
+++ b/apps/onelauncher/frontend/src/routes/app/cluster/settings.tsx
@@ -38,7 +38,7 @@ function RouteComponent() {
-
+
diff --git a/apps/onelauncher/frontend/src/routes/app/index.tsx b/apps/onelauncher/frontend/src/routes/app/index.tsx
index 2a8b54d7..234ad819 100644
--- a/apps/onelauncher/frontend/src/routes/app/index.tsx
+++ b/apps/onelauncher/frontend/src/routes/app/index.tsx
@@ -28,20 +28,6 @@ hey future sassan here i guess the issue is solved idk
function RouteComponent() {
const result = useCommand('getClusters', bindings.core.getClusters);
- useEffect(() => {
- let unlisten: (() => void) | undefined;
- (async () => {
- unlisten = await bindings.events.ingress.on((e) => {
- if (typeof e.ingress_type === 'object')
- if ('PrepareCluster' in e.ingress_type)
- // eslint-disable-next-line no-console -- ok
- console.log(`Preparing cluster: ${e.ingress_type.PrepareCluster.cluster_name} %${e.percent}`);
- });
- })();
-
- return () => unlisten?.();
- }, []);
-
return (
diff --git a/apps/onelauncher/frontend/src/routes/app/route.tsx b/apps/onelauncher/frontend/src/routes/app/route.tsx
index e18f1696..d04e56c6 100644
--- a/apps/onelauncher/frontend/src/routes/app/route.tsx
+++ b/apps/onelauncher/frontend/src/routes/app/route.tsx
@@ -1,13 +1,41 @@
import Navbar from '@/components/Navbar';
+import useNotifications from '@/hooks/useNotification';
+import { bindings } from '@/main';
import { AnimatedOutlet } from '@onelauncher/common/components';
import { createFileRoute } from '@tanstack/react-router';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
+import { useEffect } from 'react';
export const Route = createFileRoute('/app')({
component: RouteComponent,
});
function RouteComponent() {
+ const { set, remove } = useNotifications();
+
+ useEffect(() => {
+ let unlisten: (() => void) | undefined;
+ (async () => {
+ unlisten = await bindings.events.ingress.on((e) => {
+ if (typeof e.ingress_type === 'object')
+ if ('PrepareCluster' in e.ingress_type) {
+ const { cluster_name } = e.ingress_type.PrepareCluster;
+ let id = `cluster-${cluster_name}`;
+
+ set(id, {
+ title: 'Preparing Cluster',
+ message: e.message,
+ });
+
+ if (e.percent === e.total)
+ remove(id);
+ }
+ });
+ })();
+
+ return () => unlisten?.();
+ }, [set, remove]);
+
return (
<>
diff --git a/apps/onelauncher/frontend/src/routes/app/settings/minecraft.tsx b/apps/onelauncher/frontend/src/routes/app/settings/minecraft.tsx
index 4dd631f4..789d73d2 100644
--- a/apps/onelauncher/frontend/src/routes/app/settings/minecraft.tsx
+++ b/apps/onelauncher/frontend/src/routes/app/settings/minecraft.tsx
@@ -35,7 +35,7 @@ function RouteComponent() {
{/*
*/}
-
+
@@ -129,7 +129,13 @@ export function GameSettings(props: GameSettingProps) {
// );
// }
-export function ProcessSettings() {
+interface ProcessSettingsProps {
+ settings: SettingProfileModel;
+}
+
+export function ProcessSettings(props: ProcessSettingsProps) {
+ const { settings } = props;
+
return (
<>
Process
@@ -140,6 +146,10 @@ export function ProcessSettings() {
title="Pre-Launch Command"
>
{
+ settings.hook_pre = e.target.value || null;
+ }}
placeholder="echo 'Game started'"
/>
@@ -150,6 +160,10 @@ export function ProcessSettings() {
title="Wrapper Command"
>
{
+ settings.hook_wrapper = e.target.value || null;
+ }}
placeholder="gamescope"
/>
@@ -160,6 +174,10 @@ export function ProcessSettings() {
title="Post-Exit Command"
>
{
+ settings.hook_post = e.target.value || null;
+ }}
placeholder="echo 'Game exited'"
/>