Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Post import hex/data samples tour #355

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions lang/ui.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1071,10 +1071,58 @@
"defaultMessage": "Your data collection micro:bit is connected!",
"description": "Tour step title"
},
"tour-dataSamples-imported-actions-content": {
"defaultMessage": "An action is the type of movement you want the machine learning tool to recognise e.g. ‘waving’ or ‘clapping’. ",
"description": "Tour step content"
},
"tour-dataSamples-imported-addActions-content": {
"defaultMessage": "You can add more actions by pressing on this button.",
"description": "Tour step description"
},
"tour-dataSamples-imported-addActions-title": {
"defaultMessage": "Add more actions",
"description": "Tour step title"
},
"tour-dataSamples-imported-collectData-content": {
"defaultMessage": "Connect a micro:bit to collect movement data samples from the micro:bit’s accelerometer.",
"description": "Tour step title"
},
"tour-dataSamples-imported-collectData-title": {
"defaultMessage": "Connect to collect more data samples",
"description": "Tour step title"
},
"tour-dataSamples-imported-content": {
"defaultMessage": "You can add more actions or data samples, or train a machine learning (ML) model to recognise different actions if you have enough data.",
"description": "Tour step content"
},
"tour-dataSamples-imported-recordings-content": {
"defaultMessage": "These are the movement data samples for an action. Collecting more samples should result in a better machine learning model. Your data samples are only stored on your computer, they do not get sent to anyone else.",
"description": "Tour step description"
},
"tour-dataSamples-imported-title": {
"defaultMessage": "New actions and data samples have been loaded!",
"description": "Tour step title"
},
"tour-dataSamples-liveGraph-content": {
"defaultMessage": "The graph shows movement data from the micro:bit’s accelerometer. Move your data collection micro:bit and see how the graph changes.",
"description": "Tour step content"
},
"tour-dataSamples-recordButton-content": {
"defaultMessage": "Press to record a data sample or press button B on your micro:bit.",
"description": "Tour step content"
},
"tour-dataSamples-recordButton-title": {
"defaultMessage": "Collect more data samples",
"description": "Tour step title"
},
"tour-testModel-afterTrain-connect-content": {
"defaultMessage": "Connect a micro:bit to test your machine learning model.",
"description": "Tour step description"
},
"tour-testModel-afterTrain-connect-title": {
"defaultMessage": "Connect to test your model",
"description": "Tour step title"
},
"tour-testModel-afterTrain-content": {
"defaultMessage": "Now test your machine learning model. Try each action by moving your data collection micro:bit. Does the model detect each action?",
"description": "Tour step description"
Expand Down
1 change: 1 addition & 0 deletions src/components/DataRecordingGridItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const DataRecordingGridItem = ({
<CardBody display="flex" flexDirection="row" p={1} gap={3}>
<HStack w="8.25rem" justifyContent="center">
<IconButton
className={tourElClassname.recordDataSamplesButton}
ref={closeRecordingDialogFocusRef}
height="fit-content"
width="fit-content"
Expand Down
1 change: 1 addition & 0 deletions src/components/LiveGraphPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const LiveGraphPanel = ({
</Button>
) : (
<Button
className={tourElClassname.connectButton}
variant="primary"
size="sm"
isDisabled={
Expand Down
104 changes: 73 additions & 31 deletions src/messages/ui.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1403,30 +1403,6 @@
"value": "The name is used when you save a file."
}
],
"newpage-browse-lessons": [
{
"type": 0,
"value": "Browse lessons"
}
],
"newpage-browse-projects": [
{
"type": 0,
"value": "Browse projects"
}
],
"newpage-choose-subtitle": [
{
"type": 0,
"value": "Find a project or lesson from our teacher resources and open it in micro:bit classroom"
}
],
"newpage-choose-title": [
{
"type": 0,
"value": "Choose a project or lesson"
}
],
"newpage-continue-session-instruction": [
{
"type": 0,
Expand All @@ -1451,12 +1427,6 @@
"value": "Run whole class sessions, easily share code with students and save progress"
}
],
"newpage-heading-title": [
{
"type": 0,
"value": "Welcome to micro:bit classroom"
}
],
"newpage-last-session-date": [
{
"children": [
Expand Down Expand Up @@ -1895,12 +1865,84 @@
"value": "Your data collection micro:bit is connected!"
}
],
"tour-dataSamples-imported-actions-content": [
{
"type": 0,
"value": "An action is the type of movement you want the machine learning tool to recognise e.g. ‘waving’ or ‘clapping’. "
}
],
"tour-dataSamples-imported-addActions-content": [
{
"type": 0,
"value": "You can add more actions by pressing on this button."
}
],
"tour-dataSamples-imported-addActions-title": [
{
"type": 0,
"value": "Add more actions"
}
],
"tour-dataSamples-imported-collectData-content": [
{
"type": 0,
"value": "Connect a micro:bit to collect movement data samples from the micro:bit’s accelerometer."
}
],
"tour-dataSamples-imported-collectData-title": [
{
"type": 0,
"value": "Connect to collect more data samples"
}
],
"tour-dataSamples-imported-content": [
{
"type": 0,
"value": "You can add more actions or data samples, or train a machine learning (ML) model to recognise different actions if you have enough data."
}
],
"tour-dataSamples-imported-recordings-content": [
{
"type": 0,
"value": "These are the movement data samples for an action. Collecting more samples should result in a better machine learning model. Your data samples are only stored on your computer, they do not get sent to anyone else."
}
],
"tour-dataSamples-imported-title": [
{
"type": 0,
"value": "New actions and data samples have been loaded!"
}
],
"tour-dataSamples-liveGraph-content": [
{
"type": 0,
"value": "The graph shows movement data from the micro:bit’s accelerometer. Move your data collection micro:bit and see how the graph changes."
}
],
"tour-dataSamples-recordButton-content": [
{
"type": 0,
"value": "Press to record a data sample or press button B on your micro:bit."
}
],
"tour-dataSamples-recordButton-title": [
{
"type": 0,
"value": "Collect more data samples"
}
],
"tour-testModel-afterTrain-connect-content": [
{
"type": 0,
"value": "Connect a micro:bit to test your machine learning model."
}
],
"tour-testModel-afterTrain-connect-title": [
{
"type": 0,
"value": "Connect to test your model"
}
],
"tour-testModel-afterTrain-content": [
{
"type": 0,
Expand Down Expand Up @@ -1970,7 +2012,7 @@
"unplug-radio-link-microbit-description": [
{
"type": 0,
"value": "Unplug the radio link micro:bit from the computer. If you want to record more data samples, you will need to reconnect with the tool."
"value": "Unplug the radio link micro:bit from the computer. You will need to reconnect the micro:bit if you want to record more data samples."
}
],
"unplug-radio-link-microbit-label": [
Expand Down
7 changes: 4 additions & 3 deletions src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ export interface TourState {
}

export enum TourId {
DataSamplesPage = "dataSamplesPage",
CollectDataToTrainModel = "collectDataToTrainModel",
TestModelPage = "testModelPage",
DataSamplesPagePostConnect = "data samples page post connect",
CollectDataToTrainModel = "collect data to train model",
DataSamplesPagePostImport = "data samples page post import",
TestModelPage = "test model page connected",
}
33 changes: 26 additions & 7 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ const updateProject = (
};
};

const getPostImportTourState = (
settings: Settings,
tourState: TourState | undefined
): TourState | undefined => {
const { toursCompleted } = settings;
return toursCompleted.includes(TourId.DataSamplesPagePostImport) ||
toursCompleted.includes(TourId.DataSamplesPagePostConnect)
? tourState
: { id: TourId.DataSamplesPagePostImport, index: 0 };
};

export interface State {
gestures: GestureData[];
model: tf.LayersModel | undefined;
Expand Down Expand Up @@ -281,6 +292,7 @@ export const useStore = create<Store>()(
gestures: updatedGestures,
model: undefined,
tourState:
!toursCompleted.includes(TourId.DataSamplesPagePostImport) &&
!toursCompleted.includes(TourId.CollectDataToTrainModel) &&
updatedGestures.length === 1 &&
updatedGestures[0].recordings.length === 1
Expand Down Expand Up @@ -388,7 +400,7 @@ export const useStore = create<Store>()(
},

loadDataset(newGestures: GestureData[]) {
set(({ project, projectEdited }) => {
set(({ project, projectEdited, tourState, settings }) => {
return {
gestures: (() => {
const copy = newGestures.map((g) => ({ ...g }));
Expand All @@ -404,6 +416,7 @@ export const useStore = create<Store>()(
})(),
model: undefined,
...updateProject(project, projectEdited, newGestures, undefined),
tourState: getPostImportTourState(settings, tourState),
};
});
},
Expand Down Expand Up @@ -528,6 +541,8 @@ export const useStore = create<Store>()(
project: prevProject,
isEditorOpen,
changedHeaderExpected,
tourState,
settings,
} = state;
const newProjectHeader = newProject.header!.id;
const previousProjectHeader = prevProject.header!.id;
Expand Down Expand Up @@ -557,6 +572,7 @@ export const useStore = create<Store>()(
gestures: dataset.data,
model: undefined,
isEditorOpen: false,
tourState: getPostImportTourState(settings, tourState),
};
} else if (isEditorOpen) {
return {
Expand Down Expand Up @@ -593,14 +609,17 @@ export const useStore = create<Store>()(
},
dataCollectionMicrobitConnected() {
set(
({ gestures, tourState, settings }) => ({
({ gestures, tourState, settings: { toursCompleted } }) => ({
gestures:
gestures.length === 0 ? [createFirstGesture()] : gestures,
tourState: settings.toursCompleted.includes(
TourId.DataSamplesPage
)
? tourState
: { id: TourId.DataSamplesPage, index: 0 },
tourState:
toursCompleted.includes(TourId.DataSamplesPagePostConnect) ||
toursCompleted.includes(TourId.DataSamplesPagePostImport)
? tourState
: {
id: TourId.DataSamplesPagePostConnect,
index: 0,
},
}),
false,
"dataCollectionMicrobitConnected"
Expand Down
59 changes: 56 additions & 3 deletions src/tours.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { FormattedMessageStepContent } from "./pages/Tour";
export const tourElClassname = {
liveGraph: "live-graph",
dataSamplesActionCard: "data-samples-action-card",
dataSamplesRow: "data-samples-row",
recordDataSamplesCard: "record-data-samples-card",
recordDataSamplesButton: "record-data-samples-button",
connectButton: "connect-button",
addActionButton: "add-action-button",
trainModelButton: "train-model-button",
estimatedAction: "estimated-action",
Expand Down Expand Up @@ -39,8 +42,7 @@ const classSelector = (classname: string) => `.${classname}`;
// If you complete a tour then we don't show it again.
export const tours: Record<TourId, TourStep[]> = {
// Launched when you connect a micro:bit when you have no recordings.
// If you import data without connecting a micro:bit you're on your own for now.
[TourId.DataSamplesPage]: [
[TourId.DataSamplesPagePostConnect]: [
{
title: <FormattedMessage id="tour-dataSamples-connected-title" />,
content: (
Expand All @@ -62,7 +64,7 @@ export const tours: Record<TourId, TourStep[]> = {
),
},
],
// Launched after recording your first recording.
// Launched after recording your first recording and have no recordings.
[TourId.CollectDataToTrainModel]: [
{
title: <FormattedMessage id="tour-collectData-afterFirst-title" />,
Expand Down Expand Up @@ -92,6 +94,57 @@ export const tours: Record<TourId, TourStep[]> = {
),
},
],
// Launched after importing data without connecting a micro:bit.
[TourId.DataSamplesPagePostImport]: [
{
title: <FormattedMessage id="tour-dataSamples-imported-title" />,
content: (
<FormattedMessageStepContent id="tour-dataSamples-imported-content" />
),
modalSize: "xl",
},
{
selector: classSelector(tourElClassname.dataSamplesActionCard),
title: <FormattedMessage id="actions-label" />,
content: (
<FormattedMessageStepContent id="tour-dataSamples-imported-actions-content" />
),
},
{
selector: classSelector(tourElClassname.recordDataSamplesCard),
title: <FormattedMessage id="content.data.data" />,
content: (
<FormattedMessageStepContent id="tour-dataSamples-imported-recordings-content" />
),
},
{
selector: classSelector(tourElClassname.addActionButton),
title: (
<FormattedMessage id="tour-dataSamples-imported-addActions-title" />
),
content: (
<FormattedMessageStepContent id="tour-dataSamples-imported-addActions-content" />
),
},
{
selector: classSelector(tourElClassname.connectButton),
title: (
<FormattedMessage id="tour-dataSamples-imported-collectData-title" />
),
content: (
<FormattedMessageStepContent id="tour-dataSamples-imported-collectData-content" />
),
},
{
selector: classSelector(tourElClassname.trainModelButton),
title: <FormattedMessage id="menu.trainer.trainModelButton" />,
content: (
<FormattedMessageStepContent id="tour-collectData-trainModel-content" />
),
},
// TODO: Add tour step for triggering data samples page tour
// so that the user can see tour steps of things they may have missed
Comment on lines +145 to +146
Copy link
Author

@microbit-grace microbit-grace Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a tour after connecting micro:bit was considered so that other content could also be introduced e.g. recording instructions, live graph. But depending on which page/stage the user connects a micro:bit, the content would probably need to be different. As a more generic response, perhaps we add a step at the end of the tour for telling them how to trigger a more thorough/generic tour?

],
// Launched after training a model
// If you haven't connected a micro:bit this session then it'll
// be a bit weird but we just go with it for now.
Expand Down
Loading