Skip to content

Commit a5de448

Browse files
Merge remote-tracking branch 'origin/develop' into UEPR-230
2 parents 8113d9c + 9fb0e54 commit a5de448

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+5593
-2693
lines changed

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20.19.0
1+
20.19.2

package-lock.json

Lines changed: 4621 additions & 2392 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "scratch-editor",
3-
"version": "11.1.0",
3+
"version": "11.2.0-feature-parity.2",
44
"private": "true",
55
"description": "Scratch editor mono-repository",
66
"author": "Scratch Foundation",

packages/scratch-gui/.npmignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
npm-*
77

88
# Double copies of all the static assets and tutorial gifs
9-
/src
9+
# /src
1010

1111
# Testing
1212
/.nyc_output

packages/scratch-gui/.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20.19.0
1+
20.19.2

packages/scratch-gui/package.json

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@scratch/scratch-gui",
3-
"version": "11.1.0",
3+
"version": "11.2.0-feature-parity.2",
44
"description": "Graphical User Interface for creating and running Scratch 3.0 projects",
55
"author": "Massachusetts Institute of Technology",
66
"license": "AGPL-3.0-only",
@@ -16,6 +16,18 @@
1616
"types": "./dist/types/index.d.ts",
1717
"default": "./dist/scratch-gui.js"
1818
},
19+
"./costumes": {
20+
"default": "./src/lib/libraries/costumes.json"
21+
},
22+
"./sprites": {
23+
"default": "./src/lib/libraries/sprites.json"
24+
},
25+
"./sounds": {
26+
"default": "./src/lib/libraries/sounds.json"
27+
},
28+
"./backdrops": {
29+
"default": "./src/lib/libraries/backdrops.json"
30+
},
1931
"./standalone": {
2032
"types": "./dist/types/index-standalone.d.ts",
2133
"default": "./dist/scratch-gui-standalone.js"
@@ -43,9 +55,9 @@
4355
},
4456
"dependencies": {
4557
"@microbit/microbit-universal-hex": "0.2.2",
46-
"@scratch/scratch-render": "11.1.0",
47-
"@scratch/scratch-svg-renderer": "11.1.0",
48-
"@scratch/scratch-vm": "11.1.0",
58+
"@scratch/scratch-render": "11.2.0-feature-parity.2",
59+
"@scratch/scratch-svg-renderer": "11.2.0-feature-parity.2",
60+
"@scratch/scratch-vm": "11.2.0-feature-parity.2",
4961
"arraybuffer-loader": "1.0.8",
5062
"autoprefixer": "9.8.8",
5163
"balance-text": "3.3.1",
@@ -92,16 +104,18 @@
92104
"react-tabs": "2.3.1",
93105
"react-tooltip": "4.5.1",
94106
"react-virtualized": "9.22.6",
107+
"react-visibility-sensor": "5.1.1",
95108
"redux-throttle": "0.1.1",
96-
"scratch-audio": "2.0.119",
97-
"scratch-blocks": "1.1.209",
98-
"scratch-l10n": "5.0.198",
99-
"scratch-paint": "3.0.207",
100-
"scratch-render-fonts": "1.0.182",
101-
"scratch-storage": "4.0.106",
109+
"scratch-audio": "2.0.147",
110+
"scratch-blocks": "1.1.210",
111+
"scratch-l10n": "5.0.247",
112+
"scratch-paint": "3.0.260",
113+
"scratch-render-fonts": "1.0.195",
114+
"scratch-storage": "4.0.142",
102115
"startaudiocontext": "1.2.1",
103116
"style-loader": "4.0.0",
104117
"to-style": "1.3.3",
118+
"text-encoding": "0.7.0",
105119
"wav-encoder": "1.3.0",
106120
"xhr": "2.6.0"
107121
},
@@ -112,14 +126,14 @@
112126
"redux": "^3.7.2"
113127
},
114128
"devDependencies": {
115-
"@babel/cli": "7.27.0",
116-
"@babel/core": "7.26.10",
117-
"@babel/eslint-parser": "7.27.0",
129+
"@babel/cli": "7.27.2",
130+
"@babel/core": "7.27.1",
131+
"@babel/eslint-parser": "7.27.1",
118132
"@babel/plugin-proposal-object-rest-spread": "7.20.7",
119133
"@babel/plugin-syntax-dynamic-import": "7.8.3",
120-
"@babel/plugin-transform-async-to-generator": "7.25.9",
121-
"@babel/preset-env": "7.26.9",
122-
"@babel/preset-react": "7.26.3",
134+
"@babel/plugin-transform-async-to-generator": "7.27.1",
135+
"@babel/preset-env": "7.27.2",
136+
"@babel/preset-react": "7.27.1",
123137
"@types/prop-types": "15.7.14",
124138
"@types/react-modal": "3.16.3",
125139
"@typescript-eslint/eslint-plugin": "8.7.0",
@@ -141,9 +155,8 @@
141155
"html-webpack-plugin": "5.6.3",
142156
"jest": "21.2.1",
143157
"jest-junit": "7.0.0",
158+
"mkdirp": "1.0.4",
144159
"raf": "3.4.1",
145-
"react": "16.14.0",
146-
"react-dom": "16.14.0",
147160
"react-test-renderer": "16.14.0",
148161
"redux-mock-store": "1.5.5",
149162
"rimraf": "2.7.1",
@@ -156,7 +169,7 @@
156169
"ts-loader": "9.5.2",
157170
"url-loader": "4.1.1",
158171
"web-audio-test-api": "0.5.2",
159-
"webpack": "5.98.0",
172+
"webpack": "5.99.8",
160173
"webpack-cli": "5.1.4",
161174
"webpack-dev-server": "5.2.1",
162175
"yauzl": "2.10.0"

packages/scratch-gui/src/components/cards/cards.jsx

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -149,20 +149,19 @@ VideoStep.propTypes = {
149149
video: PropTypes.string.isRequired
150150
};
151151

152-
const ImageStep = ({title, image}) => (
153-
<Fragment>
154-
<div className={styles.stepTitle}>
155-
{title}
156-
</div>
157-
<div className={styles.stepImageContainer}>
158-
<img
159-
className={styles.stepImage}
160-
draggable={false}
161-
key={image} /* Use src as key to prevent hanging around on slow connections */
162-
src={image}
163-
/>
164-
</div>
165-
</Fragment>
152+
const ImageStep = ({title, image}) => (<Fragment>
153+
<div className={styles.stepTitle}>
154+
{title}
155+
</div>
156+
<div className={styles.stepImageContainer}>
157+
<img
158+
className={styles.stepImage}
159+
draggable={false}
160+
key={image} /* Use src as key to prevent hanging around on slow connections */
161+
src={image}
162+
/>
163+
</div>
164+
</Fragment>
166165
);
167166

168167
ImageStep.propTypes = {
@@ -292,9 +291,9 @@ const Cards = props => {
292291
onShowAll,
293292
onNextStep,
294293
onPrevStep,
295-
showVideos,
296294
step,
297295
expanded,
296+
showVideos,
298297
...posProps
299298
} = props;
300299
let {x, y} = posProps;
@@ -361,18 +360,19 @@ const Cards = props => {
361360
/>
362361
) : (
363362
steps[step].video ? (
364-
showVideos ? (
365-
<VideoStep
366-
dragging={dragging}
367-
expanded={expanded}
368-
video={translateVideo(steps[step].video, locale)}
369-
/>
370-
) : ( // Else show the deck image and title
371-
<ImageStep
372-
image={content[activeDeckId].img}
373-
title={content[activeDeckId].name}
374-
/>
375-
)
363+
showVideos ?
364+
(
365+
<VideoStep
366+
dragging={dragging}
367+
expanded={expanded}
368+
video={translateVideo(steps[step].video, locale)}
369+
/>
370+
) : (
371+
<ImageStep
372+
image={content[activeDeckId].img}
373+
title={content[activeDeckId].name}
374+
/>
375+
)
376376
) : (
377377
<ImageStep
378378
image={translateImage(steps[step].image, locale)}
@@ -428,10 +428,6 @@ Cards.propTypes = {
428428
y: PropTypes.number
429429
};
430430

431-
Cards.defaultProps = {
432-
showVideos: true
433-
};
434-
435431
export {
436432
Cards as default,
437433
// Others exported for testability

packages/scratch-gui/src/components/connection-modal/auto-scanning-step.jsx

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ const PHASES = keyMirror({
2424
notfound: null
2525
});
2626

27+
const defaultPrescanMessage = (<FormattedMessage
28+
defaultMessage="Have your device nearby, then begin searching."
29+
description="Prompt for beginning the search"
30+
id="gui.connection.auto-scanning.prescan"
31+
/>);
32+
33+
const defaultScanBeginMessage = (<FormattedMessage
34+
defaultMessage="Press the button on your device."
35+
description="Prompt for pushing the button on the device"
36+
id="gui.connection.auto-scanning.scanBeginMessage"
37+
/>);
38+
2739
const AutoScanningStep = props => {
2840
// Offer to update both during scan and after a failed scan, as long there's an update function.
2941
// It's possible the scan will find "some" device but not the desired device,
@@ -35,16 +47,23 @@ const AutoScanningStep = props => {
3547
<div className={styles.activityAreaInfo}>
3648
<div className={styles.centeredRow}>
3749
{props.phase === PHASES.prescan && (
38-
<React.Fragment>
50+
props.connectionIconURL ? (
3951
<img
4052
className={styles.radarBig}
41-
src={radarIcon}
53+
src={props.connectionIconURL}
4254
/>
43-
<img
44-
className={styles.bluetoothCenteredIcon}
45-
src={bluetoothIcon}
46-
/>
47-
</React.Fragment>
55+
) : (
56+
<React.Fragment>
57+
<img
58+
className={styles.radarBig}
59+
src={radarIcon}
60+
/>
61+
<img
62+
className={styles.bluetoothCenteredIcon}
63+
src={bluetoothIcon}
64+
/>
65+
</React.Fragment>
66+
)
4867
)}
4968
{props.phase === PHASES.pressbutton && (
5069
<React.Fragment>
@@ -77,20 +96,8 @@ const AutoScanningStep = props => {
7796
</Box>
7897
<Box className={styles.bottomArea}>
7998
<Box className={classNames(styles.bottomAreaItem, styles.instructions)}>
80-
{props.phase === PHASES.prescan && (
81-
<FormattedMessage
82-
defaultMessage="Have your device nearby, then begin searching."
83-
description="Prompt for beginning the search"
84-
id="gui.connection.auto-scanning.prescan"
85-
/>
86-
)}
87-
{props.phase === PHASES.pressbutton && (
88-
<FormattedMessage
89-
defaultMessage="Press the button on your device."
90-
description="Prompt for pushing the button on the device"
91-
id="gui.connection.auto-scanning.pressbutton"
92-
/>
93-
)}
99+
{props.phase === PHASES.prescan && props.prescanMessage}
100+
{props.phase === PHASES.pressbutton && props.scanBeginMessage}
94101
</Box>
95102
{showUpdate && (
96103
<Box className={classNames(styles.bottomAreaItem, styles.instructions)}>
@@ -180,15 +187,20 @@ const AutoScanningStep = props => {
180187
};
181188

182189
AutoScanningStep.propTypes = {
190+
connectionIconURL: PropTypes.string,
183191
connectionTipIconURL: PropTypes.string,
184192
onRefresh: PropTypes.func,
185193
onStartScan: PropTypes.func,
186194
onUpdatePeripheral: PropTypes.func,
187-
phase: PropTypes.oneOf(Object.keys(PHASES))
195+
phase: PropTypes.oneOf(Object.keys(PHASES)),
196+
prescanMessage: PropTypes.node,
197+
scanBeginMessage: PropTypes.node
188198
};
189199

190200
AutoScanningStep.defaultProps = {
191-
phase: PHASES.prescan
201+
phase: PHASES.prescan,
202+
prescanMessage: defaultPrescanMessage,
203+
scanBeginMessage: defaultScanBeginMessage
192204
};
193205

194206
export {

packages/scratch-gui/src/components/connection-modal/connection-modal.jsx

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,23 @@ const PHASES = keyMirror({
2424
updatePeripheral: null
2525
});
2626

27-
const ConnectionModalComponent = props => (
28-
<Modal
27+
const ConnectionModalComponent = props => {
28+
// ScanningStep allows the user to choose a peripheral from a list.
29+
// AutoScanningStep connects to the first peripheral found.
30+
// Also, AutoScanningStep adds "prescan" and "pressbutton" phases before the actual scan.
31+
// When useExternalPeripheralList is true, force the use of AutoScanningStep:
32+
// - We want to automatically connect to the first peripheral "found" since it's actually the one selected by the
33+
// user from the external list.
34+
// - We want to show the "prescan" phase to inform the user before the external list appears.
35+
// - The "pressbutton" phase doesn't hurt: it might be hidden behind the external list (especially with Android
36+
// CDM) or it might help the user to keep the peripheral device awake.
37+
// TODO: does forcing AutoScanningStep mean we can eliminate the `USER_PICKED_PERIPHERAL` message?
38+
const ScanningStepContainer = (
39+
(props.useAutoScan || props.useExternalPeripheralList) ?
40+
AutoScanningStep :
41+
ScanningStep
42+
);
43+
return (<Modal
2944
className={styles.modalContent}
3045
contentLabel={props.name}
3146
headerClassName={styles.header}
@@ -35,27 +50,30 @@ const ConnectionModalComponent = props => (
3550
onRequestClose={props.onCancel}
3651
>
3752
<Box className={styles.body}>
38-
{props.phase === PHASES.scanning && !props.useAutoScan && <ScanningStep {...props} />}
39-
{props.phase === PHASES.scanning && props.useAutoScan && <AutoScanningStep {...props} />}
53+
{props.phase === PHASES.scanning && <ScanningStepContainer {...props} />}
4054
{props.phase === PHASES.connecting && <ConnectingStep {...props} />}
4155
{props.phase === PHASES.connected && <ConnectedStep {...props} />}
4256
{props.phase === PHASES.error && <ErrorStep {...props} />}
4357
{props.phase === PHASES.unavailable && <UnavailableStep {...props} />}
4458
{props.phase === PHASES.updatePeripheral && <UpdatePeripheralStep {...props} />}
4559
</Box>
46-
</Modal>
47-
);
60+
</Modal>);
61+
};
4862

4963
ConnectionModalComponent.propTypes = {
5064
connectingMessage: PropTypes.node.isRequired,
65+
connectionIconURL: PropTypes.string,
5166
connectionSmallIconURL: PropTypes.string,
5267
connectionTipIconURL: PropTypes.string,
5368
name: PropTypes.node,
5469
onCancel: PropTypes.func.isRequired,
5570
onHelp: PropTypes.func.isRequired,
5671
phase: PropTypes.oneOf(Object.keys(PHASES)).isRequired,
72+
prescanMessage: PropTypes.node,
73+
scanBeginMessage: PropTypes.node,
5774
title: PropTypes.string.isRequired,
58-
useAutoScan: PropTypes.bool.isRequired
75+
useAutoScan: PropTypes.bool.isRequired,
76+
useExternalPeripheralList: PropTypes.bool
5977
};
6078

6179
ConnectionModalComponent.defaultProps = {

packages/scratch-gui/src/components/debug-modal/debug-modal.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
left: 0;
77
right: 0;
88
bottom: 0;
9-
background-color: 'transparent';
9+
background-color: transparent;
1010
display: flex;
1111
justify-content: center;
1212
align-items: center;

0 commit comments

Comments
 (0)