Skip to content

Commit 84d0b11

Browse files
Dialog warnings for using MakeCode with a V1 (#358)
Co-authored-by: Matt Hillsdon <[email protected]>
1 parent f77f60b commit 84d0b11

12 files changed

+400
-56
lines changed

lang/ui.en.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,10 @@
599599
"defaultMessage": "Training model…",
600600
"description": "Progress title"
601601
},
602+
"continue-makecode-action": {
603+
"defaultMessage": "Continue to MakeCode",
604+
"description": "Continue to MakeCode editor button text"
605+
},
602606
"cookies-action": {
603607
"defaultMessage": "Cookies",
604608
"description": "Action to show dialog to choose website cookie preferences"
@@ -763,6 +767,26 @@
763767
"defaultMessage": "Home page",
764768
"description": ""
765769
},
770+
"incompatible-device-body-1": {
771+
"defaultMessage": "Continue to MakeCode to edit the program. You can then save the project hex which can be downloaded onto a micro:bit V2.",
772+
"description": "Incompatible device dialog body text"
773+
},
774+
"incompatible-device-body-2": {
775+
"defaultMessage": "Alternatively, <link>save the project hex</link> without using MakeCode.",
776+
"description": "Incompatible device dialog body text"
777+
},
778+
"incompatible-device-body-alt": {
779+
"defaultMessage": "Go back to select a different micro:bit, or <link>save the project hex</link> which can be downloaded onto a micro:bit V2 later.",
780+
"description": "Incompatible device dialog body text"
781+
},
782+
"incompatible-device-heading": {
783+
"defaultMessage": "Incompatible device",
784+
"description": "Incompatible device dialog heading"
785+
},
786+
"incompatible-device-subtitle": {
787+
"defaultMessage": "You are using a micro:bit V1, but machine learning projects need the faster processor on a micro:bit V2. <link>Learn more about micro:bit versions.</link>",
788+
"description": "Incompatible device dialog subtitle"
789+
},
766790
"insufficient-data-body": {
767791
"defaultMessage": "You need at least 3 data samples for 2 actions to train the model.",
768792
"description": "Insufficient data modal content"

src/components/DownloadDialogs.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useDownloadActions } from "../hooks/download-hooks";
1010
import { useStore } from "../store";
1111
import UnplugRadioLinkMicrobitDialog from "./UnplugRadioLinkMicrobitDialog";
1212
import ConnectRadioDataCollectionMicrobitDialog from "./ConnectRadioDataCollectionMicrobitDialog";
13+
import UnsupportedEditorDevice from "./IncompatibleEditorDevice";
1314

