Skip to content
Snippets Groups Projects
Verified Commit 77c765bd authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

feat: improved modal support

parent bbfa014d
No related branches found
No related tags found
1 merge request!9Version 0.4.0 🍾
Pipeline #1380 passed
......@@ -166,13 +166,82 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => {
const [backgroundIndex, setBackgroundIndex] = useState(0);
const [romInfo, setRomInfo] = useState<RomInfo>({});
const [framerate, setFramerate] = useState(0);
const [keyaction, setKeyaction] = useState<string | null>(null);
const [keyaction, setKeyaction] = useState<string>();
const [modalVisible, setModalVisible] = useState(false);
const [modalTitle, setModalTitle] = useState<string>();
const [modalText, setModalText] = useState<string>();
const frameRef = useRef<boolean>(false);
const errorRef = useRef<boolean>(false);
const modalCallbackRef =
useRef<(value: boolean | PromiseLike<boolean>) => void>();
useEffect(() => {
document.body.style.backgroundColor = `#${getBackground()}`;
}, [backgroundIndex]);
useEffect(() => {
switch (keyaction) {
case "Escape":
setFullscreen(false);
setKeyaction(undefined);
break;
case "Fullscreen":
setFullscreen(!fullscreen);
setKeyaction(undefined);
break;
}
}, [keyaction]);
useEffect(() => {
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
setKeyaction("Escape");
event.stopPropagation();
event.preventDefault();
}
if (event.key === "f" && event.ctrlKey === true) {
setKeyaction("Fullscreen");
event.stopPropagation();
event.preventDefault();
}
});
emulator.bind("booted", () => {
const romInfo = emulator.getRomInfo();
setRomInfo(romInfo);
});
}, []);
const getPauseText = () => (paused ? "Resume" : "Pause");
const getPauseIcon = () =>
paused ? require("../res/play.svg") : require("../res/pause.svg");
const getBackground = () => backgrounds[backgroundIndex];
const showModal = async (
text: string,
title = "Alert"
): Promise<boolean> => {
setModalText(text);
setModalTitle(title);
setModalVisible(true);
const result = (await new Promise((resolve) => {
modalCallbackRef.current = resolve;
})) as boolean;
return result;
};
const onModalConfirm = () => {
if (modalCallbackRef.current) {
modalCallbackRef.current(true);
modalCallbackRef.current = undefined;
}
setModalVisible(false);
};
const onModalCancel = () => {
if (modalCallbackRef.current) {
modalCallbackRef.current(false);
modalCallbackRef.current = undefined;
}
setModalVisible(false);
};
const onPauseClick = () => {
emulator.toggleRunning();
setPaused(!paused);
......@@ -180,6 +249,12 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => {
const onResetClick = () => {
emulator.reset();
};
const onBenchmarkClick = async () => {
const result = await showModal(
"Are you sure you want to start a benchmark?\nThe benchmark is considered an expensive operation!",
"Confirm"
);
};
const onFullscreenClick = () => {
setFullscreen(!fullscreen);
};
......@@ -204,43 +279,16 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => {
await handler(undefined, require("../res/storm.png"), 0.2);
});
};
const onKeyDown = (event: KeyboardEvent) => {};
useEffect(() => {
document.body.style.backgroundColor = `#${getBackground()}`;
}, [backgroundIndex]);
useEffect(() => {
switch (keyaction) {
case "Escape":
setFullscreen(false);
setKeyaction(null);
break;
case "Fullscreen":
setFullscreen(!fullscreen);
setKeyaction(null);
break;
}
}, [keyaction]);
useEffect(() => {
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
setKeyaction("Escape");
event.stopPropagation();
event.preventDefault();
}
if (event.key === "f" && event.ctrlKey === true) {
setKeyaction("Fullscreen");
event.stopPropagation();
event.preventDefault();
}
});
emulator.bind("booted", () => {
const romInfo = emulator.getRomInfo();
setRomInfo(romInfo);
});
}, []);
return (
<div className="app">
<Modal />
<Modal
visible={modalVisible}
title={modalTitle}
text={modalText}
onConfirm={onModalConfirm}
onCancel={onModalCancel}
/>
<Footer color={getBackground()}>
Built with ❤️ by{" "}
<Link href="https://joao.me" target="_blank">
......@@ -313,6 +361,12 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => {
imageAlt="reset"
onClick={onResetClick}
/>
<Button
text={"Benchmark"}
image={require("../res/bolt.svg")}
imageAlt="benchmark"
onClick={onBenchmarkClick}
/>
<Button
text={"Fullscreen"}
image={require("../res/maximise.svg")}
......@@ -322,7 +376,7 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => {
<Button
text={"Theme"}
image={require("../res/marker.svg")}
imageAlt="marker"
imageAlt="theme"
onClick={onThemeClick}
/>
</ButtonContainer>
......
......@@ -66,10 +66,10 @@ export const Display: FC<DisplayProps> = ({
const classes = () =>
["display", fullscreen ? "fullscreen" : null, size, ...style].join(" ");
const [width, setWidth] = useState<number | undefined>(undefined);
const [height, setHeight] = useState<number | undefined>(undefined);
const [width, setWidth] = useState<number>();
const [height, setHeight] = useState<number>();
const canvasRef = useRef<HTMLCanvasElement>(null);
const canvasContentsRef = useRef<CanvasContents | undefined>(undefined);
const canvasContentsRef = useRef<CanvasContents>();
const resizeRef = useRef(() => {
const [fullWidth, fullHeight] = crop(options.width / options.height);
setWidth(fullWidth);
......
import React, { ReactNode, FC, ButtonHTMLAttributes } from "react";
import React, { ReactNode, FC, ButtonHTMLAttributes, useEffect } from "react";
import Button from "../button/button";
import "./modal.css";
......@@ -10,16 +10,27 @@ type ModalProps = {
text?: string;
visible?: boolean;
style?: string[];
onConfirm?: () => void;
onCancel?: () => void;
};
export const Modal: FC<ModalProps> = ({
title = "Alert",
text = "Do you confirm the following operation?",
visible = false,
style = []
style = [],
onConfirm,
onCancel
}) => {
const classes = () =>
["modal", visible ? "visible" : "", ...style].join(" ");
useEffect(() => {
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
onCancel && onCancel();
}
});
}, []);
return (
<div className={classes()}>
<div className="modal-window">
......@@ -29,6 +40,7 @@ export const Modal: FC<ModalProps> = ({
size={"medium"}
style={["simple", "rounded", "no-text"]}
image={require("./close.svg")}
onClick={onCancel}
/>
</div>
<h2 className="modal-title">{title}</h2>
......@@ -38,11 +50,13 @@ export const Modal: FC<ModalProps> = ({
text={"Cancel"}
size={"medium"}
style={["simple", "red", "border", "padded-large"]}
onClick={onCancel}
/>
<Button
text={"Confirm"}
size={"medium"}
style={["simple", "border", "padded-large"]}
onClick={onConfirm}
/>
</div>
</div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment