mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
arm powered steam deck
This commit is contained in:
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -12,7 +12,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<!-- site-metadata:inject -->
|
<!-- site-metadata:inject -->
|
||||||
<!-- analytics:inject -->
|
<!-- analytics:inject -->
|
||||||
<script type="module" crossorigin src="/assets/index-CIeAOZ_Y.js"></script>
|
<script type="module" crossorigin src="/assets/index-hzmph71J.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DKoVL79I.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DKoVL79I.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// Undocked Page Exit Guard
|
||||||
|
// Purpose: Asks the browser to confirm document-level navigation while the current driver's rover is undocked.
|
||||||
|
// Scope: Owns only the native beforeunload lifecycle; it does not render UI or attempt to replace browser safety dialogs.
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useControlSelector } from '../../controls/index.js';
|
||||||
|
import { useTelemetrySelector } from '../../context/TelemetryContext.jsx';
|
||||||
|
|
||||||
|
function selectHomeBaseState(frame) {
|
||||||
|
const homeBase = frame?.sensors?.chargingSources?.homeBase;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Missing telemetry must remain distinct from a real "not on the home base"
|
||||||
|
reading. Treating the initial empty frame as undocked would enable the exit
|
||||||
|
warning before the browser has received enough information to justify it.
|
||||||
|
*/
|
||||||
|
return typeof homeBase === 'boolean' ? homeBase : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function UndockedPageExitGuard() {
|
||||||
|
const roverId = useControlSelector((control) => control.state.roverId);
|
||||||
|
const homeBaseState = useTelemetrySelector(roverId, selectHomeBaseState);
|
||||||
|
const shouldConfirmExit = Boolean(roverId) && homeBaseState === false;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!shouldConfirmExit) return undefined;
|
||||||
|
|
||||||
|
function handleBeforeUnload(event) {
|
||||||
|
/*
|
||||||
|
Browsers intentionally own the wording and presentation of this dialog.
|
||||||
|
preventDefault is the modern signal, while assigning returnValue keeps
|
||||||
|
the confirmation working in browsers that still require the legacy part
|
||||||
|
of the beforeunload contract.
|
||||||
|
*/
|
||||||
|
event.preventDefault();
|
||||||
|
event.returnValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('beforeunload', handleBeforeUnload);
|
||||||
|
return () => {
|
||||||
|
/*
|
||||||
|
Removing the listener as soon as the rover docks or the assignment ends
|
||||||
|
prevents ordinary spectators and completed drivers from seeing a stale
|
||||||
|
leave-page confirmation.
|
||||||
|
*/
|
||||||
|
window.removeEventListener('beforeunload', handleBeforeUnload);
|
||||||
|
};
|
||||||
|
}, [shouldConfirmExit]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
import useLayoutMode from '../hooks/useLayoutMode.js';
|
import useLayoutMode from '../hooks/useLayoutMode.js';
|
||||||
import { DriverLayoutProvider } from '../layouts/driver/DriverLayoutContext.jsx';
|
import { DriverLayoutProvider } from '../layouts/driver/DriverLayoutContext.jsx';
|
||||||
import DriverLayoutRoot from '../layouts/driver/DriverLayoutRoot.jsx';
|
import DriverLayoutRoot from '../layouts/driver/DriverLayoutRoot.jsx';
|
||||||
|
import UndockedPageExitGuard from '../components/UndockedPageExitGuard/index.jsx';
|
||||||
|
|
||||||
/* Driver-page compositions live under layouts/driver. App retains only global providers, overlays, and route-level state. */
|
/* Driver-page compositions live under layouts/driver. App retains only global providers, overlays, and route-level state. */
|
||||||
function DriverPageRoot() {
|
function DriverPageRoot() {
|
||||||
@@ -92,6 +93,12 @@ function DriverPageContent({ layout }) {
|
|||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<ControlSystemProvider>
|
<ControlSystemProvider>
|
||||||
|
{/*
|
||||||
|
Keep document-exit protection inside the control provider so it follows
|
||||||
|
the same assigned-rover identity as every driving command. Mounting it
|
||||||
|
only on the driver page leaves spectator and utility routes unchanged.
|
||||||
|
*/}
|
||||||
|
<UndockedPageExitGuard />
|
||||||
<KeyboardInputManager />
|
<KeyboardInputManager />
|
||||||
<GamepadInputManager />
|
<GamepadInputManager />
|
||||||
<main className={`relative flex w-full flex-col ${themeGapClass} text-base`}>
|
<main className={`relative flex w-full flex-col ${themeGapClass} text-base`}>
|
||||||
|
|||||||
Reference in New Issue
Block a user