mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 17:45:22 +00:00
ble/alerts: move missing service from notifications
This commit is contained in:
@@ -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'),
|
||||
};
|
||||
};
|
||||
@@ -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,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 };
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user