diff --git a/packages/scratch-gui/src/lib/make-toolbox-xml.js b/packages/scratch-gui/src/lib/make-toolbox-xml.js index 90346b8b03..ed86d2cc6e 100644 --- a/packages/scratch-gui/src/lib/make-toolbox-xml.js +++ b/packages/scratch-gui/src/lib/make-toolbox-xml.js @@ -5,7 +5,7 @@ const categorySeparator = ''; const blockSeparator = ''; // At default scale, about 28px - + const motion = function (isInitialSetup, isStage, targetId, colors) { const stageSelected = ScratchBlocks.ScratchMsgs.translate( 'MOTION_STAGE_SELECTED', @@ -513,6 +513,7 @@ const sensing = function (isInitialSetup, isStage, targetId, colors) { ${blockSeparator} + ${categorySeparator} @@ -736,7 +737,7 @@ const myBlocks = function (isInitialSetup, isStage, targetId, colors) { `; }; - + const xmlOpen = ''; const xmlClose = ''; diff --git a/packages/scratch-gui/src/lib/opcode-labels.js b/packages/scratch-gui/src/lib/opcode-labels.js index 22bff608af..9fd9f2240f 100644 --- a/packages/scratch-gui/src/lib/opcode-labels.js +++ b/packages/scratch-gui/src/lib/opcode-labels.js @@ -68,6 +68,11 @@ const messages = defineMessages({ description: 'Label for the loudness monitor when shown on the stage', id: 'gui.opcodeLabels.loudness' }, + sensing_online: { + defaultMessage: 'online', + description: 'Label for the online status monitor when shown on the stage', + id: 'gui.opcodeLabels.online' + }, sensing_username: { defaultMessage: 'username', description: 'Label for the username monitor when shown on the stage', @@ -152,6 +157,7 @@ class OpcodeLabels { // Sensing sensing_answer: {category: 'sensing'}, sensing_loudness: {category: 'sensing'}, + sensing_online: {category: 'sensing'}, sensing_username: {category: 'sensing'}, sensing_current: {category: 'sensing'}, sensing_timer: {category: 'sensing'} @@ -208,6 +214,7 @@ class OpcodeLabels { // Sensing this._opcodeMap.sensing_answer.labelFn = () => this._translator(messages.sensing_answer); this._opcodeMap.sensing_loudness.labelFn = () => this._translator(messages.sensing_loudness); + this._opcodeMap.sensing_online.labelFn = () => this._translator(messages.sensing_online); this._opcodeMap.sensing_username.labelFn = () => this._translator(messages.sensing_username); this._opcodeMap.sensing_current.labelFn = params => { switch (params.CURRENTMENU.toLowerCase()) { diff --git a/packages/scratch-vm/src/blocks/scratch3_sensing.js b/packages/scratch-vm/src/blocks/scratch3_sensing.js index 3d1ddbf4dd..cddf3ce4f5 100644 --- a/packages/scratch-vm/src/blocks/scratch3_sensing.js +++ b/packages/scratch-vm/src/blocks/scratch3_sensing.js @@ -71,6 +71,7 @@ class Scratch3SensingBlocks { sensing_loud: this.isLoud, sensing_askandwait: this.askAndWait, sensing_answer: this.getAnswer, + sensing_online: this.getOnline, sensing_username: this.getUsername, sensing_userid: () => {} // legacy no-op block }; @@ -84,6 +85,9 @@ class Scratch3SensingBlocks { sensing_loudness: { getId: () => 'loudness' }, + sensing_online: { + getId: () => 'online' + }, sensing_timer: { getId: () => 'timer' }, @@ -328,6 +332,16 @@ class Scratch3SensingBlocks { return 0; } + getOnline (args, util) { + const status = window.navigator.onLine; + if (typeof status === 'boolean') { + return status; + } + // an empty string will evaluate as false in a Boolean context, + // but it allows distinguishing between "false" and "unknown" if needed + return ''; + } + getUsername (args, util) { return util.ioQuery('userData', 'getUsername'); }