diff --git a/src/actions/ble.ts b/src/actions/ble.ts index d6ad1ec1..19f4785d 100644 --- a/src/actions/ble.ts +++ b/src/actions/ble.ts @@ -51,6 +51,7 @@ export function didConnect(): BleDeviceDidConnectAction { export enum BleDeviceFailToConnectReasonType { NoWebBluetooth = 'ble.device.didFailToConnect.noWebBluetooth', + NoBluetooth = 'ble.device.didFailToConnect.noBluetooth', Canceled = 'ble.device.didFailToConnect.canceled', NoGatt = 'ble.device.didFailToConnect.noGatt', NoService = 'ble.device.didFailToConnect.noService', @@ -63,6 +64,8 @@ type Reason = { export type BleDeviceFailToConnectNoWebBluetoothReason = Reason; +export type BleDeviceFailToConnectNoBluetoothReason = Reason; + export type BleDeviceFailToConnectCanceledReason = Reason; export type BleDeviceFailToConnectNoGattReason = Reason; @@ -75,6 +78,7 @@ export type BleDeviceFailToConnectUnknownReason = Reason = { export type BootloaderConnectionFailToConnectNoWebBluetoothReason = Reason; +export type BootloaderConnectionFailToConnectNoBluetoothReason = Reason; + export type BootloaderConnectionFailToConnectGattServiceNotFoundReason = Reason; export type BootloaderConnectionFailToConnectCanceledReason = Reason; @@ -103,6 +107,7 @@ export type BootloaderConnectionFailToConnectUnknownReason = Reason navigator.bluetooth.getAvailability()); + if (!available) { + yield* put(didFailToConnect({ reason: Reason.NoBluetooth })); + return; + } let device: BluetoothDevice; try { diff --git a/src/sagas/lwp3-bootloader-ble.ts b/src/sagas/lwp3-bootloader-ble.ts index 69ad67cd..338064fb 100644 --- a/src/sagas/lwp3-bootloader-ble.ts +++ b/src/sagas/lwp3-bootloader-ble.ts @@ -45,7 +45,11 @@ function* connect(_action: BootloaderConnectionAction): Generator { return; } - // TODO: check navigator.bluetooth.getAvailability() + const available = yield* call(() => navigator.bluetooth.getAvailability()); + if (!available) { + yield* put(didFailToConnect(Reason.NoBluetooth)); + return; + } let device: BluetoothDevice; try { diff --git a/src/sagas/notification.test.ts b/src/sagas/notification.test.ts index b7b114bc..0f456bc9 100644 --- a/src/sagas/notification.test.ts +++ b/src/sagas/notification.test.ts @@ -28,6 +28,7 @@ import notification from './notification'; test.each([ bleDidFailToConnect({ reason: BleDeviceFailToConnectReasonType.NoWebBluetooth }), + bleDidFailToConnect({ reason: BleDeviceFailToConnectReasonType.NoBluetooth }), bleDidFailToConnect({ reason: BleDeviceFailToConnectReasonType.NoGatt }), bleDidFailToConnect({ reason: BleDeviceFailToConnectReasonType.NoService }), bleDidFailToConnect({ @@ -38,6 +39,7 @@ test.each([ message: 'test', }), bootloaderDidFailToConnect(BootloaderConnectionFailureReason.NoWebBluetooth), + bootloaderDidFailToConnect(BootloaderConnectionFailureReason.NoBluetooth), bootloaderDidFailToConnect(BootloaderConnectionFailureReason.GattServiceNotFound), storageChanged('test'), didFailToCompile(['reason']), diff --git a/src/sagas/notification.ts b/src/sagas/notification.ts index b9fb0c7a..d976198b 100644 --- a/src/sagas/notification.ts +++ b/src/sagas/notification.ts @@ -171,6 +171,9 @@ function* showBleDeviceDidFailToConnectError( hubName: 'Pybricks Hub', }); break; + case BleDeviceFailToConnectReasonType.NoBluetooth: + yield* showSingleton(Level.Error, MessageId.BleNoBluetooth); + break; case BleDeviceFailToConnectReasonType.NoWebBluetooth: yield* showSingleton( Level.Error, @@ -207,6 +210,9 @@ function* showBootloaderDidFailToConnectError( ), ); break; + case BootloaderConnectionFailureReason.NoBluetooth: + yield* showSingleton(Level.Error, MessageId.BleNoBluetooth); + break; case BootloaderConnectionFailureReason.Unknown: yield* showUnexpectedError(MessageId.BleUnexpectedError, action.err); break;