Skip to content

Commit acc8652

Browse files
Initial tour implementation (#321)
* Trigger data collection tour when connected * Trigger train model tour once first recording is added * Trigger testing model tour after training
1 parent 33923d2 commit acc8652

26 files changed

+891
-100
lines changed

lang/ui.en.json

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
"defaultMessage": "Developed in partnership with <link>Center for Computational Thinking and Design, Aarhus University</link>",
1212
"description": "Title of about dialog"
1313
},
14+
"accelerometer-image-alt": {
15+
"defaultMessage": "micro:bit showing X axis going across the front, Y axis going down and up, Z axis going back to front",
16+
"description": "Alt text for image showing the board-relative directions of the X/Y/Z dimensions of the micro:bit accelerometer"
17+
},
18+
"actions-label": {
19+
"defaultMessage": "Actions",
20+
"description": "Label for Actions"
21+
},
1422
"actions.reconnect": {
1523
"defaultMessage": "Reconnect",
1624
"description": ""
@@ -512,7 +520,7 @@
512520
"description": ""
513521
},
514522
"content.data.dataDescription": {
515-
"defaultMessage": "Multiple samples of movement data collected in approximately 2 second bursts.",
523+
"defaultMessage": "Short collections of movement data lasting approximately 2 seconds. Your data samples are only stored on your computer, they do not get sent to anyone else.",
516524
"description": ""
517525
},
518526
"content.data.deleteAction": {
@@ -604,15 +612,15 @@
604612
"description": ""
605613
},
606614
"content.model.output.output.descriptionBody": {
607-
"defaultMessage": "What the micro:bit will do when each action is detected.",
615+
"defaultMessage": "These MakeCode blocks will show icons for each action detected when you transfer your code and model to a micro:bit.",
608616
"description": ""
609617
},
610618
"content.model.output.output.descriptionTitle": {
611619
"defaultMessage": "Output",
612620
"description": ""
613621
},
614622
"content.model.output.recognitionPoint": {
615-
"defaultMessage": "Recognition Point:",
623+
"defaultMessage": "Recognition point:",
616624
"description": ""
617625
},
618626
"content.trainer.description": {
@@ -740,7 +748,7 @@
740748
"description": ""
741749
},
742750
"footer.helpContent": {
743-
"defaultMessage": "This graph shows movement data from the micro:bits accelerometer in real time. Try moving your connected micro:bit to see the X, Y and Z axes change.",
751+
"defaultMessage": "This graph shows movement data from the micro:bit's accelerometer in real time. Try moving your data collection micro:bit to see the X, Y and Z axes change. Each coloured line represents a different direction (dimension) you are moving the micro:bit in.",
744752
"description": ""
745753
},
746754
"footer.helpHeader": {
@@ -803,6 +811,10 @@
803811
"defaultMessage": "Language",
804812
"description": "Language option text"
805813
},
814+
"live-data-graph": {
815+
"defaultMessage": "Live data graph",
816+
"description": "Title for live data graph"
817+
},
806818
"loading": {
807819
"defaultMessage": "loading",
808820
"description": ""
@@ -964,8 +976,8 @@
964976
"description": "Reload page button text"
965977
},
966978
"reset-to-default-action": {
967-
"defaultMessage": "Reset to default",
968-
"description": "Reset to default button text"
979+
"defaultMessage": "Reset to default blocks",
980+
"description": "Reset to default blocks button text"
969981
},
970982
"resources": {
971983
"defaultMessage": "Resources",
@@ -1039,6 +1051,10 @@
10391051
"defaultMessage": "Join our testing community",
10401052
"description": ""
10411053
},
1054+
"skip-tour-action": {
1055+
"defaultMessage": "Skip tour",
1056+
"description": "Skip tour button text"
1057+
},
10421058
"software-versions": {
10431059
"defaultMessage": "Software versions",
10441060
"description": "Software versions text"
@@ -1067,6 +1083,82 @@
10671083
"defaultMessage": "Testing model",
10681084
"description": "Testing model page title"
10691085
},
1086+
"tour-collectData-addActions-content": {
1087+
"defaultMessage": "Decide what your other actions will be and what you will name them. You need at least 2 actions with 3 data samples to train the model. Your data samples are only stored on your computer, they do not get sent to anyone else.",
1088+
"description": "Tour step description"
1089+
},
1090+
"tour-collectData-addActions-title": {
1091+
"defaultMessage": "Add more actions",
1092+
"description": "Tour step title"
1093+
},
1094+
"tour-collectData-afterFirst-content": {
1095+
"defaultMessage": "To train the machine learning model you need at least 3 data samples for 2 different actions.",
1096+
"description": "Tour step description"
1097+
},
1098+
"tour-collectData-afterFirst-title": {
1099+
"defaultMessage": "You’ve recorded your first sample!",
1100+
"description": "Tour step title"
1101+
},
1102+
"tour-collectData-collectMore-content": {
1103+
"defaultMessage": "Record more samples for this action. Collecting more samples should result in a better machine learning model.",
1104+
"description": "Tour step description"
1105+
},
1106+
"tour-collectData-collectMore-title": {
1107+
"defaultMessage": "Collect more data samples",
1108+
"description": "Tour step title"
1109+
},
1110+
"tour-collectData-trainModel-content": {
1111+
"defaultMessage": "When you have collected enough data samples you can train the machine learning model. You can come back later to remove or add more data and re-train to make the model more reliable.",
1112+
"description": "Tour step description"
1113+
},
1114+
"tour-dataSamples-actions-content": {
1115+
"defaultMessage": "An action is the type of movement you want the machine learning tool to recognise e.g. ‘waving’ or ‘clapping’. Decide what your first action will be, name it and then start recording data samples.",
1116+
"description": "Tour step content"
1117+
},
1118+
"tour-dataSamples-connected-content": {
1119+
"defaultMessage": "Now you can start collecting data samples to train a machine learning (ML) model to recognise different movements.",
1120+
"description": "Tour step content"
1121+
},
1122+
"tour-dataSamples-connected-title": {
1123+
"defaultMessage": "Your data collection micro:bit is connected!",
1124+
"description": "Tour step title"
1125+
},
1126+
"tour-dataSamples-liveGraph-content": {
1127+
"defaultMessage": "The graph shows movement data from the micro:bit’s accelerometer. Move your data collection micro:bit and see how the graph changes.",
1128+
"description": "Tour step content"
1129+
},
1130+
"tour-testModel-afterTrain-content": {
1131+
"defaultMessage": "Now test your machine learning model. Try each action by moving your data collection micro:bit. Does the model detect each action?",
1132+
"description": "Tour step description"
1133+
},
1134+
"tour-testModel-afterTrain-title": {
1135+
"defaultMessage": "You’ve trained an ML model!",
1136+
"description": "Tour step title"
1137+
},
1138+
"tour-testModel-certaintyRecognition-content": {
1139+
"defaultMessage": "The meter shows how confident the model is that you are doing each action. Move the slider to adjust the recognition point, or threshold.",
1140+
"description": "Tour step description"
1141+
},
1142+
"tour-testModel-certaintyRecognition-title": {
1143+
"defaultMessage": "Certainty and recognition point",
1144+
"description": "Tour step title"
1145+
},
1146+
"tour-testModel-editInMakeCode-content": {
1147+
"defaultMessage": "Open your project in MakeCode to download the program and your machine learning model to a micro:bit. You can add more blocks to create your own programs using your model.",
1148+
"description": "Tour step description"
1149+
},
1150+
"tour-testModel-estimatedAction-content": {
1151+
"defaultMessage": "The action the model estimates you are currently doing is shown above the micro:bit icon for that action.",
1152+
"description": "Tour step description"
1153+
},
1154+
"tour-testModel-makeCodeBlocks-content": {
1155+
"defaultMessage": "These MakeCode blocks will show icons for each action detected when you transfer your code and model to a micro:bit.",
1156+
"description": "Tour step description"
1157+
},
1158+
"tour-testModel-makeCodeBlocks-title": {
1159+
"defaultMessage": "Microsoft MakeCode blocks",
1160+
"description": "Tour step title"
1161+
},
10701162
"train-model-intro-description": {
10711163
"defaultMessage": "Ask the computer to use your training samples to train the machine learning model to recognise different actions.",
10721164
"description": "Train model step home page description"

src/components/AddDataGridWalkThrough.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { GridItem, HStack, Image, Text, VStack } from "@chakra-ui/react";
1+
import { GridItem, HStack, Text, VStack } from "@chakra-ui/react";
22
import { FormattedMessage } from "react-intl";
33
import { GestureData } from "../model";
4-
import upCurveArrowImage from "../images/curve-arrow-up.svg";
5-
import greetingEmojiWithArrowImage from "../images/greeting-emoji-with-arrow.svg";
64
import DataRecordingGridItem from "./DataRecordingGridItem";
5+
import GreetingEmojiWithArrow from "./GreetingEmojiWithArrow";
6+
import UpCurveArrow from "./UpCurveArrow";
77

88
interface AddDataGridWalkThrough {
99
gesture: GestureData;
@@ -19,12 +19,7 @@ const AddDataGridWalkThrough = ({
1919
{gesture.name.length === 0 ? (
2020
<GridItem h="120px">
2121
<VStack m={0} p={2} w={200} transform="translate(-30px, 40px)">
22-
<Image
23-
w="120px"
24-
h="103px"
25-
src={greetingEmojiWithArrowImage}
26-
alt=""
27-
/>
22+
<GreetingEmojiWithArrow w="120px" h="103px" color="brand.500" />
2823
<Text textAlign="center">
2924
<FormattedMessage id="content.data.addActionWalkThrough" />
3025
</Text>
@@ -46,7 +41,7 @@ const AddDataGridWalkThrough = ({
4641
transform="translateX(65px)"
4742
w="calc(100% - 65px)"
4843
>
49-
<Image w="60px" h="93px" src={upCurveArrowImage} alt="" />
44+
<UpCurveArrow w="60px" h="93px" color="brand.500" />
5045
<Text w={200} textAlign="center">
5146
<FormattedMessage id="content.data.addRecordingWalkThrough" />
5247
</Text>

src/components/CertaintyThresholdGridItem.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from "@chakra-ui/react";
1414
import { useCallback, useMemo } from "react";
1515
import { FormattedMessage, useIntl } from "react-intl";
16+
import { tourElClassname } from "../tours";
1617
import PercentageDisplay from "./PercentageDisplay";
1718
import PercentageMeter from "./PercentageMeter";
1819

@@ -54,6 +55,7 @@ const CertaintyThresholdGridItem = ({
5455
width="fit-content"
5556
borderWidth={1}
5657
borderColor="transparent"
58+
className={tourElClassname.certaintyThreshold}
5759
>
5860
<CardBody
5961
display="flex"

src/components/CodeViewCard.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Project,
66
} from "@microbit/makecode-embed/react";
77
import { memo } from "react";
8+
import { tourElClassname } from "../tours";
89

910
interface CodeViewCardProps {
1011
project: Project;
@@ -22,7 +23,13 @@ const CodeViewCard = ({ project }: CodeViewCardProps) => {
2223
borderColor="brand.500"
2324
justifyContent="center"
2425
>
25-
<Card w="full" h="full" p={5} objectFit="contain">
26+
<Card
27+
w="full"
28+
h="full"
29+
p={5}
30+
objectFit="contain"
31+
className={tourElClassname.makeCodeCodeView}
32+
>
2633
<MakeCodeBlocksRendering
2734
code={project}
2835
layout={BlockLayout.Flow}

src/components/CodeViewGridItem.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { memo, useMemo } from "react";
77
import { generateProject } from "../makecode/utils";
88
import { GestureData } from "../model";
99
import { useStore } from "../store";
10+
import { tourElClassname } from "../tours";
1011

1112
interface CodeViewGridItemProps {
1213
gesture: GestureData;
@@ -38,6 +39,7 @@ const CodeViewGridItem = ({
3839
minW="400px"
3940
width="fit-content"
4041
justifyContent="center"
42+
className={tourElClassname.makeCodeCodeView}
4143
>
4244
<Box width={width} py={2} px={2} overflow="hidden">
4345
<MakeCodeBlocksRendering

src/components/DataRecordingGridItem.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import {
1010
import { useCallback, useRef } from "react";
1111
import { useIntl } from "react-intl";
1212
import { useConnectionStage } from "../connection-stage-hooks";
13-
import { GestureData } from "../model";
1413
import RecordIcon from "../images/record-icon.svg?react";
15-
import RecordingGraph from "./RecordingGraph";
14+
import { GestureData } from "../model";
1615
import { useStore } from "../store";
16+
import { tourElClassname } from "../tours";
17+
import RecordingGraph from "./RecordingGraph";
1718

1819
interface DataRecordingGridItemProps {
1920
data: GestureData;
@@ -52,6 +53,7 @@ const DataRecordingGridItem = ({
5253
width="fit-content"
5354
borderColor={selected ? "brand.500" : "transparent"}
5455
borderWidth={1}
56+
className={tourElClassname.recordDataSamplesCard}
5557
>
5658
<CardBody display="flex" flexDirection="row" p={1} gap={3}>
5759
<HStack w="8.25rem" justifyContent="center">

src/components/DefaultPageLayout.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import { useNavigate } from "react-router";
1717
import { TOOL_NAME } from "../constants";
1818
import { flags } from "../flags";
1919
import { useProject } from "../hooks/project-hooks";
20-
import { SaveStep } from "../model";
20+
import { SaveStep, TrainModelDialogStage } from "../model";
2121
import { SessionPageId } from "../pages-config";
22+
import Tour from "../pages/Tour";
2223
import { useSettings, useStore } from "../store";
2324
import { createHomePageUrl, createSessionPageUrl } from "../urls";
2425
import ActionBar from "./ActionBar";
@@ -57,6 +58,8 @@ const DefaultPageLayout = ({
5758
const intl = useIntl();
5859
const navigate = useNavigate();
5960
const isEditorOpen = useStore((s) => s.isEditorOpen);
61+
const stage = useStore((s) => s.trainModelDialogStage);
62+
6063
const { saveHex } = useProject();
6164
const [settings] = useSettings();
6265
const toast = useToast();
@@ -103,13 +106,12 @@ const DefaultPageLayout = ({
103106

104107
return (
105108
<>
106-
{/* Suppress connection and train dialogs when MakeCode editor is open */}
107-
{!isEditorOpen && (
108-
<>
109-
<ConnectionDialogs />
110-
<TrainModelDialogs />
111-
</>
109+
{/* Suppress dialogs to prevent overlapping dialogs */}
110+
{!isEditorOpen && stage === TrainModelDialogStage.Closed && (
111+
<ConnectionDialogs />
112112
)}
113+
{!isEditorOpen && <TrainModelDialogs />}
114+
{!isEditorOpen && stage === TrainModelDialogStage.Closed && <Tour />}
113115
<DownloadDialogs />
114116
<SaveDialogs />
115117
<VStack

src/components/GestureNameGridItem.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import {
99
} from "@chakra-ui/react";
1010
import { useCallback } from "react";
1111
import { useIntl } from "react-intl";
12+
import { useStore } from "../store";
13+
import { tourElClassname } from "../tours";
1214
import { MakeCodeIcon } from "../utils/icons";
1315
import LedIcon from "./LedIcon";
1416
import LedIconPicker from "./LedIconPicker";
15-
import { useStore } from "../store";
1617

1718
interface GestureNameGridItemProps {
1819
name: string;
@@ -83,6 +84,7 @@ const GestureNameGridItem = ({
8384
borderWidth={selected ? 1 : 0}
8485
onClick={onSelectRow}
8586
position="relative"
87+
className={tourElClassname.dataSamplesActionCard}
8688
>
8789
{!readOnly && onDeleteAction && (
8890
<CloseButton
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Icon } from "@chakra-ui/react";
2+
3+
interface GreetingEmojiWithArrowProps {
4+
w: string;
5+
h: string;
6+
color?: string;
7+
}
8+
9+
const GreetingEmojiWithArrow = ({
10+
w,
11+
h,
12+
color,
13+
}: GreetingEmojiWithArrowProps) => {
14+
return (
15+
<Icon w={w} h={h} viewBox="0 0 40 31.424875" color={color}>
16+
<path
17+
d="M 105.80677,104.76545 A 12.303125,12.303125 0 0 0 90.928702,96.869948 l 0.66753,-1.30567 a 0.51964167,0.51964167 0 0 0 -0.22795,-0.70714 0.51964167,0.51964167 0 0 0 -0.707136,0.22795 l -1.235843,2.41917 a 0.51990625,0.51990625 0 0 0 0.227951,0.70713 l 2.417743,1.2359 a 0.53234167,0.53234167 0 0 0 0.70714,-0.22795 0.51990625,0.51990625 0 0 0 -0.227955,-0.70713 L 91.287,97.866588 a 11.201135,11.201135 0 0 1 13.50055,7.211022 0.54689375,0.54689375 0 0 0 0.27325,0.3067 0.6429375,0.6429375 0 0 0 0.40109,0.0441 0.48709792,0.48709792 0 0 0 0.3098,-0.2422 0.52916667,0.52916667 0 0 0 0.0347,-0.42094"
18+
fill="currentColor"
19+
clipPath="url(#clipPath1)"
20+
display="inline"
21+
transform="matrix(1.1240682,0,0,1.1240682,-100.45299,-106.55292)"
22+
/>
23+
<path
24+
fill="currentColor"
25+
d="m 20.482081,29.956698 c -0.946933,0.02373 -1.806825,-0.47303 -2.229983,-1.288273 -0.06728,-0.129623 -0.164653,-0.380133 -0.208188,-0.535614 l -0.01776,-0.06343 0.531437,-0.07469 0.531437,-0.07469 0.02115,0.06295 c 0.07312,0.217669 0.279373,0.48328 0.496971,0.639986 0.34441,0.248029 0.681415,0.321744 1.106727,0.242082 0.313052,-0.05864 0.537089,-0.18098 0.758756,-0.414348 0.196462,-0.206832 0.354616,-0.549227 0.377681,-0.817659 l 0.0088,-0.102324 0.530723,-0.07459 0.530724,-0.07459 1.43e-4,0.0747 c 0.001,0.523308 -0.130746,0.994505 -0.387281,1.385096 -0.303034,0.461387 -0.725611,0.78725 -1.257363,0.969594 -0.203606,0.06982 -0.589432,0.140666 -0.793962,0.145793 z M 14.935754,26.11049 C 13.154492,26.215391 11.529805,25.608555 10.328702,24.389713 9.0939929,23.136769 8.4689853,21.24571 8.6759065,19.388921 c 0.1167817,-1.04793 0.500206,-2.017793 1.1260509,-2.848321 0.3839756,-0.509554 0.7936766,-0.90173 1.3220506,-1.265499 0.61022,-0.420116 1.274848,-0.715598 2.038498,-0.906278 0.315066,-0.07867 10.209673,-1.468941 10.542298,-1.481276 1.167234,-0.04328 2.248553,0.206167 3.197321,0.737597 1.924577,1.078007 3.070974,3.209328 2.986059,5.551524 -0.03793,1.046194 -0.356733,2.076315 -0.907281,2.93161 -0.841472,1.307256 -2.149563,2.200682 -3.742218,2.555933 -0.269729,0.06016 -10.029244,1.430161 -10.302931,1.446279 z m 9.880667,-3.962235 c 0.735633,-0.201619 1.368721,-0.63128 1.827775,-1.240469 0.773781,-1.026845 0.90565,-2.409818 0.340308,-3.568971 -0.105176,-0.215648 -0.349956,-0.579334 -0.510764,-0.758877 -0.690198,-0.770607 -1.673157,-1.189177 -2.69908,-1.149341 -0.251513,0.0098 -9.725215,1.341208 -9.969677,1.401147 -1.390244,0.340868 -2.430743,1.518672 -2.590015,2.931793 -0.03898,0.345804 -0.031,0.577622 0.03303,0.960425 0.05584,0.333818 0.09556,0.478722 0.202706,0.739431 0.532242,1.295071 1.844656,2.149988 3.244491,2.113487 0.07914,-0.0021 2.24332,-0.29839 5.030174,-0.688747 4.280878,-0.599625 4.91621,-0.691958 5.091056,-0.739878 z m -10.36065,-0.732646 c -0.361972,-0.04241 -0.697468,-0.247762 -0.898963,-0.550245 -0.230237,-0.34563 -0.280143,-0.73156 -0.146249,-1.130973 0.06645,-0.198224 0.248934,-0.452733 0.413298,-0.576421 0.344822,-0.259487 0.770372,-0.33055 1.179512,-0.196966 0.147374,0.04812 0.203388,0.07842 0.354317,0.191689 0.153465,0.115171 0.193866,0.156446 0.280672,0.286741 0.139022,0.208671 0.193978,0.36377 0.215783,0.608988 0.0103,0.115819 0.0098,0.235942 -0.0013,0.300864 -0.07767,0.456117 -0.376294,0.826326 -0.799368,0.990978 -0.149562,0.05821 -0.43593,0.0943 -0.597744,0.07534 z m 9.309591,-1.308377 c -0.343839,-0.04029 -0.677273,-0.235675 -0.877632,-0.514288 -0.121252,-0.168608 -0.172015,-0.28824 -0.21345,-0.50303 -0.04657,-0.241405 -0.03656,-0.405943 0.03915,-0.64359 0.04614,-0.144844 0.07594,-0.200783 0.183241,-0.343974 0.141887,-0.189352 0.268866,-0.296369 0.471385,-0.397278 0.111247,-0.05543 0.154159,-0.06673 0.367323,-0.09669 0.213163,-0.02996 0.257526,-0.03093 0.379742,-0.0083 0.222326,0.04115 0.374141,0.109062 0.560044,0.250534 0.192921,0.146813 0.318982,0.310834 0.40865,0.531706 0.129905,0.319985 0.112812,0.726301 -0.04372,1.03926 -0.133147,0.266204 -0.391678,0.499271 -0.676987,0.610308 -0.149562,0.05821 -0.43593,0.0943 -0.597744,0.07534 z"
26+
/>
27+
</Icon>
28+
);
29+
};
30+
31+
export default GreetingEmojiWithArrow;

0 commit comments

Comments
 (0)