1415
const DownloadDialogs = () => {
1516
const actions = useDownloadActions();
@@ -98,6 +99,15 @@ const DownloadDialogs = () => {
9899
closeIsPrimaryAction={true}
99100
/>
100101
);
102+
case DownloadStep.IncompatibleDevice:
103+
return (
104+
<UnsupportedEditorDevice
105+
isOpen
106+
onClose={actions.close}
107+
onBack={actions.getOnBack()}
108+
stage="flashDevice"
109+
/>
110+
);
101111
}
102112
return <></>;
103113
};
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import {
2+
Button,
3+
HStack,
4+
Link,
5+
Modal,
6+
ModalBody,
7+
ModalCloseButton,
8+
ModalContent,
9+
ModalFooter,
10+
ModalHeader,
11+
ModalOverlay,
12+
Text,
13+
VStack,
14+
} from "@chakra-ui/react";
15+
import { ReactNode } from "react";
16+
import { FormattedMessage } from "react-intl";
17+
import { useProject } from "../hooks/project-hooks";
18+
19+
interface UnsupportedEditorDeviceProps {
20+
isOpen: boolean;
21+
onClose: () => void;
22+
onNext?: () => void;
23+
onBack?: () => void;
24+
stage: "openEditor" | "flashDevice";
25+
}
26+
27+
const UnsupportedEditorDevice = ({
28+
isOpen,
29+
onClose,
30+
onNext,
31+
onBack,
32+
stage,
33+
}: UnsupportedEditorDeviceProps) => {
34+
const { saveHex } = useProject();
35+
return (
36+
<Modal
37+
closeOnOverlayClick={false}
38+
motionPreset="none"
39+
isOpen={isOpen}
40+
onClose={onClose}
41+
size="3xl"
42+
isCentered
43+
>
44+
<ModalOverlay>
45+
<ModalContent>
46+
<ModalHeader>
47+
<FormattedMessage id="incompatible-device-heading" />
48+
</ModalHeader>
49+
<ModalCloseButton />
50+
<ModalBody>
51+
<VStack width="100%" alignItems="left" gap={5}>
52+
<VStack gap={5} align="stretch">
53+
<Text>
54+
<FormattedMessage
55+
id="incompatible-device-subtitle"
56+
values={{
57+
link: (children) => (
58+
<Link
59+
href="https://support.microbit.org/support/solutions/articles/19000154234-which-version-of-micro-bit-do-i-have-"
60+
color="brand.600"
61+
>
62+
{children}
63+
</Link>
64+
),
65+
}}
66+
/>
67+
</Text>
68+
{stage === "openEditor" ? (
69+
<>
70+
<Text>
71+
<FormattedMessage id="incompatible-device-body-1" />
72+
</Text>
73+
<Text>
74+
<FormattedMessage
75+
id="incompatible-device-body-2"
76+
values={{
77+
link: (chunks: ReactNode) => (
78+
<Button variant="link" onClick={() => saveHex()}>
79+
{chunks}
80+
</Button>
81+
),
82+
}}
83+
/>
84+
</Text>
85+
</>
86+
) : (
87+
<Text>
88+
<FormattedMessage
89+
id="incompatible-device-body-alt"
90+
values={{
91+
link: (chunks: ReactNode) => (
92+
<Button variant="link" onClick={() => saveHex()}>
93+
{chunks}
94+
</Button>
95+
),
96+
}}
97+
/>
98+
</Text>
99+
)}
100+
</VStack>
101+
</VStack>
102+
</ModalBody>
103+
<ModalFooter justifyContent="end">
104+
<HStack gap={5}>
105+
<Button onClick={onBack ?? onClose} variant="secondary" size="lg">
106+
<FormattedMessage
107+
id={onBack ? "back-action" : "cancel-action"}
108+
/>
109+
</Button>
110+
<Button
111+
onClick={onNext ?? onClose}
112+
variant={onNext ? "primary" : "secondary"}
113+
size="lg"
114+
>
115+
<FormattedMessage
116+
id={onNext ? "continue-makecode-action" : "cancel-action"}
117+
/>
118+
</Button>
119+
</HStack>
120+
</ModalFooter>
121+
</ModalContent>
122+
</ModalOverlay>
123+
</Modal>
124+
);
125+
};
126+
127+
export default UnsupportedEditorDevice;

