ble/alerts: move missing service from notifications

This commit is contained in:
David Lechner
2022-07-18 14:43:30 -05:00
parent 2017f6bd91
commit d3be7775b2
8 changed files with 81 additions and 47 deletions
+35
View File
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
import { Intent } from '@blueprintjs/core';
import React from 'react';
import { CreateToast } from '../../i18nToaster';
import { I18nId, useI18n } from './i18n';
type MissingServiceProps = {
serviceName: string;
hubName: string;
};
const MissingService: React.VoidFunctionComponent<MissingServiceProps> = ({
serviceName,
hubName,
}) => {
const i18n = useI18n();
return (
<>
<p>{i18n.translate(I18nId.MissingServiceMessage, { serviceName })}</p>
<p>{i18n.translate(I18nId.MissingServiceSuggestion1)}</p>
<p>{i18n.translate(I18nId.MissingServiceSuggestion2, { hubName })}</p>
</>
);
};
export const missingService: CreateToast<MissingServiceProps> = (onAction, props) => {
return {
message: <MissingService {...props} />,
icon: 'error',
intent: Intent.DANGER,
onDismiss: () => onAction('dismiss'),
};
};
+3
View File
@@ -16,4 +16,7 @@ export enum I18nId {
BluetoothNotAvailableMessage = 'bluetoothNotAvailable.message',
BluetoothNotAvailableSuggestion = 'bluetoothNotAvailable.suggestion',
NoGattMessage = 'noGatt.message',
MissingServiceMessage = 'missingService.message',
MissingServiceSuggestion1 = 'missingService.suggestion1',
MissingServiceSuggestion2 = 'missingService.suggestion2',
}
+2 -1
View File
@@ -2,8 +2,9 @@
// Copyright (c) 2022 The Pybricks Authors
import { bluetoothNotAvailable } from './BluetoothNotAvailable';
import { missingService } from './MissingService';
import { noGatt } from './NoGatt';
import { noWebBluetooth } from './NoWebBluetooth';
// gathers all of the alert creation functions for passing up to the top level
export default { bluetoothNotAvailable, noGatt, noWebBluetooth };
export default { bluetoothNotAvailable, missingService, noGatt, noWebBluetooth };
+5
View File
@@ -11,5 +11,10 @@
},
"noGatt": {
"message": "The web browser did not give permission to use Bluetooth Low Energy."
},
"missingService": {
"message": "Connected to hub but failed to get {serviceName} service.",
"suggestion1": "Ensure that you are using the most recent firmware.",
"suggestion2": "If the problem persists, try removing the \"{hubName}\" device in your OS Bluetooth settings, then try connecting again."
}
}
+18
View File
@@ -349,6 +349,12 @@ describe('connect action is dispatched', () => {
await runConnectUntil(saga, ConnectRunPoint.Connect);
await expect(saga.take()).resolves.toEqual(
alertsShowAlert('ble', 'missingService', {
serviceName: 'Device Information',
hubName: 'test name',
}),
);
await expect(saga.take()).resolves.toEqual(
bleDidFailToConnectPybricks({
reason: BleDeviceFailToConnectReasonType.NoDeviceInfoService,
@@ -478,6 +484,12 @@ describe('connect action is dispatched', () => {
await runConnectUntil(saga, ConnectRunPoint.DidReceivePnpId);
await expect(saga.take()).resolves.toEqual(
alertsShowAlert('ble', 'missingService', {
serviceName: 'Pybricks',
hubName: 'test name',
}),
);
await expect(saga.take()).resolves.toEqual(
bleDidFailToConnectPybricks({
reason: BleDeviceFailToConnectReasonType.NoPybricksService,
@@ -554,6 +566,12 @@ describe('connect action is dispatched', () => {
await runConnectUntil(saga, ConnectRunPoint.DidReceivePnpId);
await expect(saga.take()).resolves.toEqual(
alertsShowAlert('ble', 'missingService', {
serviceName: 'Nordic UART',
hubName: 'test name',
}),
);
await expect(saga.take()).resolves.toEqual(
bleDidFailToConnectPybricks({
// FIXME: this is wrong error
+18
View File
@@ -186,6 +186,12 @@ function* handleBleConnectPybricks(): Generator {
);
if (!deviceInfoService) {
yield* put(
alertsShowAlert('ble', 'missingService', {
serviceName: 'Device Information',
hubName: device.name || 'Pybricks Hub',
}),
);
yield* put(
bleDidFailToConnectPybricks({ reason: Reason.NoDeviceInfoService }),
);
@@ -249,6 +255,12 @@ function* handleBleConnectPybricks(): Generator {
);
if (!pybricksService) {
yield* put(
alertsShowAlert('ble', 'missingService', {
serviceName: 'Pybricks',
hubName: device.name || 'Pybricks Hub',
}),
);
yield* put(
bleDidFailToConnectPybricks({
reason: Reason.NoPybricksService,
@@ -312,6 +324,12 @@ function* handleBleConnectPybricks(): Generator {
);
if (!uartService) {
yield* put(
alertsShowAlert('ble', 'missingService', {
serviceName: 'Nordic UART',
hubName: device.name || 'Pybricks Hub',
}),
);
yield* put(
bleDidFailToConnectPybricks({
reason: Reason.NoPybricksService,
-22
View File
@@ -12,10 +12,6 @@ import { AnyAction } from 'redux';
import { AsyncSaga, uuid } from '../../test';
import { appDidCheckForUpdate } from '../app/actions';
import { bleDIServiceDidReceiveFirmwareRevision } from '../ble-device-info-service/actions';
import {
BleDeviceFailToConnectReasonType,
bleDidFailToConnectPybricks,
} from '../ble/actions';
import { editorDidFailToOpenFile } from '../editor/actions';
import { EditorError } from '../editor/error';
import {
@@ -61,12 +57,6 @@ function createTestToasterSaga(): { toaster: IToaster; saga: AsyncSaga } {
}
test.each([
bleDidFailToConnectPybricks({
reason: BleDeviceFailToConnectReasonType.NoDeviceInfoService,
}),
bleDidFailToConnectPybricks({
reason: BleDeviceFailToConnectReasonType.NoPybricksService,
}),
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.Unknown, <Error>{
message: 'test',
}),
@@ -122,18 +112,6 @@ test.each([
});
test.each([
bleDidFailToConnectPybricks({
reason: BleDeviceFailToConnectReasonType.NoWebBluetooth,
}),
bleDidFailToConnectPybricks({
reason: BleDeviceFailToConnectReasonType.NoBluetooth,
}),
bleDidFailToConnectPybricks({ reason: BleDeviceFailToConnectReasonType.Canceled }),
bleDidFailToConnectPybricks({ reason: BleDeviceFailToConnectReasonType.NoGatt }),
bleDidFailToConnectPybricks({
reason: BleDeviceFailToConnectReasonType.Unknown,
err: { name: 'test', message: 'unknown' },
}),
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.NoWebBluetooth),
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.NoBluetooth),
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.Canceled),
-24
View File
@@ -14,10 +14,6 @@ import { getAlertProps } from '../alerts';
import { appDidCheckForUpdate, appReload } from '../app/actions';
import { appName } from '../app/constants';
import { bleDIServiceDidReceiveFirmwareRevision } from '../ble-device-info-service/actions';
import {
BleDeviceFailToConnectReasonType,
bleDidFailToConnectPybricks,
} from '../ble/actions';
import { editorDidFailToOpenFile } from '../editor/actions';
import { EditorError } from '../editor/error';
import {
@@ -170,25 +166,6 @@ function* showUnexpectedError(messageId: I18nId, error: Error): Generator {
);
}
function* showBleDeviceDidFailToConnectError(
action: ReturnType<typeof bleDidFailToConnectPybricks>,
): Generator {
switch (action.reason) {
case BleDeviceFailToConnectReasonType.NoPybricksService:
yield* showSingleton(Level.Error, I18nId.BleGattServiceNotFound, {
serviceName: 'Pybricks',
hubName: 'Pybricks Hub',
});
break;
case BleDeviceFailToConnectReasonType.NoDeviceInfoService:
yield* showSingleton(Level.Error, I18nId.BleGattServiceNotFound, {
serviceName: 'Device Information',
hubName: 'Pybricks Hub',
});
break;
}
}
function* showBootloaderDidFailToConnectError(
action: ReturnType<typeof bootloaderDidFailToConnect>,
): Generator {
@@ -421,7 +398,6 @@ function* showExplorerFailToDelete(
}
export default function* (): Generator {
yield* takeEvery(bleDidFailToConnectPybricks, showBleDeviceDidFailToConnectError);
yield* takeEvery(bootloaderDidFailToConnect, showBootloaderDidFailToConnectError);
yield* takeEvery(didFailToFinish, showFlashFirmwareError);
yield* takeEvery(didCompile, dismissCompilerError);