mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 17:45:22 +00:00
firmware/bootloaderInstructions: extract component
This extracts the instructions for placing a hub in bootloader mode to a separate component so that it can be shared.
This commit is contained in:
committed by
David Lechner
parent
f167f168ee
commit
44169bd178
@@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
import { Callout, Intent } from '@blueprintjs/core';
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
pybricksUsbDfuWindowsDriverInstallUrl,
|
||||
pybricksUsbLinuxUdevRulesUrl,
|
||||
} from '../../app/constants';
|
||||
import { Hub, hubHasBluetoothButton, hubHasUSB } from '../../components/hubPicker';
|
||||
import ExternalLinkIcon from '../../utils/ExternalLinkIcon';
|
||||
import { isLinux, isWindows } from '../../utils/os';
|
||||
import { useI18n } from './i18n';
|
||||
|
||||
type BootloaderInstructionsProps = {
|
||||
hubType: Hub;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides customized instructions on how to enter bootloader mode based
|
||||
* on the hub type.
|
||||
*/
|
||||
const BootloaderInstructions: React.VoidFunctionComponent<
|
||||
BootloaderInstructionsProps
|
||||
> = ({ hubType }) => {
|
||||
const i18n = useI18n();
|
||||
|
||||
const { button, light, lightPattern } = useMemo(() => {
|
||||
return {
|
||||
button: i18n.translate(
|
||||
hubHasBluetoothButton(hubType) ? 'button.bluetooth' : 'button.power',
|
||||
),
|
||||
light: i18n.translate(
|
||||
hubHasBluetoothButton(hubType) ? 'light.bluetooth' : 'light.status',
|
||||
),
|
||||
lightPattern: i18n.translate(
|
||||
hubHasBluetoothButton(hubType)
|
||||
? 'lightPattern.bluetooth'
|
||||
: 'lightPattern.status',
|
||||
),
|
||||
};
|
||||
}, [i18n, hubType]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{hubHasUSB(hubType) && isLinux() && (
|
||||
<Callout intent={Intent.WARNING} icon="warning-sign">
|
||||
{i18n.translate('warning.linux')}{' '}
|
||||
<a
|
||||
href={pybricksUsbLinuxUdevRulesUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{i18n.translate('warning.learnMore')}
|
||||
</a>
|
||||
<ExternalLinkIcon />
|
||||
</Callout>
|
||||
)}
|
||||
{hubHasUSB(hubType) && isWindows() && (
|
||||
<Callout intent={Intent.WARNING} icon="warning-sign">
|
||||
{i18n.translate('warning.windows')}{' '}
|
||||
<a
|
||||
href={pybricksUsbDfuWindowsDriverInstallUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{i18n.translate('warning.learnMore')}
|
||||
</a>
|
||||
<ExternalLinkIcon />
|
||||
</Callout>
|
||||
)}
|
||||
<p>{i18n.translate('instruction')}</p>
|
||||
<ol>
|
||||
{hubHasUSB(hubType) && <li>{i18n.translate('step.disconnectUsb')}</li>}
|
||||
|
||||
<li>{i18n.translate('step.powerOff')}</li>
|
||||
|
||||
{/* City hub has power issues and requires disconnecting motors/sensors */}
|
||||
{hubType === Hub.City && <li>{i18n.translate('step.disconnectIo')}</li>}
|
||||
|
||||
<li>{i18n.translate('step.holdButton', { button })}</li>
|
||||
|
||||
{hubHasUSB(hubType) && <li>{i18n.translate('step.connectUsb')}</li>}
|
||||
|
||||
<li>
|
||||
{i18n.translate('step.waitForLight', {
|
||||
button,
|
||||
light,
|
||||
lightPattern,
|
||||
})}
|
||||
</li>
|
||||
|
||||
<li>
|
||||
{i18n.translate(
|
||||
/* hubs with USB will keep the power on, but other hubs won't */
|
||||
hubHasUSB(hubType) ? 'step.releaseButton' : 'step.keepHolding',
|
||||
{
|
||||
button,
|
||||
},
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default BootloaderInstructions;
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
import { useI18n as useShopifyI18n } from '@shopify/react-i18n';
|
||||
import type { TypedI18n } from '../../i18n';
|
||||
import type translations from './translations/en.json';
|
||||
|
||||
export function useI18n(): TypedI18n<typeof translations> {
|
||||
// istanbul ignore next: babel-loader rewrites this line
|
||||
const [i18n] = useShopifyI18n();
|
||||
return i18n;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"warning": {
|
||||
"linux": "If you have never used Pybricks with USB on Linux, you will need to configure udev rules to allow permission before you can flash the hub firmware.",
|
||||
"windows": " If you have never used Pybricks with USB on Windows, you may need to manually install a USB driver before you can flash the hub firmware.",
|
||||
"learnMore": "Learn more."
|
||||
},
|
||||
"instruction": "To flash the firmware, the hub must be placed in bootloader mode. Follow the steps below to do this:",
|
||||
"button": {
|
||||
"bluetooth": "Bluetooth button",
|
||||
"power": "power button"
|
||||
},
|
||||
"light": {
|
||||
"bluetooth": "Bluetooth light",
|
||||
"status": "hub status light"
|
||||
},
|
||||
"lightPattern": {
|
||||
"bluetooth": "pink-green-blue-off",
|
||||
"status": "light purple"
|
||||
},
|
||||
"step": {
|
||||
"disconnectUsb": "Disconnect the USB cable from the hub.",
|
||||
"powerOff": "Turn off the hub.",
|
||||
"disconnectIo": "Disconnect all motors and sensors from the I/O ports on the hub.",
|
||||
"holdButton": "Press and hold the {button} on the hub.",
|
||||
"connectUsb": "Connect the USB cable.",
|
||||
"waitForLight": "Keep holding the {button} and wait for the {light} to start flashing {lightPattern}. This takes about 5 seconds.",
|
||||
"releaseButton": "Release the {button}",
|
||||
"keepHolding": "Keep holding the {button}."
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
import './installPybricksDialog.scss';
|
||||
import {
|
||||
Button,
|
||||
Callout,
|
||||
Checkbox,
|
||||
Classes,
|
||||
Collapse,
|
||||
@@ -23,28 +22,18 @@ import { Classes as Classes2, Popover2 } from '@blueprintjs/popover2';
|
||||
import { FirmwareMetadata, HubType } from '@pybricks/firmware';
|
||||
import { fileOpen } from 'browser-fs-access';
|
||||
import classNames from 'classnames';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useLocalStorage } from 'usehooks-ts';
|
||||
import { alertsShowAlert } from '../../alerts/actions';
|
||||
import {
|
||||
pybricksUsbDfuWindowsDriverInstallUrl,
|
||||
pybricksUsbLinuxUdevRulesUrl,
|
||||
} from '../../app/constants';
|
||||
import HelpButton from '../../components/HelpButton';
|
||||
import {
|
||||
Hub,
|
||||
hubBootloaderType,
|
||||
hubHasBluetoothButton,
|
||||
hubHasUSB,
|
||||
} from '../../components/hubPicker';
|
||||
import { Hub, hubBootloaderType } from '../../components/hubPicker';
|
||||
import { HubPicker } from '../../components/hubPicker/HubPicker';
|
||||
import { useHubPickerSelectedHub } from '../../components/hubPicker/hooks';
|
||||
import { useSelector } from '../../reducers';
|
||||
import { ensureError } from '../../utils';
|
||||
import ExternalLinkIcon from '../../utils/ExternalLinkIcon';
|
||||
import { isLinux, isWindows } from '../../utils/os';
|
||||
import BootloaderInstructions from '../bootloaderInstructions/BootloaderInstructions';
|
||||
import {
|
||||
firmwareInstallPybricksDialogAccept,
|
||||
firmwareInstallPybricksDialogCancel,
|
||||
@@ -55,6 +44,7 @@ import { validateHubName } from '.';
|
||||
|
||||
const dialogBody = classNames(
|
||||
Classes.DIALOG_BODY,
|
||||
Classes.RUNNING_TEXT,
|
||||
'pb-firmware-installPybricksDialog-body',
|
||||
);
|
||||
|
||||
@@ -409,107 +399,16 @@ const BootloaderModePanel: React.VoidFunctionComponent<BootloaderModePanelProps>
|
||||
}) => {
|
||||
const i18n = useI18n();
|
||||
|
||||
const { button, light, lightPattern } = useMemo(() => {
|
||||
return {
|
||||
button: i18n.translate(
|
||||
hubHasBluetoothButton(hubType)
|
||||
? 'bootloaderPanel.button.bluetooth'
|
||||
: 'bootloaderPanel.button.power',
|
||||
),
|
||||
light: i18n.translate(
|
||||
hubHasBluetoothButton(hubType)
|
||||
? 'bootloaderPanel.light.bluetooth'
|
||||
: 'bootloaderPanel.light.status',
|
||||
),
|
||||
lightPattern: i18n.translate(
|
||||
hubHasBluetoothButton(hubType)
|
||||
? 'bootloaderPanel.lightPattern.bluetooth'
|
||||
: 'bootloaderPanel.lightPattern.status',
|
||||
),
|
||||
};
|
||||
}, [i18n, hubType]);
|
||||
|
||||
return (
|
||||
<div className={dialogBody}>
|
||||
{hubHasUSB(hubType) && isLinux() && (
|
||||
<Callout intent={Intent.WARNING} icon="warning-sign">
|
||||
{i18n.translate('bootloaderPanel.warning.linux')}{' '}
|
||||
<a
|
||||
href={pybricksUsbLinuxUdevRulesUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{i18n.translate('bootloaderPanel.warning.learnMore')}
|
||||
</a>
|
||||
<ExternalLinkIcon />
|
||||
</Callout>
|
||||
)}
|
||||
{hubHasUSB(hubType) && isWindows() && (
|
||||
<Callout intent={Intent.WARNING} icon="warning-sign">
|
||||
{i18n.translate('bootloaderPanel.warning.windows')}{' '}
|
||||
<a
|
||||
href={pybricksUsbDfuWindowsDriverInstallUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{i18n.translate('bootloaderPanel.warning.learnMore')}
|
||||
</a>
|
||||
<ExternalLinkIcon />
|
||||
</Callout>
|
||||
)}
|
||||
|
||||
<div className={Classes.RUNNING_TEXT}>
|
||||
<p>{i18n.translate('bootloaderPanel.instruction1')}</p>
|
||||
<ol>
|
||||
{hubHasUSB(hubType) && (
|
||||
<li>{i18n.translate('bootloaderPanel.step.disconnectUsb')}</li>
|
||||
)}
|
||||
|
||||
<li>{i18n.translate('bootloaderPanel.step.powerOff')}</li>
|
||||
|
||||
{/* City hub has power issues and requires disconnecting motors/sensors */}
|
||||
{hubType === Hub.City && (
|
||||
<li>{i18n.translate('bootloaderPanel.step.disconnectIo')}</li>
|
||||
)}
|
||||
|
||||
<li>
|
||||
{i18n.translate('bootloaderPanel.step.holdButton', { button })}
|
||||
</li>
|
||||
|
||||
{hubHasUSB(hubType) && (
|
||||
<li>{i18n.translate('bootloaderPanel.step.connectUsb')}</li>
|
||||
)}
|
||||
|
||||
<li>
|
||||
{i18n.translate('bootloaderPanel.step.waitForLight', {
|
||||
button,
|
||||
light,
|
||||
lightPattern,
|
||||
})}
|
||||
</li>
|
||||
|
||||
<li>
|
||||
{i18n.translate(
|
||||
/* hubs with USB will keep the power on, but other hubs won't */
|
||||
hubHasUSB(hubType)
|
||||
? 'bootloaderPanel.step.releaseButton'
|
||||
: 'bootloaderPanel.step.keepHolding',
|
||||
{
|
||||
button,
|
||||
},
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
<p>
|
||||
{i18n.translate('bootloaderPanel.instruction2', {
|
||||
flashFirmware: (
|
||||
<strong>
|
||||
{i18n.translate('flashFirmwareButton.label')}
|
||||
</strong>
|
||||
),
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<BootloaderInstructions hubType={hubType} />
|
||||
<p>
|
||||
{i18n.translate('bootloaderPanel.instruction2', {
|
||||
flashFirmware: (
|
||||
<strong>{i18n.translate('flashFirmwareButton.label')}</strong>
|
||||
),
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -54,34 +54,6 @@
|
||||
},
|
||||
"bootloaderPanel": {
|
||||
"title": "Place hub in bootloader mode",
|
||||
"warning": {
|
||||
"linux": "If you have never used Pybricks with USB on Linux, you will need to configure udev rules to allow permission before you can flash the hub firmware.",
|
||||
"windows": " If you have never used Pybricks with USB on Windows, you may need to manually install a USB driver before you can flash the hub firmware.",
|
||||
"learnMore": "Learn more."
|
||||
},
|
||||
"instruction1": "To flash the firmware, the hub must be placed in bootloader mode. Follow the steps below to do this:",
|
||||
"button": {
|
||||
"bluetooth": "Bluetooth button",
|
||||
"power": "power button"
|
||||
},
|
||||
"light": {
|
||||
"bluetooth": "Bluetooth light",
|
||||
"status": "hub status light"
|
||||
},
|
||||
"lightPattern": {
|
||||
"bluetooth": "pink-green-blue-off",
|
||||
"status": "light purple"
|
||||
},
|
||||
"step": {
|
||||
"disconnectUsb": "Disconnect the USB cable from the hub.",
|
||||
"powerOff": "Turn off the hub.",
|
||||
"disconnectIo": "Disconnect all motors and sensors from the I/O ports on the hub.",
|
||||
"holdButton": "Press and hold the {button} on the hub.",
|
||||
"connectUsb": "Connect the USB cable.",
|
||||
"waitForLight": "Keep holding the {button} and wait for the {light} to start flashing {lightPattern}. This takes about 5 seconds.",
|
||||
"releaseButton": "Release the {button}",
|
||||
"keepHolding": "Keep holding the {button}."
|
||||
},
|
||||
"instruction2": "Then click the {flashFirmware} button below to connect to the hub and flash the firmware."
|
||||
},
|
||||
"backButton": {
|
||||
|
||||
Reference in New Issue
Block a user