From 3cf9fed80a7f6b16fa97d544be13621732d6f910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Tue, 1 Nov 2022 12:57:43 +0000 Subject: [PATCH] feat: new unregister of events --- examples/web/react/app.tsx | 32 +++++++++++++---- examples/web/react/components/modal/modal.tsx | 8 +++-- .../web/react/components/overlay/overlay.tsx | 36 ++++++++++++------- examples/web/react/components/tiles/tiles.css | 0 4 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 examples/web/react/components/tiles/tiles.css diff --git a/examples/web/react/app.tsx b/examples/web/react/app.tsx index 4462d92d..9ab89f28 100644 --- a/examples/web/react/app.tsx +++ b/examples/web/react/app.tsx @@ -45,6 +45,14 @@ export class Observable { this.events[event] = callbacks; } + unbind(event: string, callback: Callback<this>) { + const callbacks = this.events[event] ?? []; + if (!callbacks.includes(callback)) return; + const index = callbacks.indexOf(callback); + callbacks.splice(index, 1); + this.events[event] = callbacks; + } + trigger(event: string, params?: Record<string, any>) { const callbacks = this.events[event] ?? []; callbacks.forEach((c) => c(this, params)); @@ -67,6 +75,7 @@ export type BenchmarkResult = { export interface ObservableI { bind(event: string, callback: Callback<this>): void; + unbind(event: string, callback: Callback<this>): void; trigger(event: string): void; } @@ -237,7 +246,7 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => { } }, [keyaction]); useEffect(() => { - document.addEventListener("keydown", (event) => { + const onKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { setKeyaction("Escape"); event.stopPropagation(); @@ -248,14 +257,25 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => { event.stopPropagation(); event.preventDefault(); } - }); - emulator.bind("booted", () => { + }; + const onBooted = () => { const romInfo = emulator.getRomInfo(); setRomInfo(romInfo); - }); - emulator.bind("message", (_, params = {}) => { + }; + const onMessage = ( + emulator: Emulator, + params: Record<string, any> = {} + ) => { showToast(params.text, params.error, params.timeout); - }); + }; + document.addEventListener("keydown", onKeyDown); + emulator.bind("booted", onBooted); + emulator.bind("message", onMessage); + return () => { + document.removeEventListener("keydown", onKeyDown); + emulator.unbind("booted", onBooted); + emulator.unbind("message", onMessage); + }; }, []); const getPauseText = () => (paused ? "Resume" : "Pause"); diff --git a/examples/web/react/components/modal/modal.tsx b/examples/web/react/components/modal/modal.tsx index ce3fdcbe..4ed68660 100644 --- a/examples/web/react/components/modal/modal.tsx +++ b/examples/web/react/components/modal/modal.tsx @@ -25,11 +25,15 @@ export const Modal: FC<ModalProps> = ({ const classes = () => ["modal", visible ? "visible" : "", ...style].join(" "); useEffect(() => { - document.addEventListener("keydown", (event) => { + const onKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { onCancel && onCancel(); } - }); + }; + document.addEventListener("keydown", onKeyDown); + return () => { + document.removeEventListener("keydown", onKeyDown); + }; }, []); const getTextHtml = (separator = /\n/g) => ({ __html: text.replace(separator, "<br/>") diff --git a/examples/web/react/components/overlay/overlay.tsx b/examples/web/react/components/overlay/overlay.tsx index 831fc1c6..c5267fb0 100644 --- a/examples/web/react/components/overlay/overlay.tsx +++ b/examples/web/react/components/overlay/overlay.tsx @@ -15,7 +15,7 @@ export const Overlay: FC<OverlayProps> = ({ text, style = [], onFile }) => { const classes = () => ["overlay", visible ? "visible" : "", ...style].join(" "); useEffect(() => { - document.addEventListener("drop", async (event) => { + const onDrop = async (event: DragEvent) => { if ( !event.dataTransfer!.files || event.dataTransfer!.files.length === 0 @@ -30,25 +30,37 @@ export const Overlay: FC<OverlayProps> = ({ text, style = [], onFile }) => { const file = event.dataTransfer!.files[0]; onFile && onFile(file); - }); - document.addEventListener("dragover", async (event) => { + }; + const onDragOver = async (event: DragEvent) => { if (!event.dataTransfer!.items || event.dataTransfer!.items[0].type) return; - event.preventDefault(); - setVisible(true); - }); - document.addEventListener("dragenter", async (event) => { + }; + const onDragEnter = async (event: DragEvent) => { if (!event.dataTransfer!.items || event.dataTransfer!.items[0].type) return; setVisible(true); - }); - document.addEventListener("dragleave", async (event) => { - if (!event.dataTransfer!.items || event.dataTransfer!.items[0].type) - return; + }; + const onDragLeave = async (event: DragEvent) => { + if ( + !event.dataTransfer!.items || + event.dataTransfer!.items[0].type + ) { + } + return; setVisible(false); - }); + }; + document.addEventListener("drop", onDrop); + document.addEventListener("dragover", onDragOver); + document.addEventListener("dragenter", onDragEnter); + document.addEventListener("dragleave", onDragLeave); + return () => { + document.removeEventListener("drop", onDrop); + document.removeEventListener("dragover", onDragOver); + document.removeEventListener("dragenter", onDragEnter); + document.removeEventListener("dragleave", onDragLeave); + }; }, []); return ( <div className={classes()}> diff --git a/examples/web/react/components/tiles/tiles.css b/examples/web/react/components/tiles/tiles.css new file mode 100644 index 00000000..e69de29b -- GitLab