Skip to content

Commit 86768ff

Browse files
authored
Renamed Tutorial Validation Variables, Toggle Validation Message, and Render Blocks in Validation Message (microsoft#8235)
* renamed variables and fixing merge * lint * rendered blocks * shorten rules * small nits
1 parent 2874037 commit 86768ff

4 files changed

Lines changed: 41 additions & 39 deletions

File tree

pxtlib/tutorialValidator.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ namespace pxt.tutorial {
3737
const isRuleEnabled = TutorialRuleStatuses[i].ruleTurnOn;
3838
if (isRuleEnabled) {
3939
switch (ruleName) {
40-
case "validateExactNumberOfBlocks":
40+
case "exact":
4141
currRuleToValidate = validateExactNumberOfBlocks(usersBlockUsed, tutorialBlockUsed, currRuleToValidate);
4242
break;
43-
case "validateAtleastOneBlocks":
43+
case "atleastone":
4444
currRuleToValidate = validateAtleastOneBlocks(usersBlockUsed, tutorialBlockUsed, currRuleToValidate);
4545
break;
46-
case "validateMeetRequiredBlocks":
46+
case "required":
4747
const requiredBlocksList = extractRequiredBlockSnippet(tutorial, indexdb);
4848
currRuleToValidate = validateMeetRequiredBlocks(usersBlockUsed, requiredBlocksList, currRuleToValidate);
4949
break;
@@ -167,18 +167,15 @@ namespace pxt.tutorial {
167167
tutorialBlockKeys = Object.keys(tutorialBlockUsed);
168168
}
169169
let isValid = userBlockKeys.length >= tutorialBlockKeys.length; // user has enough blocks
170-
let sArr: string[] = [];
171-
sArr[0] = lf("These are the blocks you seem to be missing:");
170+
const message = lf("These are the blocks you seem to be missing:");
172171
for (let i: number = 0; i < tutorialBlockKeys.length; i++) {
173172
let tutorialBlockKey = tutorialBlockKeys[i];
174173
if (!usersBlockUsed[tutorialBlockKey] // user did not use a specific block or
175174
|| usersBlockUsed[tutorialBlockKey] < tutorialBlockUsed[tutorialBlockKey]) { // user did not use enough of a certain block
176-
sArr.push("- " + tutorialBlockKey);
177175
blockIds.push(tutorialBlockKey);
178176
isValid = false;
179177
}
180178
}
181-
const message: string = sArr.join('\n');
182179
currRule.ruleMessage = message;
183180
currRule.ruleStatus = isValid;
184181
currRule.blockIds = blockIds;
@@ -218,22 +215,22 @@ namespace pxt.tutorial {
218215
currRule.isStrict = true;
219216
const userBlockKeys = Object.keys(usersBlockUsed);
220217
let requiredBlockKeys: string[] = []
218+
let blockIds = [];
221219
if (requiredBlocks != undefined) {
222220
requiredBlockKeys = Object.keys(requiredBlocks);
223221
}
224222
let isValid: boolean = true;
225-
let sArr: string[] = [];
226-
sArr[0] = lf("You are required to have the following block:");
223+
const message = lf("You are required to have the following block:");
227224
for (let i: number = 0; i < requiredBlockKeys.length; i++) {
228225
let requiredBlockKey = requiredBlockKeys[i];
229226
if (!usersBlockUsed[requiredBlockKey]) {
230-
sArr.push("- " + requiredBlockKey);
227+
blockIds.push(requiredBlockKey);
231228
isValid = false;
232229
}
233230
}
234-
const message: string = sArr.join('\n');
235231
currRule.ruleMessage = message;
236232
currRule.ruleStatus = isValid;
233+
currRule.blockIds = blockIds;
237234
return currRule;
238235
}
239236
}

theme/tutorialCodeValidation.less

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,3 @@
6969
font-size: small;
7070
white-space: pre-line;
7171
}
72-

webapp/src/tutorial.tsx

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ export class TutorialHint extends data.Component<ISettingsProps, TutorialHintSta
359359
interface TutorialCardState {
360360
showHint?: boolean;
361361
showSeeMore?: boolean;
362-
showUnusedBlockMessage?: boolean;
362+
showTutorialValidationMessage?: boolean;
363363
}
364364

365365
interface TutorialCardProps extends ISettingsProps {
@@ -381,7 +381,7 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
381381
this.state = {
382382
showSeeMore: false,
383383
showHint: options.tutorialStepInfo[this.prevStep].showHint,
384-
showUnusedBlockMessage: false
384+
showTutorialValidationMessage: false
385385
}
386386

387387
this.toggleHint = this.toggleHint.bind(this);
@@ -396,8 +396,8 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
396396
this.toggleExpanded = this.toggleExpanded.bind(this);
397397
this.onMarkdownDidRender = this.onMarkdownDidRender.bind(this);
398398
this.handleResize = this.handleResize.bind(this);
399-
this.showUnusedBlocksMessageOnClick = this.showUnusedBlocksMessageOnClick.bind(this);
400-
this.showUnusedBlocksMessage = this.showUnusedBlocksMessage.bind(this);
399+
this.showTutorialValidationMessageOnClick = this.showTutorialValidationMessageOnClick.bind(this);
400+
this.closeTutorialValidationMessage = this.closeTutorialValidationMessage.bind(this);
401401
this.doubleClickedNextStep = this.doubleClickedNextStep.bind(this);
402402
this.validationTelemetry = this.validationTelemetry.bind(this);
403403
}
@@ -412,7 +412,7 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
412412

413413
pxt.tickEvent(`tutorial.previous`, { tutorial: options.tutorial, step: previousStep }, { interactiveConsent: true });
414414
this.props.parent.setTutorialStep(previousStep);
415-
this.setState({ showUnusedBlockMessage: false });
415+
this.setState({ showTutorialValidationMessage: false });
416416
}
417417

418418
nextTutorialStep() {
@@ -427,8 +427,8 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
427427
this.props.parent.setTutorialStep(nextStep);
428428

429429
const tutorialCodeValidationIsOn = options.metadata.tutorialCodeValidation;
430-
if (tutorialCodeValidationIsOn && this.state.showUnusedBlockMessage) { // disables tutorial validation pop-up if next buttion is clicked
431-
this.setState({ showUnusedBlockMessage: false });
430+
if (tutorialCodeValidationIsOn && this.state.showTutorialValidationMessage) { // disables tutorial validation pop-up if next buttion is clicked
431+
this.setState({ showTutorialValidationMessage: false });
432432
}
433433
}
434434

@@ -571,8 +571,8 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
571571
}
572572
}
573573

