diff --git a/lang/ui.en.json b/lang/ui.en.json
index 6a0c84d54..4a18add40 100644
--- a/lang/ui.en.json
+++ b/lang/ui.en.json
@@ -599,6 +599,10 @@
"defaultMessage": "Training model…",
"description": "Progress title"
},
+ "continue-makecode-action": {
+ "defaultMessage": "Continue to MakeCode",
+ "description": "Continue to MakeCode editor button text"
+ },
"cookies-action": {
"defaultMessage": "Cookies",
"description": "Action to show dialog to choose website cookie preferences"
@@ -763,6 +767,26 @@
"defaultMessage": "Home page",
"description": ""
},
+ "incompatible-device-body-1": {
+ "defaultMessage": "Continue to MakeCode to edit the program. You can then save the project hex which can be downloaded onto a micro:bit V2.",
+ "description": "Incompatible device dialog body text"
+ },
+ "incompatible-device-body-2": {
+ "defaultMessage": "Alternatively, save the project hex without using MakeCode.",
+ "description": "Incompatible device dialog body text"
+ },
+ "incompatible-device-body-alt": {
+ "defaultMessage": "Go back to select a different micro:bit, or save the project hex which can be downloaded onto a micro:bit V2 later.",
+ "description": "Incompatible device dialog body text"
+ },
+ "incompatible-device-heading": {
+ "defaultMessage": "Incompatible device",
+ "description": "Incompatible device dialog heading"
+ },
+ "incompatible-device-subtitle": {
+ "defaultMessage": "You are using a micro:bit V1, but machine learning projects need the faster processor on a micro:bit V2. Learn more about micro:bit versions.",
+ "description": "Incompatible device dialog subtitle"
+ },
"insufficient-data-body": {
"defaultMessage": "You need at least 3 data samples for 2 actions to train the model.",
"description": "Insufficient data modal content"
diff --git a/src/components/DownloadDialogs.tsx b/src/components/DownloadDialogs.tsx
index 6d6733c5c..2e6693d4a 100644
--- a/src/components/DownloadDialogs.tsx
+++ b/src/components/DownloadDialogs.tsx
@@ -10,6 +10,7 @@ import { useDownloadActions } from "../hooks/download-hooks";
import { useStore } from "../store";
import UnplugRadioLinkMicrobitDialog from "./UnplugRadioLinkMicrobitDialog";
import ConnectRadioDataCollectionMicrobitDialog from "./ConnectRadioDataCollectionMicrobitDialog";
+import UnsupportedEditorDevice from "./IncompatibleEditorDevice";
const DownloadDialogs = () => {
const actions = useDownloadActions();
@@ -98,6 +99,15 @@ const DownloadDialogs = () => {
closeIsPrimaryAction={true}
/>
);
+ case DownloadStep.IncompatibleDevice:
+ return (
+
+ );
}
return <>>;
};
diff --git a/src/components/IncompatibleEditorDevice.tsx b/src/components/IncompatibleEditorDevice.tsx
new file mode 100644
index 000000000..abf401524
--- /dev/null
+++ b/src/components/IncompatibleEditorDevice.tsx
@@ -0,0 +1,127 @@
+import {
+ Button,
+ HStack,
+ Link,
+ Modal,
+ ModalBody,
+ ModalCloseButton,
+ ModalContent,
+ ModalFooter,
+ ModalHeader,
+ ModalOverlay,
+ Text,
+ VStack,
+} from "@chakra-ui/react";
+import { ReactNode } from "react";
+import { FormattedMessage } from "react-intl";
+import { useProject } from "../hooks/project-hooks";
+
+interface UnsupportedEditorDeviceProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onNext?: () => void;
+ onBack?: () => void;
+ stage: "openEditor" | "flashDevice";
+}
+
+const UnsupportedEditorDevice = ({
+ isOpen,
+ onClose,
+ onNext,
+ onBack,
+ stage,
+}: UnsupportedEditorDeviceProps) => {
+ const { saveHex } = useProject();
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ (
+
+ {children}
+
+ ),
+ }}
+ />
+
+ {stage === "openEditor" ? (
+ <>
+
+
+
+
+ (
+
+ ),
+ }}
+ />
+
+ >
+ ) : (
+
+ (
+
+ ),
+ }}
+ />
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default UnsupportedEditorDevice;
diff --git a/src/components/ManualFlashingDialog.tsx b/src/components/ManualFlashingDialog.tsx
index d047bc457..8837cbfec 100644
--- a/src/components/ManualFlashingDialog.tsx
+++ b/src/components/ManualFlashingDialog.tsx
@@ -70,9 +70,9 @@ const ManualFlashingDialog = ({
id="connectMB.transferHex.manualDownload"
values={{
link: (chunks: ReactNode) => (
-
+
+
),
}}
/>
diff --git a/src/components/TestingModelGridView.tsx b/src/components/TestingModelGridView.tsx
index 5bb2f7a93..b1983614e 100644
--- a/src/components/TestingModelGridView.tsx
+++ b/src/components/TestingModelGridView.tsx
@@ -10,11 +10,13 @@ import {
MenuList,
Portal,
VStack,
+ useDisclosure,
} from "@chakra-ui/react";
import { MakeCodeRenderBlocksProvider } from "@microbit/makecode-embed/react";
-import React from "react";
+import React, { useCallback } from "react";
import { RiArrowRightLine, RiDeleteBin2Line } from "react-icons/ri";
import { FormattedMessage, useIntl } from "react-intl";
+import { useConnectActions } from "../connect-actions-hooks";
import { usePrediction } from "../hooks/ml-hooks";
import { useProject } from "../hooks/project-hooks";
import { mlSettings } from "../ml";
@@ -26,6 +28,7 @@ import CodeViewCard from "./CodeViewCard";
import CodeViewGridItem from "./CodeViewGridItem";
import GestureNameGridItem from "./GestureNameGridItem";
import HeadingGrid from "./HeadingGrid";
+import UnsupportedEditorDevice from "./IncompatibleEditorDevice";
import LiveGraphPanel from "./LiveGraphPanel";
import MoreMenuButton from "./MoreMenuButton";
@@ -59,12 +62,34 @@ const TestingModelGridView = () => {
const gestures = useStore((s) => s.gestures);
const setRequiredConfidence = useStore((s) => s.setRequiredConfidence);
const { openEditor, project, resetProject, projectEdited } = useProject();
+ const { getDataCollectionBoardVersion } = useConnectActions();
const [{ languageId }] = useSettings();
const makeCodeLang = getMakeCodeLang(languageId);
+ const { isOpen, onOpen, onClose } = useDisclosure();
+
+ const continueToEditor = useCallback(async () => {
+ await openEditor();
+ onClose();
+ }, [onClose, openEditor]);
+
+ const maybeOpenEditor = useCallback(() => {
+ // Open editor if device is not a V1, otherwise show warning dialog.
+ if (getDataCollectionBoardVersion() === "V1") {
+ return onOpen();
+ }
+ void openEditor();
+ }, [getDataCollectionBoardVersion, onOpen, openEditor]);
+
return (
<>
+
{