|
16 | 16 |
|
17 | 17 | import { useTranslation } from 'react-i18next';
|
18 | 18 | import { useSync } from '@/hooks/api';
|
19 |
| -import { connect, getState, syncState } from '@/api/bluetooth'; |
| 19 | +import { connect, getState, syncState, TPeripheral } from '@/api/bluetooth'; |
20 | 20 | import { runningInIOS } from '@/utils/env';
|
| 21 | +import { Status } from '@/components/status/status'; |
21 | 22 | import { ActionableItem } from '@/components/actionable-item/actionable-item';
|
22 | 23 | import { Badge } from '@/components/badge/badge';
|
| 24 | +import { HorizontallyCenteredSpinner, SpinnerRingAnimated } from '@/components/spinner/SpinnerAnimation'; |
23 | 25 | import styles from './bluetooth.module.css';
|
24 | 26 |
|
| 27 | +const isConnectedOrConnecting = (peripheral: TPeripheral) => { |
| 28 | + return peripheral.connectionState === 'connecting' || peripheral.connectionState === 'connected'; |
| 29 | +}; |
| 30 | + |
25 | 31 | const _Bluetooth = () => {
|
26 | 32 | const { t } = useTranslation();
|
27 | 33 | const state = useSync(getState, syncState);
|
28 | 34 | if (!state) {
|
29 | 35 | return null;
|
30 | 36 | }
|
31 | 37 | if (!state.bluetoothAvailable) {
|
32 |
| - return <>Please turn on Bluetooth</>; |
| 38 | + return ( |
| 39 | + <Status type="warning"> |
| 40 | + {t('bluetooth.enable')} |
| 41 | + </Status> |
| 42 | + ); |
33 | 43 | }
|
| 44 | + const hasConnection = state.peripherals.some(isConnectedOrConnecting); |
34 | 45 | return (
|
35 | 46 | <>
|
36 | 47 | <div className={styles.label}>
|
37 | 48 | {t('bluetooth.select')}
|
38 | 49 | </div>
|
39 | 50 | <div className={styles.container}>
|
40 |
| - { state.scanning ? 'scanning' : null } |
41 | 51 | {state.peripherals.map(peripheral => {
|
| 52 | + const onClick = !hasConnection ? () => connect(peripheral.identifier) : undefined; |
| 53 | + const connectingIcon = peripheral.connectionState === 'connecting' ? ( |
| 54 | + <SpinnerRingAnimated /> |
| 55 | + ) : undefined; |
42 | 56 | return (
|
43 | 57 | <ActionableItem
|
44 | 58 | key={peripheral.identifier}
|
45 |
| - onClick={() => connect(peripheral.identifier)}> |
| 59 | + icon={connectingIcon} |
| 60 | + onClick={onClick}> |
46 | 61 | <span>
|
47 | 62 | { peripheral.name !== '' ? peripheral.name : peripheral.identifier }
|
48 | 63 | {' '}
|
| 64 | + { peripheral.connectionState === 'connected' ? ( |
| 65 | + <Badge type="success"> |
| 66 | + {t('bluetooth.connected')} |
| 67 | + </Badge> |
| 68 | + ) : null } |
49 | 69 | { peripheral.connectionState === 'error' ? (
|
50 | 70 | <Badge type="danger">
|
51 |
| - {t('bluetooth.connectionFailed')} |
| 71 | + <span style={{ whiteSpace: 'wrap' }}> |
| 72 | + {peripheral.connectionError} |
| 73 | + </span> |
52 | 74 | </Badge>
|
53 | 75 | ) : null }
|
54 |
| - { peripheral.connectionState === 'error' ? ( |
55 |
| - <p>{ peripheral.connectionError }</p> |
56 |
| - ) : peripheral.connectionState } |
57 | 76 | </span>
|
58 |
| - |
59 | 77 | </ActionableItem>
|
60 | 78 | );
|
61 | 79 | })}
|
62 | 80 | </div>
|
| 81 | + {state.scanning && ( |
| 82 | + <HorizontallyCenteredSpinner /> |
| 83 | + )} |
63 | 84 | </>
|
64 | 85 | );
|
65 | 86 | };
|
|
0 commit comments