Skip to content

Commit 437915e

Browse files
committed
Merge branch 'UEPR-282-face-sensing' of github.com:scratchfoundation/scratch-editor into UEPR-56-UEPR-282
2 parents bf1f3ba + 257dc82 commit 437915e

File tree

21 files changed

+1092
-9
lines changed

21 files changed

+1092
-9
lines changed

package-lock.json

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

packages/scratch-gui/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,15 @@
5757
"watch": "webpack --watch"
5858
},
5959
"dependencies": {
60+
"@mediapipe/face_detection": "0.4.1646425229",
6061
"@microbit/microbit-universal-hex": "0.2.2",
6162
"@radix-ui/react-context-menu": "^2.2.5",
6263
"@testing-library/user-event": "^14.6.1",
6364
"@scratch/scratch-render": "11.6.0",
6465
"@scratch/scratch-svg-renderer": "11.6.0",
6566
"@scratch/scratch-vm": "11.6.0",
67+
"@tensorflow-models/face-detection": "^1.0.3",
68+
"@tensorflow/tfjs": "^4.22.0",
6669
"arraybuffer-loader": "1.0.8",
6770
"autoprefixer": "9.8.8",
6871
"balance-text": "3.3.1",

packages/scratch-gui/src/containers/blocks.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ class Blocks extends React.Component {
144144
if (this.props.isVisible) {
145145
this.setLocale();
146146
}
147+
148+
window.addEventListener('load-extension', () => {
149+
this.props.vm.extensionManager.loadExtensionURL('faceSensing').then(() => {
150+
this.handleCategorySelected('faceSensing');
151+
});
152+
});
147153
}
148154
shouldComponentUpdate (nextProps, nextState) {
149155
return (

packages/scratch-gui/src/containers/stage.jsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,16 +340,29 @@ class Stage extends React.Component {
340340
}
341341
onStartDrag (x, y) {
342342
if (this.state.dragId) return;
343-
const drawableId = this.renderer.pick(x, y);
343+
344+
// Targets with no attached drawable cannot be dragged.
345+
let draggableTargets = this.props.vm.runtime.targets.filter(
346+
target => Number.isFinite(target.drawableID)
347+
);
348+
349+
// Because pick queries can be expensive, only perform them for drawables that are currently draggable.
350+
// If we're in the editor, we can drag all targets. Otherwise, filter.
351+
if (!this.props.useEditorDragStyle) {
352+
draggableTargets = draggableTargets.filter(
353+
target => target.draggable
354+
);
355+
}
356+
if (draggableTargets.length === 0) return;
357+
358+
const draggableIDs = draggableTargets.map(target => target.drawableID);
359+
const drawableId = this.renderer.pick(x, y, 1, 1, draggableIDs);
344360
if (drawableId === null) return;
345361
const targetId = this.props.vm.getTargetIdForDrawableId(drawableId);
346362
if (targetId === null) return;
347363

348364
const target = this.props.vm.runtime.getTargetById(targetId);
349365

350-
// Do not start drag unless in editor drag mode or target is draggable
351-
if (!(this.props.useEditorDragStyle || target.draggable)) return;
352-
353366
// Dragging always brings the target to the front
354367
target.goToFront();
355368

packages/scratch-gui/src/lib/alerts/index.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,20 @@ const alerts = [
215215
),
216216
iconSpinner: true,
217217
level: AlertLevels.SUCCESS
218+
},
219+
{
220+
alertId: 'loadingExtensionData',
221+
alertType: AlertTypes.STANDARD,
222+
clearList: [],
223+
content: (
224+
<FormattedMessage
225+
defaultMessage="Loading extension..."
226+
description="Message indicating that extension is in process of loading"
227+
id="gui.alerts.loadingExtensionData"
228+
/>
229+
),
230+
iconSpinner: true,
231+
level: AlertLevels.SUCCESS
218232
}
219233
];
220234

packages/scratch-gui/src/lib/cloud-manager-hoc.jsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ const cloudManagerHOC = function (WrappedComponent) {
101101
handleExtensionAdded (categoryInfo) {
102102
// Note that props.vm.extensionManager.isExtensionLoaded('videoSensing') is still false
103103
// at the point of this callback, so it is difficult to reuse the canModifyCloudData logic.
104-
if (categoryInfo.id === 'videoSensing' && this.isConnected()) {
104+
if (
105+
(categoryInfo.id === 'videoSensing' ||
106+
categoryInfo.id === 'faceSensing') &&
107+
this.isConnected()
108+
) {
105109
this.disconnectFromCloud();
106110
}
107111
}
@@ -157,9 +161,18 @@ const cloudManagerHOC = function (WrappedComponent) {
157161
isShowingWithId: getIsShowingWithId(loadingState),
158162
projectId: state.scratchGui.projectState.projectId,
159163
// if you're editing someone else's project, you can't modify cloud data
160-
canModifyCloudData: (!state.scratchGui.mode.hasEverEnteredEditor || ownProps.canSave) &&
164+
canModifyCloudData:
165+
(!state.scratchGui.mode.hasEverEnteredEditor ||
166+
ownProps.canSave) &&
161167
// possible security concern if the program attempts to encode webcam data over cloud variables
162-
!ownProps.vm.extensionManager.isExtensionLoaded('videoSensing')
168+
!(
169+
ownProps.vm.extensionManager.isExtensionLoaded(
170+
'videoSensing'
171+
) ||
172+
ownProps.vm.extensionManager.isExtensionLoaded(
173+
'faceSensing'
174+
)
175+
)
163176
};
164177
};
165178

Lines changed: 1 addition & 0 deletions
Loading
27.7 KB
Loading

packages/scratch-gui/src/lib/libraries/extensions/index.jsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ import gdxforInsetIconURL from './gdxfor/gdxfor-small.svg';
4646
import gdxforConnectionIconURL from './gdxfor/gdxfor-illustration.svg';
4747
import gdxforConnectionSmallIconURL from './gdxfor/gdxfor-small.svg';
4848

49+
import faceSensingIconURL from './faceSensing/faceSensing.png';
50+
import faceSensingInsetIconURL from './faceSensing/faceSensing-small.svg';
51+
4952
export default [
5053
{
5154
name: (
@@ -107,6 +110,26 @@ export default [
107110
),
108111
featured: true
109112
},
113+
{
114+
name: (
115+
<FormattedMessage
116+
defaultMessage="Face Sensing"
117+
description="Name for the 'Face Sensing' extension"
118+
id="gui.extension.faceSensing.name"
119+
/>
120+
),
121+
extensionId: 'faceSensing',
122+
iconURL: faceSensingIconURL,
123+
insetIconURL: faceSensingInsetIconURL,
124+
description: (
125+
<FormattedMessage
126+
defaultMessage="Sense faces with the camera."
127+
description="Description for the 'Face Sensing' extension"
128+
id="gui.extension.faceSensing.description"
129+
/>
130+
),
131+
featured: true
132+
},
110133
{
111134
name: (
112135
<FormattedMessage
Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)