Skip to content

Commit ac7fe01

Browse files
loiswells97floehopper
authored andcommitted
Add runCode, stopCode & rerunCode to web component
Based on [1] & #899. The motivation for this change is to support the Block-to-Text app [2]. This mainly adds the `runCode`, `stopCode`, & `rerunCode` methods to the web component, but it also adds a check on the `webComponent` boolean state in `Output` to determine whether or not to render the `RunBar`. I don't really understand why this is needed, but having chatted to @loiswells97 we've got a nagging feeling there's a use case that does need it, so I'm going to leave it in plae for now. I've added a unit test to illustate the behaviour. I plan to add an e2e spec in a subsequent commit which will test the new methods on the web component. [1]: f9086a8 [2]: https://github.com/RaspberryPiFoundation/block-to-text-alpha/
1 parent b5aa82a commit ac7fe01

File tree

5 files changed

+54
-5
lines changed

5 files changed

+54
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1313
- Add `output_only` attribute to web component (#1014 & originally #782)
1414
- Add `assets_identifier` attribute to web component (#1014 & originally #901)
1515
- Enhance `code` attribute on web component to override project main component content (#1014 & originally #901)
16+
- Add `runCode`, `stopCode` & `rerunCode` methods to web component (#1014 & originally #899)
1617

1718
### Changed
1819

src/components/Editor/Output/Output.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const Output = ({ embedded = false, browserPreview = false }) => {
1212
const isBrowserPreview =
1313
searchParams.get("browserPreview") === "true" || browserPreview;
1414
const usePyodide = searchParams.get("pyodide") === "true";
15+
const webComponent = useSelector((state) => state.editor.webComponent);
1516

1617
return (
1718
<>
@@ -21,7 +22,9 @@ const Output = ({ embedded = false, browserPreview = false }) => {
2122
projectType={project.project_type}
2223
usePyodide={usePyodide}
2324
/>
24-
{isEmbedded && !isBrowserPreview && <RunBar embedded />}
25+
{!webComponent && isEmbedded && !isBrowserPreview && (
26+
<RunBar embedded />
27+
)}
2528
</div>
2629
</>
2730
);

src/components/Editor/Output/Output.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ describe("Output component", () => {
6262
expect(screen.queryByText("runButton.run")).toBeInTheDocument();
6363
});
6464

65+
describe("when webComponent state is true", () => {
66+
beforeEach(() => {
67+
initialState.editor.webComponent = true;
68+
store = mockStore(initialState);
69+
});
70+
71+
test("does not show run bar", () => {
72+
render(
73+
<Provider store={store}>
74+
<MemoryRouter>
75+
<Output />
76+
</MemoryRouter>
77+
</Provider>,
78+
);
79+
expect(screen.queryByText("runButton.run")).not.toBeInTheDocument();
80+
});
81+
});
82+
6583
describe("when browserPreview property is true", () => {
6684
test("does not show run bar", () => {
6785
render(

src/components/WebComponentProject/WebComponentProject.jsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,8 @@ const WebComponentProject = ({
4444
const [codeHasRun, setCodeHasRun] = useState(codeHasBeenRun);
4545
const dispatch = useDispatch();
4646

47-
useEffect(() => {
48-
dispatch(setIsSplitView(false));
49-
dispatch(setWebComponent(true));
50-
}, [dispatch]);
47+
dispatch(setIsSplitView(false));
48+
dispatch(setWebComponent(true));
5149

5250
useEffect(() => {
5351
setCodeHasRun(false);

src/web-component.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import store from "./redux/stores/WebComponentStore";
88
import { Provider } from "react-redux";
99
import "./utils/i18n";
1010
import camelCase from "camelcase";
11+
import { stopCodeRun, stopDraw, triggerCodeRun } from "./redux/EditorSlice";
1112

1213
Sentry.init({
1314
dsn: process.env.REACT_APP_SENTRY_DSN,
@@ -101,6 +102,34 @@ class WebComponent extends HTMLElement {
101102
this.mountReactApp();
102103
}
103104

105+
stopCode() {
106+
const state = store.getState();
107+
if (state.editor.codeRunTriggered || state.editor.drawTriggered) {
108+
store.dispatch(stopCodeRun());
109+
store.dispatch(stopDraw());
110+
}
111+
}
112+
113+
runCode() {
114+
store.dispatch(triggerCodeRun());
115+
}
116+
117+
rerunCode() {
118+
this.stopCode();
119+
120+
new Promise((resolve) => {
121+
let checkInterval = setInterval(() => {
122+
let state = store.getState();
123+
if (!state.codeRunTriggered && !state.drawTriggered) {
124+
clearInterval(checkInterval);
125+
resolve();
126+
}
127+
}, 50);
128+
}).then(() => {
129+
this.runCode();
130+
});
131+
}
132+
104133
reactProps() {
105134
return {
106135
...this.componentAttributes,

0 commit comments

Comments
 (0)