Skip to content

Commit 78b3328

Browse files
authored
feat: relay scratch run events to the listening parent app (#1496)
Relates to issues: [1484](RaspberryPiFoundation/digital-editor-issues#1484) This will likely need the changes from [1483](RaspberryPiFoundation/digital-editor-issues#1483) to be seen to work full stack There as a draft PR that will capture the even in editor-standalone - RaspberryPiFoundation/editor-standalone#954
1 parent 2d2e39b commit 78b3328

4 files changed

Lines changed: 108 additions & 0 deletions

File tree

src/components/Editor/Project/ScratchContainer.jsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useDispatch, useSelector } from "react-redux";
33
import { ClickScrollPlugin, OverlayScrollbars } from "overlayscrollbars";
44
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
55
import { applyScratchProjectIdentifierUpdate } from "../../../redux/EditorSlice";
6+
import { runStartedEvent } from "../../../events/WebComponentCustomEvents";
67
import {
78
subscribeToScratchProjectIdentifierUpdates,
89
postMessageToScratchIframe,
@@ -66,6 +67,22 @@ export default function ScratchContainer() {
6667
});
6768
}, [accessToken, initialAccessToken]);
6869

70+
useEffect(() => {
71+
const allowedOrigin = getScratchAllowedOrigin();
72+
73+
const handleScratchRunStarted = (event) => {
74+
if (event.origin !== allowedOrigin) return;
75+
if (event.data?.type !== "scratch-gui-project-run-started") return;
76+
77+
document.dispatchEvent(runStartedEvent({}));
78+
};
79+
80+
window.addEventListener("message", handleScratchRunStarted);
81+
return () => {
82+
window.removeEventListener("message", handleScratchRunStarted);
83+
};
84+
}, []);
85+
6986
useEffect(() => {
7087
const allowedOrigin = getScratchAllowedOrigin();
7188
const authKey = localStorage.getItem("authKey");

src/components/Editor/Project/ScratchContainer.test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,49 @@ describe("ScratchContainer", () => {
170170
});
171171
});
172172

173+
describe("scratch-gui-project-run-started message", () => {
174+
let runStartedHandler;
175+
176+
beforeEach(() => {
177+
runStartedHandler = jest.fn();
178+
document.addEventListener("editor-runStarted", runStartedHandler);
179+
});
180+
181+
afterEach(() => {
182+
document.removeEventListener("editor-runStarted", runStartedHandler);
183+
});
184+
185+
test("dispatches editor-runStarted when scratch-gui-project-run-started is received", () => {
186+
renderScratchContainer();
187+
188+
act(() => {
189+
dispatchMessage({
190+
type: "scratch-gui-project-run-started",
191+
});
192+
});
193+
194+
expect(runStartedHandler).toHaveBeenCalledTimes(1);
195+
expect(runStartedHandler.mock.calls[0][0].detail).toEqual({});
196+
});
197+
198+
test("does not dispatch editor-runStarted after unmount", () => {
199+
const store = buildStore();
200+
const { unmount } = render(
201+
<Provider store={store}>
202+
<ScratchContainer />
203+
</Provider>,
204+
);
205+
206+
unmount();
207+
208+
act(() => {
209+
dispatchMessage({ type: "scratch-gui-project-run-started" });
210+
});
211+
212+
expect(runStartedHandler).not.toHaveBeenCalled();
213+
});
214+
});
215+
173216
test("updates the parent project identifier without reloading the iframe project_id", () => {
174217
const { store } = renderScratchContainer();
175218

src/components/ScratchEditor/ScratchIntegrationHOC.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ const ScratchIntegrationHOC = function (WrappedComponent) {
2121
this.handleRemix = this.handleRemix.bind(this);
2222
this.handleSave = this.handleSave.bind(this);
2323
this.handleProjectChanged = this.handleProjectChanged.bind(this);
24+
this.handleProjectRunStart = this.handleProjectRunStart.bind(this);
2425
}
2526
componentDidMount() {
2627
window.addEventListener("message", this.handleMessage);
2728
this.props.vm.on("PROJECT_CHANGED", this.handleProjectChanged);
29+
this.props.vm.on("PROJECT_RUN_START", this.handleProjectRunStart);
2830
this.props.setStageSize();
2931
}
3032
componentWillUnmount() {
@@ -33,6 +35,10 @@ const ScratchIntegrationHOC = function (WrappedComponent) {
3335
"PROJECT_CHANGED",
3436
this.handleProjectChanged,
3537
);
38+
this.props.vm.removeListener(
39+
"PROJECT_RUN_START",
40+
this.handleProjectRunStart,
41+
);
3642
}
3743

3844
handleMessage(event) {
@@ -90,6 +96,9 @@ const ScratchIntegrationHOC = function (WrappedComponent) {
9096
handleProjectChanged() {
9197
postScratchGuiEvent("scratch-gui-project-changed");
9298
}
99+
handleProjectRunStart() {
100+
postScratchGuiEvent("scratch-gui-project-run-started");
101+
}
93102
render() {
94103
const {
95104
loadProject,

src/components/ScratchEditor/ScratchIntegrationHOC.test.jsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,43 @@ describe("ScratchIntegrationHOC", () => {
137137
});
138138
});
139139
});
140+
141+
describe("Scratch VM run events", () => {
142+
it("registers a PROJECT_RUN_START listener on mount", () => {
143+
render(
144+
React.createElement(Provider, { store }, React.createElement(Wrapped)),
145+
);
146+
147+
expect(mockVm.on).toHaveBeenCalledWith(
148+
"PROJECT_RUN_START",
149+
expect.any(Function),
150+
);
151+
});
152+
153+
it("removes the PROJECT_RUN_START listener on unmount", () => {
154+
const { unmount } = render(
155+
React.createElement(Provider, { store }, React.createElement(Wrapped)),
156+
);
157+
const handler = getVmHandler("PROJECT_RUN_START");
158+
159+
unmount();
160+
161+
expect(mockVm.removeListener).toHaveBeenCalledWith(
162+
"PROJECT_RUN_START",
163+
handler,
164+
);
165+
});
166+
167+
it("posts a project-run-started event when PROJECT_RUN_START fires", () => {
168+
render(
169+
React.createElement(Provider, { store }, React.createElement(Wrapped)),
170+
);
171+
172+
getVmHandler("PROJECT_RUN_START")();
173+
174+
expect(postScratchGuiEvent).toHaveBeenCalledWith(
175+
"scratch-gui-project-run-started",
176+
);
177+
});
178+
});
140179
});

0 commit comments

Comments
 (0)