Convert space cadet to isolated app

This commit is contained in:
Dustin Brett 2025-01-20 19:57:11 -08:00
parent 734bfb4407
commit acc77cd878
5 changed files with 54 additions and 44 deletions

View File

@ -1,13 +1,8 @@
import styled from "styled-components";
const StyledSpaceCadet = styled.div`
height: calc(100% - 30px) !important;
width: 100% !important;
canvas {
height: calc(100% + 12px) !important;
width: 100% !important;
}
height: ${({ theme }) => `calc(100% - ${theme.sizes.titleBar.height}px)`};
width: 100%;
`;
export default StyledSpaceCadet;

View File

@ -2,16 +2,13 @@ import StyledSpaceCadet from "components/apps/SpaceCadet/StyledSpaceCadet";
import useSpaceCadet from "components/apps/SpaceCadet/useSpaceCadet";
import AppContainer from "components/system/Apps/AppContainer";
import { type ComponentProcessProps } from "components/system/Apps/RenderComponent";
import { haltEvent } from "utils/functions";
const SpaceCadet: FC<ComponentProcessProps> = ({ id }) => (
<AppContainer
StyledComponent={StyledSpaceCadet}
id={id}
useHook={useSpaceCadet}
>
<canvas id="canvas" onContextMenu={haltEvent} />
</AppContainer>
/>
);
export default SpaceCadet;

View File

@ -3,60 +3,77 @@ import { type ContainerHookProps } from "components/system/Apps/AppContainer";
import useEmscriptenMount from "components/system/Files/FileManager/useEmscriptenMount";
import { type EmscriptenFS } from "contexts/fileSystem/useAsyncFs";
import { useProcesses } from "contexts/process";
import { haltEvent, loadFiles } from "utils/functions";
import useIsolatedContentWindow from "hooks/useIsolatedContentWindow";
import { TRANSITIONS_IN_MILLISECONDS } from "utils/constants";
import { loadFiles } from "utils/functions";
const useSpaceCadet = ({
containerRef,
id,
setLoading,
loading,
}: ContainerHookProps): void => {
const { linkElement, processes: { [id]: { libs = [] } = {} } = {} } =
useProcesses();
const [canvas, setCanvas] = useState<HTMLCanvasElement>();
const { processes: { [id]: { libs = [] } = {} } = {} } = useProcesses();
const mountEmFs = useEmscriptenMount();
const getContentWindow = useIsolatedContentWindow(
id,
containerRef,
undefined,
"canvas { height: calc(100% + 12px) !important; width: 100% !important; }",
true
);
const [contentWindow, setContentWindow] = useState<Window>();
useEffect(() => {
const containerCanvas = containerRef.current?.querySelector("canvas");
if (loading) {
const newContentWindow = getContentWindow?.();
if (containerCanvas instanceof HTMLCanvasElement) {
window.Module = {
canvas: containerCanvas,
if (!newContentWindow) return;
const canvas = newContentWindow?.document.querySelector(
"canvas"
) as HTMLCanvasElement;
canvas.addEventListener("contextmenu", haltEvent);
newContentWindow.Module = {
canvas,
postRun: () => {
setLoading(false);
mountEmFs(window.FS as EmscriptenFS, "SpaceCadet");
linkElement(id, "peekElement", containerCanvas);
setContentWindow(newContentWindow);
mountEmFs(newContentWindow.FS as EmscriptenFS, "SpaceCadet");
},
windowElement: newContentWindow.document.body,
};
setCanvas(containerCanvas);
}
}, [containerRef, id, linkElement, mountEmFs, setLoading]);
useEffect(() => {
if (canvas) {
setTimeout(() => {
const { height, width } =
containerRef.current?.getBoundingClientRect() || {};
newContentWindow.document.body.getBoundingClientRect() || {};
if (height && width) {
canvas.style.height = `${height}px`;
canvas.style.width = `${width}px`;
loadFiles(libs, undefined, !!window.Module.canvas);
setTimeout(
() =>
loadFiles(libs, undefined, undefined, undefined, newContentWindow),
TRANSITIONS_IN_MILLISECONDS.WINDOW
);
}
}, TRANSITIONS_IN_MILLISECONDS.WINDOW);
}
}, [getContentWindow, libs, loading, mountEmFs, setLoading]);
return () => {
if (canvas && window.Module) {
useEffect(
() => () => {
if (contentWindow?.Module) {
try {
window.Module.SDL2?.audioContext.close();
contentWindow.Module.SDL2?.audioContext.close();
} catch {
// Ignore errors during closing
}
}
};
}, [canvas, containerRef, libs]);
},
[contentWindow?.Module]
);
};
export default useSpaceCadet;

File diff suppressed because one or more lines are too long

View File

@ -16,6 +16,7 @@ declare global {
arguments?: string[];
canvas: HTMLCanvasElement;
postRun: () => void;
windowElement?: HTMLElement;
};
sharedGlobals?: Record<string, SharedGlobal>;
}