Skip to content

Commit c74d091

Browse files
committed
LAUNCHER-12 fix: frontend not reacting to game close
1 parent e8ad2e0 commit c74d091

File tree

4 files changed

+66
-33
lines changed

4 files changed

+66
-33
lines changed

apps/frontend/src/ui/hooks/useNotifications.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import type { UnlistenFn } from '@tauri-apps/api/event';
22
import type { NotificationData } from '~ui/components/overlay/notifications/NotificationComponent';
33
import { events } from '@onelauncher/client/bindings';
4+
import { randomString } from '~utils';
45
import { type Accessor, type Context, createContext, createSignal, onCleanup, onMount, type ParentProps, type Signal, useContext } from 'solid-js';
56

67
type Notifications = Record<string, NotificationData>;
78

89
interface HookReturn {
910
list: Accessor<Notifications>;
1011
set: (id: string, data: NotificationData) => void;
12+
create: (data: NotificationData) => void;
1113
clear: () => void;
1214
}
1315

@@ -44,11 +46,14 @@ export function NotificationProvider(props: ParentProps) {
4446
function useNotifications(): HookReturn {
4547
const [notifications, setNotifications] = useContext(NotificationContext);
4648

47-
return {
49+
const ctx = {
4850
list: notifications,
4951
set: (id, data) => setNotifications(notifications => ({ ...notifications, [id]: data })),
52+
create: data => ctx.set(randomString(6), data),
5053
clear: () => setNotifications({}),
51-
};
54+
} satisfies HookReturn;
55+
56+
return ctx;
5257
}
5358

5459
export default useNotifications;

apps/frontend/src/ui/pages/cluster/ClusterGame.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Modal, { createModal } from '~ui/components/overlay/Modal';
1111
import Sidebar from '~ui/components/Sidebar';
1212
import useClusterContext from '~ui/hooks/useCluster';
1313
import useCommand from '~ui/hooks/useCommand';
14+
import useNotifications from '~ui/hooks/useNotifications';
1415
import { createSignal, onCleanup, onMount } from 'solid-js';
1516
import { render } from 'solid-js/web';
1617

@@ -26,6 +27,7 @@ function ClusterGame() {
2627
const [params] = useSearchParams<ClusterGameParams>();
2728
const [log] = useCommand(() => bridge.commands.getClusterLog(cluster()!.uuid, 'latest.log'));
2829
const [isRunning, setIsRunning] = createSignal(true);
30+
const notifications = useNotifications();
2931

3032
const [unlisten, setUnlisten] = createSignal<UnlistenFn>();
3133
let codeRef!: HTMLElement;
@@ -39,6 +41,11 @@ function ClusterGame() {
3941
render(() => <Line line={event.payload.message} />, codeRef);
4042
else if (event.payload.event === 'finished')
4143
setIsRunning(false);
44+
else if (event.payload.event === 'modified')
45+
notifications.create({
46+
title: 'Process Status',
47+
message: event.payload.message,
48+
});
4249
});
4350

4451
setUnlisten(() => unlisten);

apps/frontend/src/utils/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ export function int32ToBigInt([high, low]: [number, number]): bigint {
5454
return (BigInt(high | 0) << 32n) | BigInt(low >>> 0);
5555
}
5656

57+
export function randomString(len: number = 6, charSet: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
58+
let randomString = '';
59+
for (let i = 0; i < len; i++) {
60+
const randomPos = Math.floor(Math.random() * charSet.length);
61+
randomString += charSet.substring(randomPos, randomPos + 1);
62+
}
63+
return randomString;
64+
}
65+
5766
export function abbreviateNumber(n: number | bigint, locale: string = 'en-US'): string {
5867
return new Intl.NumberFormat(locale, {
5968
notation: 'compact',

packages/core/src/store/processor.rs

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use uuid::Uuid;
1313

1414
use crate::api::cluster;
1515
use crate::constants::PROCESSOR_FILE;
16-
use crate::proxy::send::send_process;
16+
use crate::proxy::send::{send_ingress, send_message, send_process};
1717
use crate::proxy::ProcessPayloadType;
1818
use crate::utils::http::read_json;
1919
use crate::State;
@@ -427,7 +427,7 @@ impl Processor {
427427

428428
#[cfg(target_os = "linux")]
429429
{
430-
if enable_gamemode.is_some_and(|x| x == true) {
430+
if enable_gamemode.is_some_and(|x| x) {
431431
if let Err(err) = onelauncher_gamemode::request_start_for_wrapper(pid) {
432432
tracing::warn!("failed to enable gamemode, continuing: {}", err);
433433
};
@@ -654,8 +654,8 @@ impl Processor {
654654
});
655655

656656
tokio::spawn(async {
657-
let state = State::get();
658-
let state = match state.await {
657+
let state = State::get().await;
658+
let state = match state {
659659
Ok(state) => state,
660660
Err(err) => {
661661
tracing::warn!("failed to get state: {}", err);
@@ -689,47 +689,59 @@ impl Processor {
689689
}
690690

691691
let post = if let Some(hook) = post {
692-
let mut cmd = hook.split(' ');
693-
if let Some(c) = cmd.next() {
694-
let mut c = Command::new(c);
695-
c.args(cmd).current_dir(cluster_path.full_path().await?);
696-
Some(c)
697-
} else {
692+
if hook.is_empty() {
698693
None
694+
} else {
695+
let mut cmd = hook.split(' ');
696+
if let Some(c) = cmd.next() {
697+
let mut c = Command::new(c);
698+
c.args(cmd).current_dir(cluster_path.full_path().await?);
699+
Some(c)
700+
} else {
701+
None
702+
}
699703
}
700704
} else {
701705
None
702706
};
703707

704708
if let Some(mut m_c) = post {
705-
{
706-
let mut current_child: tokio::sync::RwLockWriteGuard<'_, ChildType> =
707-
current_child.write().await;
708-
let new_child = m_c.spawn().map_err(IOError::from)?;
709-
current_pid = new_child
710-
.id()
711-
.ok_or_else(|| anyhow::anyhow!("process failed, couldnt get pid"))?;
712-
*current_child = ChildType::ChildProcess(new_child);
713-
}
709+
let result = {
710+
{
711+
let mut current_child: tokio::sync::RwLockWriteGuard<'_, ChildType> =
712+
current_child.write().await;
714713

715-
send_process(
716-
uuid,
717-
current_pid,
718-
ProcessPayloadType::Modified,
719-
"running post hook",
720-
)
721-
.await?;
714+
let new_child = m_c.spawn().map_err(IOError::from)?;
715+
716+
current_pid = new_child
717+
.id()
718+
.ok_or_else(|| anyhow::anyhow!("process failed, couldnt get pid"))?;
719+
720+
*current_child = ChildType::ChildProcess(new_child);
721+
};
722+
723+
send_process(
724+
uuid,
725+
current_pid,
726+
ProcessPayloadType::Modified,
727+
"running post hook",
728+
)
729+
.await?;
722730

723-
loop {
724731
let value = current_child.write().await.try_wait();
725-
if let Some(stat) = value? {
732+
733+
if let Ok(Some(stat)) = value {
726734
exit_status = stat;
727-
break;
728735
}
729736

730-
tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
737+
Ok::<(), crate::Error>(())
738+
};
739+
740+
if let Err(err) = result {
741+
tracing::error!("failed to run post hook: {err}");
742+
let _ = send_message(format!("failed to run post hook: {err}").as_str()).await;
731743
}
732-
}
744+
};
733745

734746
send_process(
735747
uuid,

0 commit comments

Comments
 (0)