574-
private showUnusedBlocksMessageOnClick(evt?: any) {
575-
this.setState({ showUnusedBlockMessage: true });
574+
private showTutorialValidationMessageOnClick(evt?: any) {
575+
this.setState({ showTutorialValidationMessage: true });
576576
}
577577

578578
private expandedHintOnClick(evt?: any) {
@@ -635,12 +635,12 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
635635
}
636636
th.showHint(visible, showFullText);
637637
if (visible) {
638-
this.setState({ showUnusedBlockMessage: false });
638+
this.setState({ showTutorialValidationMessage: false });
639639
}
640640
}
641641

642-
showUnusedBlocksMessage() {
643-
this.setState({ showUnusedBlockMessage: false });
642+
closeTutorialValidationMessage() {
643+
this.setState({ showTutorialValidationMessage: false });
644644
}
645645

646646
isCodeValidated(rules: pxt.tutorial.TutorialRuleStatus[]) {
@@ -697,10 +697,10 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
697697
const showDialog = stepInfo.showDialog;
698698
const validationEnabled = (stepInfo.listOfValidationRules != undefined);
699699
const tutorialCodeValidated = this.isCodeValidated(stepInfo.listOfValidationRules);
700-
const showMissingBlockPopupMessage = this.state.showUnusedBlockMessage && validationEnabled;
700+
const showTutorialValidationMessage = this.state.showTutorialValidationMessage && validationEnabled;
701701
const strictRulePresent = this.areStrictRulesPresent(stepInfo.listOfValidationRules);
702702
const nextOnClick = (!validationEnabled || !strictRulePresent || (tutorialCodeValidated && strictRulePresent)) ? this.nextTutorialStep :
703-
(this.state.showUnusedBlockMessage) ? this.doubleClickedNextStep : this.showUnusedBlocksMessageOnClick;
703+
(this.state.showTutorialValidationMessage) ? this.doubleClickedNextStep : this.showTutorialValidationMessageOnClick;
704704

705705
const tutorialAriaLabel = lf("Press Space or Enter to show a hint.");
706706
const tutorialHintTooltip = lf("Click to show a hint!");
@@ -715,7 +715,6 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
715715
const isRtl = pxt.Util.isUserLanguageRtl();
716716
return <div id="tutorialcard" className={`ui ${tutorialStepExpanded ? 'tutorialExpanded' : ''} ${tutorialReady ? 'tutorialReady' : ''} ${this.state.showSeeMore ? 'seemore' : ''} ${!this.state.showHint ? 'showTooltip' : ''} ${hasHint ? 'hasHint' : ''}`} style={tutorialStepExpanded ? this.getExpandedCardStyle('height') : null} >
717717
{hasHint && this.state.showHint && !showDialog && <div className="mask" role="region" onClick={this.closeHint}></div>}
718-
719718
<div className='ui buttons'>
720719
{hasPrevious ? <sui.Button icon={`${isRtl ? 'right' : 'left'} chevron large`} className={`prevbutton left attached ${!hasPrevious ? 'disabled' : ''}`} text={lf("Back")} textClass="widedesktop only" ariaLabel={lf("Go to the previous step of the tutorial.")} onClick={this.previousTutorialStep} onKeyDown={sui.fireClickOnEnter} /> : undefined}
721720
<div className="ui segment attached tutorialsegment">
@@ -740,8 +739,8 @@ export class TutorialCard extends data.Component<TutorialCardProps, TutorialCard
740739
</div>
741740
{hasNext ? <sui.Button icon={`${isRtl ? 'left' : 'right'} chevron large`} className={`nextbutton right attached ${!hasNext ? 'disabled' : ''} ${tutorialCodeValidated ? 'isValidated' : ''}`} text={lf("Next")} textClass="widedesktop only" ariaLabel={lf("Go to the next step of the tutorial.")}
742741
onClick={nextOnClick} onKeyDown={sui.fireClickOnEnter} /> : undefined}
743-
{showMissingBlockPopupMessage &&
744-
<TutorialCodeValidation.ShowValidationMessage onYesButtonClick={this.nextTutorialStep} onNoButtonClick={this.showUnusedBlocksMessage} initialVisible={this.state.showUnusedBlockMessage} isTutorialCodeInvalid={!tutorialCodeValidated} ruleComponents={stepInfo.listOfValidationRules} areStrictRulesPresent={strictRulePresent} validationTelemetry={this.validationTelemetry} parent={this.props.parent} />}
742+
{showTutorialValidationMessage &&
743+
<TutorialCodeValidation.ShowValidationMessage onYesButtonClick={this.nextTutorialStep} onNoButtonClick={this.closeTutorialValidationMessage} initialVisible={this.state.showTutorialValidationMessage} isTutorialCodeInvalid={!tutorialCodeValidated} ruleComponents={stepInfo.listOfValidationRules} areStrictRulesPresent={strictRulePresent} validationTelemetry={this.validationTelemetry} parent={this.props.parent} />}
745744
{hasFinish ? <sui.Button icon="left checkmark" className={`orange right attached ${!tutorialReady ? 'disabled' : ''}`} text={lf("Finish")} ariaLabel={lf("Finish the tutorial.")} onClick={this.finishTutorial} onKeyDown={sui.fireClickOnEnter} /> : undefined}
746745
</div>
747746
</div>;

webapp/src/tutorialCodeValidation.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import * as React from "react";
44
import * as data from "./data";
55
import * as sui from "./sui";
66
import * as compiler from "./compiler";
7-
import { TutorialCard } from "./tutorial";
87

98
type ISettingsProps = pxt.editor.ISettingsProps;
109

@@ -32,14 +31,14 @@ export class ShowValidationMessage extends data.Component<TutorialCodeValidation
3231
this.state = { visible: this.props.initialVisible, ruleBlocks: {} };
3332
}
3433

35-
showUnusedBlocksMessage(vis: boolean) {
34+
showTutorialValidationMessage(vis: boolean) {
3635
this.setState({ visible: vis });
3736
}
3837

3938
moveOnToNextTutorialStep() {
4039
this.props.validationTelemetry("continue");
4140
this.props.onYesButtonClick();
42-
this.showUnusedBlocksMessage(false);
41+
this.showTutorialValidationMessage(false);
4342
}
4443

4544
stayOnThisTutorialStep() {
@@ -71,8 +70,13 @@ export class ShowValidationMessage extends data.Component<TutorialCodeValidation
7170
if (!blockUris) {
7271
return <p key={index + rule.ruleName}>{(rule.ruleTurnOn && !rule.ruleStatus) ? rule.ruleMessage : ''}</p>
7372
} else {
74-
// TODO (jxwoon): render block dataUris
75-
return <p key={index + rule.ruleName}>{(rule.ruleTurnOn && !rule.ruleStatus) ? rule.ruleMessage : ''}</p>
73+
return <div>
74+
{rule.ruleTurnOn && !rule.ruleStatus ? rule.ruleMessage : ''}
75+
<div className="validationRendering">
76+
{blockUris.map((blockUri, index) => <div> <img key={index + blockUri} src={blockUri} alt="block rendered" /></div>)}
77+
</div>
78+
</div>
79+
7680
}
7781
}
7882

@@ -97,16 +101,18 @@ export class ShowValidationMessage extends data.Component<TutorialCodeValidation
97101
return pxt.blocks.layout.blocklyToSvgAsync(svg, viewBox[0], viewBox[1], viewBox[2], viewBox[3])
98102
.then(sg => {
99103
if (!sg) return Promise.resolve<string>(undefined);
100-
return pxt.BrowserUtils.encodeToPngAsync(sg.xml, { width: sg.width, height: sg.height, pixelDensity: 1 });
104+
return pxt.BrowserUtils.encodeToPngAsync(sg.xml, { width: sg.width, height: sg.height, pixelDensity: 1 });
101105
})
102106
}
103107

104108
return Promise.resolve(undefined)
105109
})).then(blockUris => {
106-
this.setState({ ruleBlocks: {
107-
...this.state.ruleBlocks,
108-
[rule.ruleName]: blockUris.filter(b => !!b)
109-
} });
110+
this.setState({
111+
ruleBlocks: {
112+
...this.state.ruleBlocks,
113+
[rule.ruleName]: blockUris.filter(b => !!b)
114+
}
115+
});
110116
})
111117
})
112118
}
@@ -118,6 +124,7 @@ export class ShowValidationMessage extends data.Component<TutorialCodeValidation
118124
const rulesDefined = (rules != undefined);
119125
const strictRulePresent = this.props.areStrictRulesPresent;
120126
return <div>
127+
{this.state.visible && <div className="mask" role="region" onClick={this.props.onNoButtonClick} />}
121128
<div className={`tutorialCodeValidation no-select ${(!codeInvalid || (codeInvalid && !strictRulePresent)) ? 'hidden' : ''}`}>
122129
<div className="codeValidationPopUpText">
123130
{rulesDefined && rules.map((rule, index) => this.renderRule(rule, index))}

0 commit comments

Comments
 (0)