src/components/ManualFlashingDialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ const ManualFlashingDialog = ({
7070
id="connectMB.transferHex.manualDownload"
7171
values={{
7272
link: (chunks: ReactNode) => (
73-
<Text as="button" color="brand.600" onClick={handleDownload}>
73+
<Button variant="link" onClick={handleDownload}>
7474
{chunks}
75-
</Text>
75+
</Button>
7676
),
7777
}}
7878
/>

src/components/TestingModelGridView.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import {
1010
MenuList,
1111
Portal,
1212
VStack,
13+
useDisclosure,
1314
} from "@chakra-ui/react";
1415
import { MakeCodeRenderBlocksProvider } from "@microbit/makecode-embed/react";
15-
import React from "react";
16+
import React, { useCallback } from "react";
1617
import { RiArrowRightLine, RiDeleteBin2Line } from "react-icons/ri";
1718
import { FormattedMessage, useIntl } from "react-intl";
19+
import { useConnectActions } from "../connect-actions-hooks";
1820
import { usePrediction } from "../hooks/ml-hooks";
1921
import { useProject } from "../hooks/project-hooks";
2022
import { mlSettings } from "../ml";
@@ -26,6 +28,7 @@ import CodeViewCard from "./CodeViewCard";
2628
import CodeViewGridItem from "./CodeViewGridItem";
2729
import GestureNameGridItem from "./GestureNameGridItem";
2830
import HeadingGrid from "./HeadingGrid";
31+
import UnsupportedEditorDevice from "./IncompatibleEditorDevice";
2932
import LiveGraphPanel from "./LiveGraphPanel";
3033
import MoreMenuButton from "./MoreMenuButton";
3134

@@ -59,12 +62,34 @@ const TestingModelGridView = () => {
5962
const gestures = useStore((s) => s.gestures);
6063
const setRequiredConfidence = useStore((s) => s.setRequiredConfidence);
6164
const { openEditor, project, resetProject, projectEdited } = useProject();
65+
const { getDataCollectionBoardVersion } = useConnectActions();
6266

6367
const [{ languageId }] = useSettings();
6468
const makeCodeLang = getMakeCodeLang(languageId);
6569

70+
const { isOpen, onOpen, onClose } = useDisclosure();
71+
72+
const continueToEditor = useCallback(async () => {
73+
await openEditor();
74+
onClose();
75+
}, [onClose, openEditor]);
76+
77+
const maybeOpenEditor = useCallback(() => {
78+
// Open editor if device is not a V1, otherwise show warning dialog.
79+
if (getDataCollectionBoardVersion() === "V1") {
80+
return onOpen();
81+
}
82+
void openEditor();
83+
}, [getDataCollectionBoardVersion, onOpen, openEditor]);
84+
6685
return (
6786
<>
87+
<UnsupportedEditorDevice
88+
isOpen={isOpen}
89+
onClose={onClose}
90+
onNext={continueToEditor}
91+
stage="openEditor"
92+
/>
6893
<MakeCodeRenderBlocksProvider
6994
key={makeCodeLang}
7095
options={{
@@ -154,7 +179,7 @@ const TestingModelGridView = () => {
154179
<ButtonGroup isAttached>
155180
<Button
156181
variant="primary"
157-
onClick={openEditor}
182+
onClick={maybeOpenEditor}
158183
className={tourElClassname.editInMakeCodeButton}
159184
>
160185
<FormattedMessage id="edit-in-makecode-action" />

src/connect-actions-hooks.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
BoardVersion,
23
MicrobitRadioBridgeConnection,
34
MicrobitWebBluetoothConnection,
45
MicrobitWebUSBConnection,
@@ -19,6 +20,7 @@ interface ConnectContextValue {
1920
usb: MicrobitWebUSBConnection;
2021
bluetooth: MicrobitWebBluetoothConnection;
2122
radioBridge: MicrobitRadioBridgeConnection;
23+
radioRemoteBoardVersion: React.MutableRefObject<BoardVersion | undefined>;
2224
}
2325

2426
const ConnectContext = createContext<ConnectContextValue | null>(null);
@@ -50,8 +52,12 @@ export const ConnectProvider = ({ children }: ConnectProviderProps) => {
5052
}
5153
}, [bluetooth, isInitialized, radioBridge, usb]);
5254

55+
const radioRemoteBoardVersion = useRef<BoardVersion | undefined>();
56+
5357
return (
54-
<ConnectContext.Provider value={{ usb, bluetooth, radioBridge }}>
58+
<ConnectContext.Provider
59+
value={{ usb, bluetooth, radioBridge, radioRemoteBoardVersion }}
60+
>
5561
{isInitialized ? children : <></>}
5662
</ConnectContext.Provider>
5763
);
@@ -62,12 +68,20 @@ export const useConnectActions = (): ConnectActions => {
6268
if (!connectContextValue) {
6369
throw new Error("Missing provider");
6470
}
65-
const { usb, bluetooth, radioBridge } = connectContextValue;
71+
const { usb, bluetooth, radioBridge, radioRemoteBoardVersion } =
72+
connectContextValue;
6673
const logging = useLogging();
6774

6875
const connectActions = useMemo(
69-
() => new ConnectActions(logging, usb, bluetooth, radioBridge),
70-
[bluetooth, logging, radioBridge, usb]
76+
() =>
77+
new ConnectActions(
78+
logging,
79+
usb,
80+
bluetooth,
81+
radioBridge,
82+
radioRemoteBoardVersion
83+
),
84+
[bluetooth, logging, radioBridge, radioRemoteBoardVersion, usb]
7185
);
7286

7387
return connectActions;

0 commit comments

Comments
 (0)