Skip to content

Commit

Permalink
Handle radio connect/ reconnect error scenarios (#281)
Browse files Browse the repository at this point in the history
For radio connection dev purposes, when locally developing, a skip button is visible for micro:bit 1 and the radio remote device id is stored in the local storage.

Also implemented bluetooth connection fail dialog.

Other minor changes:
- Includes a small fix in logic in Add Data page so that data can be visible without connecting
- Close start over session warning dialog when new session is selected
  • Loading branch information
microbit-grace authored Aug 6, 2024
1 parent 0873cef commit 7420da2
Show file tree
Hide file tree
Showing 18 changed files with 950 additions and 235 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@microbit/microbit-connection": "^0.0.0-alpha.17",
"@microbit/microbit-connection": "^0.0.0-alpha.18",
"@tensorflow/tfjs": "^4.4.0",
"@types/w3c-web-serial": "^1.0.6",
"@types/w3c-web-usb": "^1.0.6",
Expand Down
2 changes: 1 addition & 1 deletion src/buffered-data-hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const useBufferedData = (): BufferedData => {
};

const useBufferedDataInternal = (): BufferedData => {
const connectStatus = useConnectStatus();
const [connectStatus] = useConnectStatus();
const connection = useConnectActions();
const bufferRef = useRef<BufferedData>();
const getBuffer = () => {
Expand Down
10 changes: 9 additions & 1 deletion src/components/ConnectCableDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ConnectContainerDialog, {
ConnectContainerDialogProps,
} from "./ConnectContainerDialog";
import { ConnectionFlowType } from "../connection-stage-hooks";
import { stage } from "../environment";

enum LinkType {
Switch,
Expand All @@ -28,7 +29,14 @@ const configs: Record<ConnectionFlowType, Config> = {
[ConnectionFlowType.RadioRemote]: {
headingId: "connectMB.connectCableMB1.heading",
subtitleId: "connectMB.connectCableMB1.subtitle",
onLink: LinkType.None,
...(stage === "local"
? {
linkTextId: "connectMB.connectCable.skip",
onLink: LinkType.Skip,
}
: {
onLink: LinkType.None,
}),
},
[ConnectionFlowType.RadioBridge]: {
headingId: "connectMB.connectCableMB2.heading",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import {
} from "../connection-stage-hooks";
import ExternalLink from "./ExternalLink";

interface ReconnectErrorDialogProps {
interface ConnectErrorDialogProps {
isOpen: boolean;
onClose: () => void;
onReconnect: () => void;
onConnect: () => void;
flowType: ConnectionFlowType;
errorStep:
| ConnectionFlowStep.ConnectFailed
| ConnectionFlowStep.ReconnectFailed
| ConnectionFlowStep.ConnectionLost;
}
Expand Down Expand Up @@ -57,15 +58,16 @@ const contentConfig = {
const errorTextIdPrefixConfig = {
[ConnectionFlowStep.ConnectionLost]: "disconnectedWarning",
[ConnectionFlowStep.ReconnectFailed]: "reconnectFailed",
[ConnectionFlowStep.ConnectFailed]: "connectFailed",
};

const ReconnectErrorDialog = ({
isOpen,
onClose,
onReconnect,
onConnect,
flowType,
errorStep,
}: ReconnectErrorDialogProps) => {
}: ConnectErrorDialogProps) => {
const errorTextIdPrefix = errorTextIdPrefixConfig[errorStep];
return (
<Modal
Expand Down Expand Up @@ -113,8 +115,14 @@ const ReconnectErrorDialog = ({
<Button onClick={onClose} variant="secondary" size="lg">
<FormattedMessage id="cancel-action" />
</Button>
<Button onClick={onReconnect} variant="primary" size="lg">
<FormattedMessage id="actions.reconnect" />
<Button onClick={onConnect} variant="primary" size="lg">
<FormattedMessage
id={
errorStep === ConnectionFlowStep.ConnectFailed
? "footer.connectButton"
: "actions.reconnect"
}
/>
</Button>
</HStack>
</ModalFooter>
Expand Down
31 changes: 13 additions & 18 deletions src/components/ConnectionFlowDialogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import DownloadingDialog from "./DownloadingDialog";
import EnterBluetoothPatternDialog from "./EnterBluetoothPatternDialog";
import LoadingDialog from "./LoadingDialog";
import ManualFlashingDialog from "./ManualFlashingDialog";
import ReconnectErrorDialog from "./ReconnectErrorDialog";
import ConnectErrorDialog from "./ConnectErrorDialog";
import SelectMicrobitBluetoothDialog from "./SelectMicrobitBluetoothDialog";
import SelectMicrobitUsbDialog from "./SelectMicrobitUsbDialog";
import TryAgainDialog from "./TryAgainDialog";
Expand Down Expand Up @@ -60,19 +60,13 @@ const ConnectionDialogs = () => {
[actions]
);

const onFlashSuccess = useCallback(
async (newStage: ConnectionStage) => {
// Inferring microbit name saves the user from entering the pattern
// for bluetooth connection flow
if (newStage.bluetoothMicrobitName) {
setMicrobitName(newStage.bluetoothMicrobitName);
}
if (newStage.flowType === ConnectionFlowType.RadioBridge) {
await actions.connectMicrobits();
}
},
[actions]
);
const onFlashSuccess = useCallback((newStage: ConnectionStage) => {
// Inferring microbit name saves the user from entering the pattern
// for bluetooth connection flow
if (newStage.bluetoothMicrobitName) {
setMicrobitName(newStage.bluetoothMicrobitName);
}
}, []);

async function connectAndFlash(): Promise<void> {
await actions.connectAndflashMicrobit(progressCallback, onFlashSuccess);
Expand Down Expand Up @@ -202,9 +196,9 @@ const ConnectionDialogs = () => {
<LoadingDialog isOpen={isOpen} headingId="connectMB.radio.heading" />
);
}
case ConnectionFlowStep.TryAgainBluetoothConnect:
case ConnectionFlowStep.TryAgainBluetoothSelectMicrobit:
case ConnectionFlowStep.TryAgainReplugMicrobit:
case ConnectionFlowStep.TryAgainSelectMicrobit:
case ConnectionFlowStep.TryAgainWebUsbSelectMicrobit:
case ConnectionFlowStep.TryAgainCloseTabs: {
return (
<TryAgainDialog
Expand Down Expand Up @@ -235,12 +229,13 @@ const ConnectionDialogs = () => {
case ConnectionFlowStep.WebUsbBluetoothUnsupported: {
return <WebUsbBluetoothUnsupportedDialog {...dialogCommonProps} />;
}
case ConnectionFlowStep.ConnectFailed:
case ConnectionFlowStep.ReconnectFailed:
case ConnectionFlowStep.ConnectionLost: {
return (
<ReconnectErrorDialog
<ConnectErrorDialog
{...dialogCommonProps}
onReconnect={actions.reconnect}
onConnect={actions.reconnect}
flowType={stage.flowType}
errorStep={stage.flowStep}
/>
Expand Down
7 changes: 4 additions & 3 deletions src/components/LiveGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useConnectionStage } from "../connection-stage-hooks";
import { AccelerometerDataEvent } from "@microbit/microbit-connection";
import { MlStage, useMlStatus } from "../ml-status-hooks";
import { mlSettings } from "../ml";
import { ConnectionStatus } from "../connect-status-hooks";

const smoothenDataPoint = (curr: number, next: number) => {
// TODO: Factor out so that recording graph can do the same
Expand All @@ -15,7 +16,7 @@ const smoothenDataPoint = (curr: number, next: number) => {
};

const LiveGraph = () => {
const { isConnected } = useConnectionStage();
const { isConnected, status } = useConnectionStage();
const [{ stage }] = useMlStatus();
const connectActions = useConnectActions();

Expand Down Expand Up @@ -70,12 +71,12 @@ const LiveGraph = () => {
}, [lineX, lineY, lineZ, recordLines]);

useEffect(() => {
if (isConnected) {
if (isConnected || status === ConnectionStatus.ReconnectingAutomatically) {
chart?.start();
} else {
chart?.stop();
}
}, [chart, isConnected]);
}, [chart, isConnected, status]);

// Draw on graph to display that users are recording
const [isRecording, setIsRecording] = useState<boolean>(false);
Expand Down
14 changes: 7 additions & 7 deletions src/components/LiveGraphPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { FormattedMessage } from "react-intl";
import { useConnectionStage } from "../connection-stage-hooks";
import InfoToolTip from "./InfoToolTip";
import LiveGraph from "./LiveGraph";
import { ConnectionStatus, useConnectStatus } from "../connect-status-hooks";
import { ConnectionStatus } from "../connect-status-hooks";

const LiveGraphPanel = () => {
const { actions } = useConnectionStage();
const status = useConnectStatus();
const { actions, status } = useConnectionStage();
const parentPortalRef = useRef(null);

const isReconnecting =
status === ConnectionStatus.ReconnectingAutomatically ||
status === ConnectionStatus.ReconnectingExplicitly;
const connectBtnConfig = useMemo(() => {
return status === ConnectionStatus.NotConnected ||
status === ConnectionStatus.Connecting ||
Expand Down Expand Up @@ -56,15 +57,14 @@ const LiveGraphPanel = () => {
variant="primary"
size="sm"
isDisabled={
status === ConnectionStatus.Reconnecting ||
status === ConnectionStatus.Connecting
isReconnecting || status === ConnectionStatus.Connecting
}
onClick={connectBtnConfig.onClick}
>
<FormattedMessage id={connectBtnConfig.textId} />
</Button>
)}
{status === ConnectionStatus.Reconnecting && (
{isReconnecting && (
<Text rounded="4xl" bg="white" py="1px" fontWeight="bold">
<FormattedMessage id="connectMB.reconnecting" />
</Text>
Expand Down
9 changes: 8 additions & 1 deletion src/components/StartResumeActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ const StartResumeActions = ({ ...props }: Partial<StackProps>) => {
}, [navigate]);

const handleStartNewSession = useCallback(() => {
startOverWarningDialogDisclosure.onClose();
gestureActions.deleteAllGestures();
if (isConnected) {
handleNavigateToAddData();
} else {
connStageActions.start();
}
}, [gestureActions, connStageActions, handleNavigateToAddData, isConnected]);
}, [
startOverWarningDialogDisclosure,
gestureActions,
isConnected,
handleNavigateToAddData,
connStageActions,
]);

const onClickStartNewSession = useCallback(() => {
if (hasExistingSession) {
Expand Down
16 changes: 8 additions & 8 deletions src/components/TryAgainDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,35 +68,35 @@ const configs = {
headingId: "connectMB.usbTryAgain.heading",
children: <CloseTabsContent />,
},
[ConnectionFlowStep.TryAgainSelectMicrobit]: {
[ConnectionFlowStep.TryAgainWebUsbSelectMicrobit]: {
headingId: "connectMB.usbTryAgain.heading",
children: <OneLineContent textId="connectMB.usbTryAgain.selectMicrobit" />,
},
[ConnectionFlowStep.TryAgainBluetoothConnect]: {
[ConnectionFlowStep.TryAgainBluetoothSelectMicrobit]: {
headingId: "connectMB.bluetooth.heading",
children: (
<OneLineContent textId="connectMB.bluetooth.cancelledConnection" />
),
},
};

interface TryAgainWebUsbDialogProps {
interface TryAgainDialogProps {
isOpen: boolean;
onClose: () => void;
onTryAgain: () => void;
type:
| ConnectionFlowStep.TryAgainReplugMicrobit
| ConnectionFlowStep.TryAgainCloseTabs
| ConnectionFlowStep.TryAgainSelectMicrobit
| ConnectionFlowStep.TryAgainBluetoothConnect;
| ConnectionFlowStep.TryAgainWebUsbSelectMicrobit
| ConnectionFlowStep.TryAgainBluetoothSelectMicrobit;
}

const TryAgainWebUsbDialog = ({
const TryAgainDialog = ({
type,
isOpen,
onClose,
onTryAgain,
}: TryAgainWebUsbDialogProps) => {
}: TryAgainDialogProps) => {
const config = configs[type];
return (
<Modal
Expand Down Expand Up @@ -135,4 +135,4 @@ const TryAgainWebUsbDialog = ({
);
};

export default TryAgainWebUsbDialog;
export default TryAgainDialog;
Loading

0 comments on commit 7420da2

Please sign in to comment.